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

Reply via email to