https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84222

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org,
                   |                            |jason at gcc dot gnu.org

--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
With:
--- gcc/cp/cp-tree.h.jj 2018-02-07 23:28:55.750401640 +0100
+++ gcc/cp/cp-tree.h    2018-02-08 20:08:49.618613211 +0100
@@ -7056,6 +7056,7 @@ extern tree cxx_copy_lang_qualifiers              (c

 extern void cxx_print_statistics               (void);
 extern bool maybe_warn_zero_as_null_pointer_constant (tree, location_t);
+extern void cp_warn_deprecated_use             (tree);

 /* in ptree.c */
 extern void cxx_print_xnode                    (FILE *, tree, int);
--- gcc/cp/tree.c.jj    2018-02-06 13:12:48.121808347 +0100
+++ gcc/cp/tree.c       2018-02-08 20:08:22.293628631 +0100
@@ -5348,6 +5348,19 @@ maybe_warn_zero_as_null_pointer_constant
     }
   return false;
 }
+
+/* Wrapper around warn_deprecated_use that doesn't warn for
+   current_class_type.  */
+
+void
+cp_warn_deprecated_use (tree node)
+{
+  if (TYPE_P (node)
+      && current_class_type
+      && TYPE_MAIN_VARIANT (node) == current_class_type)
+    return;
+  warn_deprecated_use (node, NULL_TREE);
+}


 #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
 /* Complain that some language-specific thing hanging off a tree
--- gcc/cp/decl.c.jj    2018-02-07 23:28:55.731401645 +0100
+++ gcc/cp/decl.c       2018-02-08 20:09:53.655577074 +0100
@@ -10363,7 +10363,7 @@ grokdeclarator (const cp_declarator *dec
      suppress reports of deprecated items.  */
   if (type && TREE_DEPRECATED (type)
       && deprecated_state != DEPRECATED_SUPPRESS)
-    warn_deprecated_use (type, NULL_TREE);
+    cp_warn_deprecated_use (type);
   if (type && TREE_CODE (type) == TYPE_DECL)
     {
       typedef_decl = type;
@@ -10371,7 +10371,7 @@ grokdeclarator (const cp_declarator *dec
       if (TREE_DEPRECATED (type)
          && DECL_ARTIFICIAL (typedef_decl)
          && deprecated_state != DEPRECATED_SUPPRESS)
-       warn_deprecated_use (type, NULL_TREE);
+       cp_warn_deprecated_use (type);
     }
   /* No type at all: default to `int', and set DEFAULTED_INT
      because it was not a user-defined typedef.  */
@@ -12712,7 +12712,7 @@ grokparms (tree parmlist, tree *parms)
            {
              tree deptype = type_is_deprecated (type);
              if (deptype)
-               warn_deprecated_use (deptype, NULL_TREE);
+               cp_warn_deprecated_use (deptype);
            }

          /* Top-level qualifiers on the parameters are
--- gcc/cp/typeck2.c.jj 2018-02-06 13:12:48.146808267 +0100
+++ gcc/cp/typeck2.c    2018-02-08 20:12:48.880478192 +0100
@@ -2056,7 +2056,7 @@ build_functional_cast (tree exp, tree pa
       if (complain & tf_warning
          && TREE_DEPRECATED (type)
          && DECL_ARTIFICIAL (exp))
-       warn_deprecated_use (type, NULL_TREE);
+       cp_warn_deprecated_use (type);
     }
   else
     type = exp;

we don't warn inside of the deprecated classes or templates (which is I think a
good thing), but do warn when defining methods for those classes or class
templates outside of the class definitions (which is I think undesirable).

Testcase:
struct __attribute__((deprecated)) C {
  C () {}
  C (const C &);
  C (const C &x, const C &y) { C z = x; }
  void foo (const C &x, const C &y);
};

void
C::foo (const C &x, const C &y)
{
  C z = x;
}

void
bar (const C &x, const C &y)
{
  C z = x;
}

template <int N>
struct __attribute__((deprecated)) D {
  D () {}
  D (const D &);
  D (const D &x, const D &y) { D z = x; }
  void foo (const D &x, const D &y);
};

template <int N>
void
D<N>::foo (const D &x, const D &y)
{
  D z = x;
}

template <int N>
void
baz (const D<N> &x, const D<N> &y)
{
  D<N> z = x;
}

Note, clang++ seems to warn only on bar, doesn't warn inside of the class
definitions (matches the patch), doesn't warn inside of the out of class method
definitions (I'd say desirable), and doesn't warn inside of baz (that looks
like a bug to me, unless they warn only when it is instantiated).

Reply via email to