Bug 84222 - [6/7 Regression] [[deprecated]] class complains about internal class usage
Summary: [6/7 Regression] [[deprecated]] class complains about internal class usage
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 8.0
: P2 normal
Target Milestone: 6.5
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks: 79078
  Show dependency treegraph
 
Reported: 2018-02-05 23:51 UTC by Daryl Haresign
Modified: 2018-06-25 18:13 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work: 4.2.3
Known to fail: 4.3.4, 4.5.4, 4.8.3, 4.9.3, 5.3.0, 6.2.0, 7.1.0, 8.0
Last reconfirmed: 2018-03-21 00:00:00


Attachments
gcc8-pr84222.patch (2.04 KB, patch)
2018-03-14 12:15 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Daryl Haresign 2018-02-05 23:51:34 UTC
If I mark a class with the [[deprecated]] annotation, it complains when the class uses its own name in the implementation:

class [[deprecated]] C {
  public:
    C() {}
    C(const C&) = default;  // emits a deprecation warning
    C(C&&) = delete;        // also emits a warning
};
Comment 1 Daryl Haresign 2018-02-06 00:03:52 UTC
Additionally, any external use of a static method of a deprecated class should probably (but does not currently) emit a warning (Clang emits a warning).

class [[deprecated]] C {
  public:
    void fn() {}
};

int main()
{
    C::fn();  // does not emit a deprecation warning
}
Comment 2 Daryl Haresign 2018-02-06 00:05:02 UTC
See also bug 79817.
Comment 3 Martin Sebor 2018-02-06 16:56:18 UTC
Confirmed with the following simplified C++ 98 test case:

$ cat pr84222.C && gcc -O2 -c -g -Wall pr84222.C
struct __attribute__ ((deprecated)) C {
    C() {}
    C(const C&);  // emits a deprecation warning
};
pr84222.C:3:15: warning: ‘C’ is deprecated [-Wdeprecated-declarations]
     C(const C&);  // emits a deprecation warning
               ^

It's a very old regression introduced in GCC 4.3.  The likely candidate is 
r128691:

        PR c++/16370
        * decl.c (grokdeclarator): Look through implicit TYPE_DECLs
        for deprecation warnings.
Comment 4 Martin Sebor 2018-02-06 17:19:56 UTC
This is a subset of bug 79078 that lists a number of problems with the handling of attribute deprecated.  I'm keeping this one open independent of the latter since this is a regression.
Comment 5 Jakub Jelinek 2018-02-08 19:25:08 UTC
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).
Comment 6 Jakub Jelinek 2018-02-08 19:36:37 UTC
Checking DECL_CONTEXT of current_function_decl if non-NULL doesn't seem to work either.
Comment 7 Jakub Jelinek 2018-03-14 12:15:56 UTC
Created attachment 43651 [details]
gcc8-pr84222.patch

Untested fix.
Comment 8 Jakub Jelinek 2018-03-15 17:45:44 UTC
Author: jakub
Date: Thu Mar 15 17:45:01 2018
New Revision: 258568

URL: https://gcc.gnu.org/viewcvs?rev=258568&root=gcc&view=rev
Log:
	PR c++/84222
	* cp-tree.h (cp_warn_deprecated_use): Declare.
	* tree.c (cp_warn_deprecated_use): New function.
	* typeck2.c (build_functional_cast): Use it.
	* decl.c (grokparms): Likewise.
	(grokdeclarator): Likewise.  Temporarily push nested class scope
	around grokparms call for out of class member definitions.

	* g++.dg/warn/deprecated.C (T::member3): Change dg-warning to dg-bogus.
	* g++.dg/warn/deprecated-6.C (T::member3): Likewise.
	* g++.dg/warn/deprecated-13.C: New test.

Added:
    trunk/gcc/testsuite/g++.dg/warn/deprecated-13.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/cp-tree.h
    trunk/gcc/cp/decl.c
    trunk/gcc/cp/tree.c
    trunk/gcc/cp/typeck2.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/g++.dg/warn/deprecated-6.C
    trunk/gcc/testsuite/g++.dg/warn/deprecated.C
