In this testcase we were giving a deprecated declaration warning
without the deprecated declaration ever having been used, because we
called mark_used when checking whether the variable is constant.  What
we really want from mark_used is the instantiation semantics, so let's
split that out.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit e74031296c8c49986ffb0ec08765f09a79f5f81f
Author: Jason Merrill <ja...@redhat.com>
Date:   Thu Jul 21 17:27:19 2016 -0400

        PR c++/71274 - deprecated warning without use.
    
        * decl2.c (maybe_instantiate_decl): Split out from mark_used.
        (decl_constant_var_p): Use it instead.

diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 22f9ede..2ff6f53 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -81,6 +81,7 @@ static tree get_guard_bits (tree);
 static void determine_visibility_from_class (tree, tree);
 static bool determine_hidden_inline (tree);
 static bool decl_defined_p (tree);
+static void maybe_instantiate_decl (tree);
 
 /* A list of static class variables.  This is needed, because a
    static class variable can be declared inside the class without
@@ -4217,7 +4218,7 @@ decl_constant_var_p (tree decl)
      in the case of a constexpr variable, we can't treat it as a
      constant until its initializer is complete in case it's used in
      its own initializer.  */
-  mark_used (decl);
+  maybe_instantiate_decl (decl);
   return DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl);
 }
 
@@ -5057,6 +5058,38 @@ possibly_inlined_p (tree decl)
   return true;
 }
 
+/* Normally, we can wait until instantiation-time to synthesize DECL.
+   However, if DECL is a static data member initialized with a constant
+   or a constexpr function, we need it right now because a reference to
+   such a data member or a call to such function is not value-dependent.
+   For a function that uses auto in the return type, we need to instantiate
+   it to find out its type.  For OpenMP user defined reductions, we need
+   them instantiated for reduction clauses which inline them by hand
+   directly.  */
+
+static void
+maybe_instantiate_decl (tree decl)
+{
+  if (DECL_LANG_SPECIFIC (decl)
+      && DECL_TEMPLATE_INFO (decl)
+      && (decl_maybe_constant_var_p (decl)
+         || (TREE_CODE (decl) == FUNCTION_DECL
+             && DECL_OMP_DECLARE_REDUCTION_P (decl))
+         || undeduced_auto_decl (decl))
+      && !DECL_DECLARED_CONCEPT_P (decl)
+      && !uses_template_parms (DECL_TI_ARGS (decl)))
+    {
+      /* Instantiating a function will result in garbage collection.  We
+        must treat this situation as if we were within the body of a
+        function so as to avoid collecting live data only referenced from
+        the stack (such as overload resolution candidates).  */
+      ++function_depth;
+      instantiate_decl (decl, /*defer_ok=*/false,
+                       /*expl_inst_class_mem_p=*/false);
+      --function_depth;
+    }
+}
+
 /* 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
@@ -5151,24 +5184,7 @@ mark_used (tree decl, tsubst_flags_t complain)
      it to find out its type.  For OpenMP user defined reductions, we need
      them instantiated for reduction clauses which inline them by hand
      directly.  */
-  if (DECL_LANG_SPECIFIC (decl)
-      && DECL_TEMPLATE_INFO (decl)
-      && (decl_maybe_constant_var_p (decl)
-         || (TREE_CODE (decl) == FUNCTION_DECL
-             && DECL_OMP_DECLARE_REDUCTION_P (decl))
-         || undeduced_auto_decl (decl))
-      && !DECL_DECLARED_CONCEPT_P (decl)
-      && !uses_template_parms (DECL_TI_ARGS (decl)))
-    {
-      /* Instantiating a function will result in garbage collection.  We
-        must treat this situation as if we were within the body of a
-        function so as to avoid collecting live data only referenced from
-        the stack (such as overload resolution candidates).  */
-      ++function_depth;
-      instantiate_decl (decl, /*defer_ok=*/false,
-                       /*expl_inst_class_mem_p=*/false);
-      --function_depth;
-    }
+  maybe_instantiate_decl (decl);
 
   if (processing_template_decl || in_template_function ())
     return true;
diff --git a/gcc/testsuite/g++.dg/warn/deprecated-11.C 
b/gcc/testsuite/g++.dg/warn/deprecated-11.C
new file mode 100644
index 0000000..5652290
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/deprecated-11.C
@@ -0,0 +1,7 @@
+// PR c++/71274
+// { dg-options -Wdeprecated-declarations }
+
+struct foo
+{
+   __attribute__ ((deprecated)) static const int a;
+};

Reply via email to