re PR c++/33911 (attribute deprecated vs. templates)
authorJason Merrill <jason@redhat.com>
Mon, 17 Nov 2014 22:09:27 +0000 (17:09 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 17 Nov 2014 22:09:27 +0000 (17:09 -0500)
PR c++/33911
gcc/cp/
* call.c (build_call_a): Don't warn_deprecated_use here.
(build_over_call): Or here.
* decl2.c (mark_used): Do it here.
(is_late_template_attribute): Attribute deprecated is not deferred.
(cplus_decl_attributes): Propagate TREE_DEPRECATED out to the template.
* parser.c (cp_parser_template_name): Warn about deprecated template.
(cp_parser_template_argument): Likewise.
libstdc++-v3/
* include/backward/binders.h: Suppress -Wdeprecated-declarations.
* include/ext/array_allocator.h: Likewise.

From-SVN: r217677

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/decl2.c
gcc/cp/parser.c
gcc/testsuite/g++.dg/ext/attr-deprecated-1.C [new file with mode: 0644]
libstdc++-v3/ChangeLog
libstdc++-v3/include/backward/binders.h
libstdc++-v3/include/ext/array_allocator.h

index 05ca493..6e7f657 100644 (file)
@@ -1,5 +1,14 @@
 2014-11-17  Jason Merrill  <jason@redhat.com>
 
+       PR c++/33911
+       * call.c (build_call_a): Don't warn_deprecated_use here.
+       (build_over_call): Or here.
+       * decl2.c (mark_used): Do it here.
+       (is_late_template_attribute): Attribute deprecated is not deferred.
+       (cplus_decl_attributes): Propagate TREE_DEPRECATED out to the template.
+       * parser.c (cp_parser_template_name): Warn about deprecated template.
+       (cp_parser_template_argument): Likewise.
+
        PR c++/50473
        * decl.c (cp_finish_decl): Don't try to process a non-dependent
        constant initializer for a reference.
index 06162aa..c180890 100644 (file)
@@ -387,8 +387,6 @@ build_call_a (tree function, int n, tree *argarray)
       mark_used (decl);
     }
 
-  if (decl && TREE_DEPRECATED (decl))
-    warn_deprecated_use (decl, NULL_TREE);
   require_complete_eh_spec_types (fntype, decl);
 
   TREE_HAS_CONSTRUCTOR (function) = (decl && DECL_CONSTRUCTOR_P (decl));
@@ -7447,11 +7445,6 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
                                ba_any, NULL, complain);
       gcc_assert (binfo && binfo != error_mark_node);
 
-      /* Warn about deprecated virtual functions now, since we're about
-        to throw away the decl.  */
-      if (TREE_DEPRECATED (fn))
-       warn_deprecated_use (fn, NULL_TREE);
-
       argarray[0] = build_base_path (PLUS_EXPR, argarray[0], binfo, 1,
                                     complain);
       if (TREE_SIDE_EFFECTS (argarray[0]))
index fb8d0c8..f3b94a9 100644 (file)
@@ -1204,9 +1204,9 @@ is_late_template_attribute (tree attr, tree decl)
       /* Also defer most attributes on dependent types.  This is not
         necessary in all cases, but is the better default.  */
       else if (dependent_type_p (type)
-              /* But attributes abi_tag and visibility specifically apply
-                 to templates.  */
+              /* But some attributes specifically apply to templates.  */
               && !is_attribute_p ("abi_tag", name)
+              && !is_attribute_p ("deprecated", name)
               && !is_attribute_p ("visibility", name))
        return true;
       else
@@ -1482,6 +1482,17 @@ cplus_decl_attributes (tree *decl, tree attributes, int flags)
 
   if (TREE_CODE (*decl) == TYPE_DECL)
     SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (*decl), TREE_TYPE (*decl));
+
+  /* Propagate deprecation out to the template.  */
+  if (TREE_DEPRECATED (*decl))
+    if (tree ti = get_template_info (*decl))
+      {
+       tree tmpl = TI_TEMPLATE (ti);
+       tree pattern = (TYPE_P (*decl) ? TREE_TYPE (tmpl)
+                       : DECL_TEMPLATE_RESULT (tmpl));
+       if (*decl == pattern)
+         TREE_DEPRECATED (tmpl) = true;
+      }
 }
 \f
 /* Walks through the namespace- or function-scope anonymous union
@@ -4891,6 +4902,10 @@ mark_used (tree decl, tsubst_flags_t complain)
       return false;
     }
 
+  if (TREE_DEPRECATED (decl) && (complain & tf_warning)
+      && deprecated_state != DEPRECATED_SUPPRESS)
+    warn_deprecated_use (decl, NULL_TREE);
+
   /* We can only check DECL_ODR_USED on variables or functions with
      DECL_LANG_SPECIFIC set, and these are also the only decls that we
      might need special handling for.  */
index 3eff5fa..b106f3b 100644 (file)
@@ -13959,7 +13959,11 @@ cp_parser_template_name (cp_parser* parser,
 
   /* If DECL is a template, then the name was a template-name.  */
   if (TREE_CODE (decl) == TEMPLATE_DECL)
-    ;
+    {
+      if (TREE_DEPRECATED (decl)
+         && deprecated_state != DEPRECATED_SUPPRESS)
+       warn_deprecated_use (decl, NULL_TREE);
+    }
   else
     {
       tree fn = NULL_TREE;
@@ -14193,7 +14197,11 @@ cp_parser_template_argument (cp_parser* parser)
        cp_parser_error (parser, "expected template-name");
     }
   if (cp_parser_parse_definitely (parser))
-    return argument;
+    {
+      if (TREE_DEPRECATED (argument))
+       warn_deprecated_use (argument, NULL_TREE);
+      return argument;
+    }
   /* It must be a non-type argument.  There permitted cases are given
      in [temp.arg.nontype]:
 
diff --git a/gcc/testsuite/g++.dg/ext/attr-deprecated-1.C b/gcc/testsuite/g++.dg/ext/attr-deprecated-1.C
new file mode 100644 (file)
index 0000000..31a7690
--- /dev/null
@@ -0,0 +1,15 @@
+// PR c++/33911
+
+template<typename T> struct __attribute__ ((deprecated)) S {};
+S<int> s;                      // { dg-warning "deprecated" }
+
+template <template <class> class T> struct A { };
+A<S> a;                                // { dg-warning "deprecated" }
+
+template <class T> void f() __attribute__ ((deprecated));
+
+int main()
+{
+  f<int>();                    // { dg-warning "deprecated" }
+  void (*p)() = f<char>;       // { dg-warning "deprecated" }
+}
index c6f32e4..857c05e 100644 (file)
@@ -1,3 +1,8 @@
+2014-11-17  Jason Merrill  <jason@redhat.com>
+
+       * include/backward/binders.h: Suppress -Wdeprecated-declarations.
+       * include/ext/array_allocator.h: Likewise.
+
 2014-11-14  Joel Sherrill <joel.sherrill@oarcorp.com>
 
        * src/c++98/mt_allocator.cc: Fix assumption that sizeof(void *) is
index bda52ed..70f8f21 100644 (file)
 #ifndef _BACKWARD_BINDERS_H
 #define _BACKWARD_BINDERS_H 1
 
+// Suppress deprecated warning for this file.
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -173,4 +177,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
+#pragma GCC diagnostic pop
+
 #endif /* _BACKWARD_BINDERS_H */
index f807495..58cf35f 100644 (file)
 #include <type_traits>
 #endif
 
+// Suppress deprecated warning for this file.
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+
 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -171,4 +175,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
+#pragma GCC diagnostic pop
+
 #endif