Comment 9 Jakub Jelinek 2018-03-15 18:09:43 UTC
Fixed for 8.1+.
Comment 10 Martin Sebor 2018-03-21 16:00:59 UTC
Let me change the Status to New since it's fixed for GCC 8.

Jakub, do you expect to backport the patch to older branches?
Comment 11 Jakub Jelinek 2018-06-22 20:43:41 UTC
Author: jakub
Date: Fri Jun 22 20:43:09 2018
New Revision: 261924

URL: https://gcc.gnu.org/viewcvs?rev=261924&root=gcc&view=rev
Log:
	Backported from mainline
	2018-03-15  Jakub Jelinek  <jakub@redhat.com>

	PR c++/84222
	* cp-tree.h (cp_warn_deprecated_use): Declare.
	* tree.c (cp_warn_deprecated_use): New function.
	* typeck2.c (build_functional_cast): Use it.
	* decl.c (grokparms): Likewise.
	(grokdeclarator): Likewise.  Temporarily push nested class scope
	around grokparms call for out of class member definitions.

	* g++.dg/warn/deprecated.C (T::member3): Change dg-warning to dg-bogus.
	* g++.dg/warn/deprecated-6.C (T::member3): Likewise.
	* g++.dg/warn/deprecated-13.C: New test.

Added:
    branches/gcc-7-branch/gcc/testsuite/g++.dg/warn/deprecated-13.C
Modified:
    branches/gcc-7-branch/gcc/cp/ChangeLog
    branches/gcc-7-branch/gcc/cp/cp-tree.h
    branches/gcc-7-branch/gcc/cp/decl.c
    branches/gcc-7-branch/gcc/cp/tree.c
    branches/gcc-7-branch/gcc/cp/typeck2.c
    branches/gcc-7-branch/gcc/testsuite/ChangeLog
    branches/gcc-7-branch/gcc/testsuite/g++.dg/warn/deprecated-6.C
    branches/gcc-7-branch/gcc/testsuite/g++.dg/warn/deprecated.C
Comment 12 Jakub Jelinek 2018-06-25 17:32:43 UTC
Author: jakub
Date: Mon Jun 25 17:32:10 2018
New Revision: 262075

URL: https://gcc.gnu.org/viewcvs?rev=262075&root=gcc&view=rev
Log:
	Backported from mainline
	2018-03-15  Jakub Jelinek  <jakub@redhat.com>

	PR c++/84222
	* cp-tree.h (cp_warn_deprecated_use): Declare.
	* tree.c (cp_warn_deprecated_use): New function.
	* typeck2.c (build_functional_cast): Use it.
	* decl.c (grokparms): Likewise.
	(grokdeclarator): Likewise.  Temporarily push nested class scope
	around grokparms call for out of class member definitions.

	* g++.dg/warn/deprecated.C (T::member3): Change dg-warning to dg-bogus.
	* g++.dg/warn/deprecated-6.C (T::member3): Likewise.
	* g++.dg/warn/deprecated-13.C: New test.

Added:
    branches/gcc-6-branch/gcc/testsuite/g++.dg/warn/deprecated-13.C
Modified:
    branches/gcc-6-branch/gcc/cp/ChangeLog
    branches/gcc-6-branch/gcc/cp/cp-tree.h
    branches/gcc-6-branch/gcc/cp/decl.c
    branches/gcc-6-branch/gcc/cp/tree.c
    branches/gcc-6-branch/gcc/cp/typeck2.c
    branches/gcc-6-branch/gcc/testsuite/ChangeLog
    branches/gcc-6-branch/gcc/testsuite/g++.dg/warn/deprecated-6.C
    branches/gcc-6-branch/gcc/testsuite/g++.dg/warn/deprecated.C
Comment 13 Jakub Jelinek 2018-06-25 18:13:07 UTC
Fixed for 6.5 and 7.4+ too.