From 5857042a2b3dd635fc6cae214abd60d3a8336060 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Fri, 23 Aug 2019 22:04:32 +0000 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 14 ++++++ gcc/cp/cp-tree.h | 1 + gcc/cp/decl.c | 6 ++- gcc/cp/decl2.c | 18 +++++++ gcc/cp/name-lookup.c | 18 +++++++ gcc/cp/parser.c | 4 ++ gcc/cp/semantics.c | 2 + gcc/testsuite/ChangeLog | 11 ++++ .../g++.dg/cpp0x/attributes-namespace1.C | 50 +++++++++++++++++++ .../g++.dg/cpp0x/attributes-namespace2.C | 27 ++++++++++ .../g++.dg/cpp0x/attributes-namespace3.C | 33 ++++++++++++ .../g++.dg/cpp0x/attributes-namespace4.C | 45 +++++++++++++++++ .../g++.dg/cpp0x/attributes-namespace5.C | 20 ++++++++ .../g++.dg/cpp1z/namespace-attribs.C | 5 +- .../g++.dg/cpp1z/namespace-attribs2.C | 5 +- 15 files changed, 252 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/attributes-namespace1.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/attributes-namespace2.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/attributes-namespace3.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/attributes-namespace4.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/attributes-namespace5.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c4160820fee..5a59f984af0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,17 @@ +2019-08-23 Marek Polacek + + 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 * 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 05f91861b42..42f180d1dd3 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 88aa69ce5de..cb5571e4f24 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 a32108f9d16..aca37a28f49 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 5f5ff81f405..a8ab4db4d0d 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 504f77a4908..53514787554 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 7ac1ba058e5..8aec4eff9b3 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 92e6da2602d..8e907137164 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2019-08-23 Marek Polacek + + 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 * 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 00000000000..d49ebb0b721 --- /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 00000000000..08a043a24e3 --- /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 00000000000..81355ab5677 --- /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 00000000000..de0c6df8d9d --- /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 // { 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 00000000000..6dbcf326061 --- /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 + 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::f3(); +template <> void Y::S::f3() { } diff --git a/gcc/testsuite/g++.dg/cpp1z/namespace-attribs.C b/gcc/testsuite/g++.dg/cpp1z/namespace-attribs.C index dd1855137de..29f8ce472be 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 193dbf6e017..7996b4b680c 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 {} -- 2.30.2