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
This commit is contained in:
parent
d0fc6e9f69
commit
5857042a2b
15 changed files with 252 additions and 7 deletions
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
|
50
gcc/testsuite/g++.dg/cpp0x/attributes-namespace1.C
Normal file
50
gcc/testsuite/g++.dg/cpp0x/attributes-namespace1.C
Normal file
|
@ -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" }
|
||||
}
|
27
gcc/testsuite/g++.dg/cpp0x/attributes-namespace2.C
Normal file
27
gcc/testsuite/g++.dg/cpp0x/attributes-namespace2.C
Normal file
|
@ -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" }
|
||||
}
|
33
gcc/testsuite/g++.dg/cpp0x/attributes-namespace3.C
Normal file
33
gcc/testsuite/g++.dg/cpp0x/attributes-namespace3.C
Normal file
|
@ -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" }
|
||||
}
|
45
gcc/testsuite/g++.dg/cpp0x/attributes-namespace4.C
Normal file
45
gcc/testsuite/g++.dg/cpp0x/attributes-namespace4.C
Normal file
|
@ -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" }
|
||||
}
|
20
gcc/testsuite/g++.dg/cpp0x/attributes-namespace5.C
Normal file
20
gcc/testsuite/g++.dg/cpp0x/attributes-namespace5.C
Normal file
|
@ -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() { }
|
|
@ -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 {}
|
||||
|
|
|
@ -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 {}
|
||||
|
|
Loading…
Add table
Reference in a new issue