There's no need to warn that a deprecated function uses a deprecated type, that just adds noise. We were preventing that in start_decl, but that didn't help member declarations that go through grokfield. So handle it in grokdeclarator instead, which is shared between them.
Tested x86_64-pc-linux-gnu, applying to trunk. gcc/cp/ChangeLog 2020-05-11 Jason Merrill <ja...@redhat.com> * decl.c (grokdeclarator): Adjust deprecated_state here. (start_decl): Not here. --- gcc/cp/decl.c | 18 +++++++++++------- gcc/testsuite/g++.dg/warn/deprecated-6.C | 2 +- gcc/testsuite/g++.dg/warn/deprecated.C | 2 +- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 73a06a60786..adf94658420 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -5214,18 +5214,11 @@ start_decl (const cp_declarator *declarator, *pushed_scope_p = NULL_TREE; - /* An object declared as __attribute__((deprecated)) suppresses - warnings of uses of other deprecated items. */ - if (lookup_attribute ("deprecated", attributes)) - deprecated_state = DEPRECATED_SUPPRESS; - attributes = chainon (attributes, prefix_attributes); decl = grokdeclarator (declarator, declspecs, NORMAL, initialized, &attributes); - deprecated_state = DEPRECATED_NORMAL; - if (decl == NULL_TREE || VOID_TYPE_P (decl) || decl == error_mark_node) return error_mark_node; @@ -11318,6 +11311,17 @@ grokdeclarator (const cp_declarator *declarator, type = NULL_TREE; type_was_error_mark_node = true; } + + /* Ignore erroneous attributes. */ + if (attrlist && *attrlist == error_mark_node) + *attrlist = NULL_TREE; + + /* An object declared as __attribute__((deprecated)) suppresses + warnings of uses of other deprecated items. */ + temp_override<deprecated_states> ds (deprecated_state); + if (attrlist && lookup_attribute ("deprecated", *attrlist)) + deprecated_state = DEPRECATED_SUPPRESS; + cp_warn_deprecated_use (type); if (type && TREE_CODE (type) == TYPE_DECL) { diff --git a/gcc/testsuite/g++.dg/warn/deprecated-6.C b/gcc/testsuite/g++.dg/warn/deprecated-6.C index b3c390be385..605b507f534 100644 --- a/gcc/testsuite/g++.dg/warn/deprecated-6.C +++ b/gcc/testsuite/g++.dg/warn/deprecated-6.C @@ -89,7 +89,7 @@ struct SS2 *p2; /* { dg-warning "'SS2' is deprecated: Please avoid SS2" } */ class T { public: void member1(int) __attribute__ ((deprecated("Please avoid member1"))); - void member2(INT1) __attribute__ ((__deprecated__("Please avoid member2"))); /* { dg-warning "'INT1' is deprecated" } */ + void member2(INT1) __attribute__ ((__deprecated__("Please avoid member2"))); int member3(T *); int x; } __attribute__ ((deprecated("Please avoid T"))); diff --git a/gcc/testsuite/g++.dg/warn/deprecated.C b/gcc/testsuite/g++.dg/warn/deprecated.C index c5ccbf3271f..3817e620250 100644 --- a/gcc/testsuite/g++.dg/warn/deprecated.C +++ b/gcc/testsuite/g++.dg/warn/deprecated.C @@ -93,7 +93,7 @@ struct SS2 *p2; /* { dg-warning "'SS2' is deprecated" } */ class T { public: void member1(int) __attribute__ ((deprecated)); - void member2(INT1) __attribute__ ((__deprecated__)); /* { dg-warning "'INT1' is deprecated" } */ + void member2(INT1) __attribute__ ((__deprecated__)); int member3(T *); int x; } __attribute__ ((deprecated)); base-commit: 2b2d298ff845ab7a07ffbd51da79473736da3324 -- 2.18.1