aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2019-08-23 22:04:32 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2019-08-23 22:04:32 +0000
commit5857042a2b3dd635fc6cae214abd60d3a8336060 (patch)
tree4d3f8bb0abb57d1a94a4245e00b078312eb47513 /gcc
parentd0fc6e9f69b27fa93438c306fd9b25404982c2ea (diff)
downloadgcc-5857042a2b3dd635fc6cae214abd60d3a8336060.zip
gcc-5857042a2b3dd635fc6cae214abd60d3a8336060.tar.gz
gcc-5857042a2b3dd635fc6cae214abd60d3a8336060.tar.bz2
PR c++/79817 - attribute deprecated on namespace.
* cp-tree.h (cp_warn_deprecated_use_scopes): Declare. * decl.c (grokdeclarator): Call cp_warn_deprecated_use_scopes. (type_is_deprecated): Likewise. * decl2.c (cp_warn_deprecated_use_scopes): New function. * name-lookup.c (handle_namespace_attrs): Handle attribute deprecated. * parser.c (cp_parser_namespace_alias_definition): Call cp_warn_deprecated_use_scopes. (cp_parser_using_declaration): Likewise. (cp_parser_using_directive): Likewise. * semantics.c (finish_id_expression_1): Likewise. * g++.dg/cpp0x/attributes-namespace1.C: New test. * g++.dg/cpp0x/attributes-namespace2.C: New test. * g++.dg/cpp0x/attributes-namespace3.C: New test. * g++.dg/cpp0x/attributes-namespace4.C: New test. * g++.dg/cpp0x/attributes-namespace5.C: New test. * g++.dg/cpp1z/namespace-attribs.C: Adjust. * g++.dg/cpp1z/namespace-attribs2.C: Adjust. From-SVN: r274888
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog14
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/decl.c6
-rw-r--r--gcc/cp/decl2.c18
-rw-r--r--gcc/cp/name-lookup.c18
-rw-r--r--gcc/cp/parser.c4
-rw-r--r--gcc/cp/semantics.c2
-rw-r--r--gcc/testsuite/ChangeLog11
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/attributes-namespace1.C50
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/attributes-namespace2.C27
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/attributes-namespace3.C33
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/attributes-namespace4.C45
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/attributes-namespace5.C20
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/namespace-attribs.C5
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/namespace-attribs2.C5
15 files changed, 252 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c416082..5a59f98 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,17 @@
+2019-08-23 Marek Polacek <polacek@redhat.com>
+
+ PR c++/79817 - attribute deprecated on namespace.
+ * cp-tree.h (cp_warn_deprecated_use_scopes): Declare.
+ * decl.c (grokdeclarator): Call cp_warn_deprecated_use_scopes.
+ (type_is_deprecated): Likewise.
+ * decl2.c (cp_warn_deprecated_use_scopes): New function.
+ * name-lookup.c (handle_namespace_attrs): Handle attribute deprecated.
+ * parser.c (cp_parser_namespace_alias_definition): Call
+ cp_warn_deprecated_use_scopes.
+ (cp_parser_using_declaration): Likewise.
+ (cp_parser_using_directive): Likewise.
+ * semantics.c (finish_id_expression_1): Likewise.
+
2019-08-23 Nathan Sidwell <nathan@acm.org>
* class.c (check_for_override): Checking IDENTIFIER_VIRTUAL_P is
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 05f9186..42f180d 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6264,6 +6264,7 @@ extern bool is_list_ctor (tree);
extern void validate_conversion_obstack (void);
extern void mark_versions_used (tree);
extern bool cp_warn_deprecated_use (tree, tsubst_flags_t = tf_warning_or_error);
+extern void cp_warn_deprecated_use_scopes (tree);
extern tree get_function_version_dispatcher (tree);
/* in class.c */
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 88aa69c..cb5571e 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -10791,6 +10791,7 @@ grokdeclarator (const cp_declarator *declarator,
cp_warn_deprecated_use (type);
if (type && TREE_CODE (type) == TYPE_DECL)
{
+ cp_warn_deprecated_use_scopes (CP_DECL_CONTEXT (type));
typedef_decl = type;
type = TREE_TYPE (typedef_decl);
if (DECL_ARTIFICIAL (typedef_decl))
@@ -13230,7 +13231,10 @@ type_is_deprecated (tree type)
if (TREE_DEPRECATED (TYPE_NAME (type)))
return type;
else
- return NULL_TREE;
+ {
+ cp_warn_deprecated_use_scopes (CP_DECL_CONTEXT (TYPE_NAME (type)));
+ return NULL_TREE;
+ }
}
/* Do warn about using typedefs to a deprecated class. */
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index a32108f..aca37a2 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -5407,6 +5407,24 @@ cp_warn_deprecated_use (tree decl, tsubst_flags_t complain)
return warned;
}
+/* Like above, but takes into account outer scopes. */
+
+void
+cp_warn_deprecated_use_scopes (tree scope)
+{
+ while (scope
+ && scope != error_mark_node
+ && scope != global_namespace)
+ {
+ if (cp_warn_deprecated_use (scope))
+ return;
+ if (TYPE_P (scope))
+ scope = CP_TYPE_CONTEXT (scope);
+ else
+ scope = CP_DECL_CONTEXT (scope);
+ }
+}
+
/* Mark DECL (either a _DECL or a BASELINK) as "used" in the program.
If DECL is a specialization or implicitly declared class member,
generate the actual definition. Return false if something goes
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 5f5ff81..a8ab4db 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -4905,6 +4905,24 @@ handle_namespace_attrs (tree ns, tree attributes)
DECL_ATTRIBUTES (ns) = tree_cons (name, args,
DECL_ATTRIBUTES (ns));
}
+ else if (is_attribute_p ("deprecated", name))
+ {
+ if (!DECL_NAME (ns))
+ {
+ warning (OPT_Wattributes, "ignoring %qD attribute on anonymous "
+ "namespace", name);
+ continue;
+ }
+ if (args && TREE_CODE (TREE_VALUE (args)) != STRING_CST)
+ {
+ error ("deprecated message is not a string");
+ continue;
+ }
+ TREE_DEPRECATED (ns) = 1;
+ if (args)
+ DECL_ATTRIBUTES (ns) = tree_cons (name, args,
+ DECL_ATTRIBUTES (ns));
+ }
else
{
warning (OPT_Wattributes, "%qD attribute directive ignored",
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 504f77a..5351478 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -19378,6 +19378,7 @@ cp_parser_namespace_alias_definition (cp_parser* parser)
/* Look for the qualified-namespace-specifier. */
namespace_specifier
= cp_parser_qualified_namespace_specifier (parser);
+ cp_warn_deprecated_use_scopes (namespace_specifier);
/* Look for the `;' token. */
cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
@@ -19492,6 +19493,8 @@ cp_parser_using_declaration (cp_parser* parser,
&& !TYPE_FUNCTION_SCOPE_P (qscope))
qscope = CP_TYPE_CONTEXT (qscope);
+ cp_warn_deprecated_use_scopes (qscope);
+
if (access_declaration_p && cp_parser_error_occurred (parser))
/* Something has already gone wrong; there's no need to parse
further. Since an error has occurred, the return value of
@@ -19752,6 +19755,7 @@ cp_parser_using_directive (cp_parser* parser)
/*is_declaration=*/true);
/* Get the namespace being used. */
namespace_decl = cp_parser_namespace_name (parser);
+ cp_warn_deprecated_use_scopes (namespace_decl);
/* And any specified attributes. */
attribs = cp_parser_attributes_opt (parser);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 7ac1ba0..8aec4ef 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -3811,6 +3811,8 @@ finish_id_expression_1 (tree id_expression,
if (TREE_CODE (decl) == FUNCTION_DECL)
mark_used (decl);
+ cp_warn_deprecated_use_scopes (scope);
+
if (TYPE_P (scope))
decl = finish_qualified_id_expr (scope,
decl,
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 92e6da2..8e90713 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,14 @@
+2019-08-23 Marek Polacek <polacek@redhat.com>
+
+ PR c++/79817 - attribute deprecated on namespace.
+ * g++.dg/cpp0x/attributes-namespace1.C: New test.
+ * g++.dg/cpp0x/attributes-namespace2.C: New test.
+ * g++.dg/cpp0x/attributes-namespace3.C: New test.
+ * g++.dg/cpp0x/attributes-namespace4.C: New test.
+ * g++.dg/cpp0x/attributes-namespace5.C: New test.
+ * g++.dg/cpp1z/namespace-attribs.C: Adjust.
+ * g++.dg/cpp1z/namespace-attribs2.C: Adjust.
+
2019-08-23 Mihailo Stojanovic <mistojanovic@wavecomp.com>
* gcc.target/mips/get-fcsr-3.c: New test.
diff --git a/gcc/testsuite/g++.dg/cpp0x/attributes-namespace1.C b/gcc/testsuite/g++.dg/cpp0x/attributes-namespace1.C
new file mode 100644
index 0000000..d49ebb0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/attributes-namespace1.C
@@ -0,0 +1,50 @@
+// PR c++/79817 - attribute deprecated on namespace.
+// { dg-do compile { target c++11 } }
+
+namespace [[deprecated]] ns1 { int i; }
+namespace [[deprecated("foo")]] ns2 { int i; }
+namespace __attribute__((deprecated)) ns3 { int i; }
+namespace __attribute__((deprecated("foo"))) ns4 { int i; }
+
+namespace [[deprecated]] ns6
+{
+ enum E { X };
+ void fn();
+}
+
+namespace [[deprecated]] ns7
+{
+ namespace ns8 {
+ int x;
+ struct Z { };
+ }
+ struct S { };
+}
+
+namespace N1
+{
+ namespace N2
+ {
+ namespace [[deprecated]] N3
+ {
+ namespace N4 { int x; }
+ }
+ }
+}
+
+void
+f ()
+{
+ ns1::i = 0; // { dg-warning ".ns1. is deprecated" }
+ ns2::i = 0; // { dg-warning ".ns2. is deprecated: foo" }
+ ns3::i = 0; // { dg-warning ".ns3. is deprecated" }
+ ns4::i = 0; // { dg-warning ".ns4. is deprecated" }
+ int i = ns1::i; // { dg-warning ".ns1. is deprecated" }
+ int k = ns6::E::X; // { dg-warning ".ns6. is deprecated" }
+ ns7::ns8::x = 42; // { dg-warning ".ns7. is deprecated" }
+ N1::N2::N3::N4::x = 42; // { dg-warning ".N1::N2::N3. is deprecated" }
+ ns6::fn(); // { dg-warning ".ns6. is deprecated" }
+ ns7::S s; // { dg-warning ".ns7. is deprecated" }
+ ns7::S sfn(int); // { dg-warning ".ns7. is deprecated" }
+ ns7::ns8::Z sfn2(int); // { dg-warning ".ns7. is deprecated" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/attributes-namespace2.C b/gcc/testsuite/g++.dg/cpp0x/attributes-namespace2.C
new file mode 100644
index 0000000..08a043a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/attributes-namespace2.C
@@ -0,0 +1,27 @@
+// PR c++/79817 - attribute deprecated on namespace.
+// { dg-do compile { target c++11 } }
+
+namespace [[deprecated]] { // { dg-warning "ignoring .deprecated. attribute on anonymous namespace" }
+ int nn;
+}
+
+inline namespace [[deprecated]] I {
+ int x;
+}
+
+namespace M {
+ int y;
+ inline namespace [[deprecated]] N {
+ int x;
+ }
+}
+
+void
+g ()
+{
+ nn = 42;
+ I::x = 42; // { dg-warning ".I. is deprecated" }
+ M::x = 42;
+ M::y = 42;
+ M::N::x = 42; // { dg-warning ".M::N. is deprecated" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/attributes-namespace3.C b/gcc/testsuite/g++.dg/cpp0x/attributes-namespace3.C
new file mode 100644
index 0000000..81355ab
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/attributes-namespace3.C
@@ -0,0 +1,33 @@
+// PR c++/79817 - attribute deprecated on namespace.
+// { dg-do compile { target c++11 } }
+
+namespace [[deprecated]] N
+{
+ typedef decltype(sizeof(int)) T;
+ int x;
+
+ namespace N2 {
+ typedef decltype(sizeof(int)) T;
+ int y;
+ }
+}
+
+namespace M {
+ namespace [[deprecated]] M2 {
+ typedef decltype(sizeof(int)) T;
+ int z;
+ }
+}
+
+void
+fn2 ()
+{
+ using N::x; // { dg-warning ".N. is deprecated" }
+ N::T j; // { dg-warning ".N. is deprecated" }
+
+ using M::M2::z; // { dg-warning ".M::M2. is deprecated" }
+ M::M2::T l; // { dg-warning ".M::M2. is deprecated" }
+
+ using N::N2::y; // { dg-warning ".N. is deprecated" }
+ N::N2::T k; // { dg-warning ".N. is deprecated" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/attributes-namespace4.C b/gcc/testsuite/g++.dg/cpp0x/attributes-namespace4.C
new file mode 100644
index 0000000..de0c6df8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/attributes-namespace4.C
@@ -0,0 +1,45 @@
+// PR c++/79817 - attribute deprecated on namespace.
+// { dg-do compile { target c++11 } }
+
+namespace [[deprecated]] N {
+ struct S { };
+ using T = int;
+ const int value = 42;
+ int arr[10];
+}
+
+namespace [[deprecated]] Y {
+ int x;
+ int i = x;
+}
+
+namespace [[deprecated]] M {
+ namespace M2 {
+ }
+}
+
+enum E { F = N::value }; // { dg-warning ".N. is deprecated" }
+
+template<N::T> // { dg-warning ".N. is deprecated" }
+struct X { };
+
+N::T foo(); // { dg-warning ".N. is deprecated" }
+
+void
+g(N::T p) // { dg-warning ".N. is deprecated" }
+{
+ N::S s; // { dg-warning ".N. is deprecated" }
+ N::arr[0] = 42; // { dg-warning ".N. is deprecated" }
+}
+
+namespace Z = Y; // { dg-warning ".Y. is deprecated" }
+namespace Z2 = M::M2; // { dg-warning ".M. is deprecated" }
+
+void
+g2 ()
+{
+ using namespace Y; // { dg-warning ".Y. is deprecated" }
+ using namespace M::M2; // { dg-warning ".M. is deprecated" }
+ using TT = N::T; // { dg-warning ".N. is deprecated" }
+ using N::T; // { dg-warning ".N. is deprecated" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/attributes-namespace5.C b/gcc/testsuite/g++.dg/cpp0x/attributes-namespace5.C
new file mode 100644
index 0000000..6dbcf32
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/attributes-namespace5.C
@@ -0,0 +1,20 @@
+// PR c++/79817 - attribute deprecated on namespace.
+// { dg-do compile { target c++11 } }
+
+namespace [[deprecated]] Y {
+ void f();
+ void f2(int);
+
+ template<typename>
+ struct S {
+ void f3 ();
+ };
+}
+
+void Y::f();
+void Y::f() { }
+void Y::f2(int);
+void Y::f2([[maybe_unused]] int);
+void Y::f2(int) { }
+template <> void Y::S<int>::f3();
+template <> void Y::S<int>::f3() { }
diff --git a/gcc/testsuite/g++.dg/cpp1z/namespace-attribs.C b/gcc/testsuite/g++.dg/cpp1z/namespace-attribs.C
index dd18551..29f8ce4 100644
--- a/gcc/testsuite/g++.dg/cpp1z/namespace-attribs.C
+++ b/gcc/testsuite/g++.dg/cpp1z/namespace-attribs.C
@@ -3,9 +3,8 @@
namespace A __attribute ((visibility ("default"))) {}
-namespace B [[deprecated]] {} // { dg-warning "ignored" }
+namespace B [[deprecated]] {}
namespace __attribute ((visibility ("default"))) C {}
-namespace [[deprecated]] D {} // { dg-warning "ignored" }
-
+namespace [[deprecated]] D {}
diff --git a/gcc/testsuite/g++.dg/cpp1z/namespace-attribs2.C b/gcc/testsuite/g++.dg/cpp1z/namespace-attribs2.C
index 193dbf6..7996b4b6 100644
--- a/gcc/testsuite/g++.dg/cpp1z/namespace-attribs2.C
+++ b/gcc/testsuite/g++.dg/cpp1z/namespace-attribs2.C
@@ -1,7 +1,6 @@
// { dg-do compile { target c++17 } }
// { dg-additional-options "-pedantic" }
-namespace B [[deprecated]] {} // { dg-warning "ignored|must precede" }
-
-namespace [[deprecated]] D {} // { dg-warning "ignored" }
+namespace B [[deprecated]] {} // { dg-error "must precede" }
+namespace [[deprecated]] D {}