c++: Fix bogus "does not declare anything" warning (PR 66159)

Message ID 20200527094419.GA2933526@redhat.com
State Superseded
Headers show
Series
  • c++: Fix bogus "does not declare anything" warning (PR 66159)
Related show

Commit Message

Kewen.Lin via Gcc-patches May 27, 2020, 9:44 a.m.
G++ gives a bogus warning for 'struct A; using B = struct ::A;'
complaining that the elaborated-type-specifier doesn't declare anything.
That's true, but it's not trying to declare struct ::A, just refer to it
unambiguously. Do not emit the warning unless we're actually parsing a
declaration.

This also makes the relevant warning depend on -Wredundant-decls (which
is not part of -Wall or -Wextra) so it can be disabled on the command
line or by using #pragma. This means the warning will no longer be given
by default, so some tests need -Wredundant-decls added.

gcc/cp/ChangeLog:

	PR c++/66159
	* parser.c (cp_parser_elaborated_type_specifier): Do not warn
	unless in a declaration. Make warning depend on
	WOPT_redundant_decls.

gcc/testsuite/ChangeLog:

	PR c++/66159
	* g++.dg/parse/specialization1.C: Remove dg-warning.
	* g++.dg/warn/forward-inner.C: Add -Wredundant-decls. Check
	alias-declaration using elaborated-type-specifier.
	* g++.dg/warn/pr36999.C: Add -Wredundant-decls.


Is it OK to make this warning no longer emitted by default, and not
even with -Wall -Wextra?

Would it be better to add a new option for this specific warning,
which would be enabled by -Wall and also by -Wredundant-decls? Maybe
-Wredundant-decls-elaborated-type or something.
commit c254d7cb3977484fd4737b973a87c1df98c30e01
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed May 27 10:40:38 2020 +0100

    c++: Fix bogus "does not declare anything" warning (PR 66159)
    
    G++ gives a bogus warning for 'struct A; using B = struct ::A;'
    complaining that the elaborated-type-specifier doesn't declare anything.
    That's true, but it's not trying to declare struct ::A, just refer to it
    unambiguously. Do not emit the warning unless we're actually parsing a
    declaration.
    
    This also makes the relevant warning depend on -Wredundant-decls (which
    is not part of -Wall or -Wextra) so it can be disabled on the command
    line or by using #pragma. This means the warning will no longer be given
    by default, so some tests need -Wredundant-decls added.
    
    gcc/cp/ChangeLog:
    
            PR c++/66159
            * parser.c (cp_parser_elaborated_type_specifier): Do not warn
            unless in a declaration. Make warning depend on
            WOPT_redundant_decls.
    
    gcc/testsuite/ChangeLog:
    
            PR c++/66159
            * g++.dg/parse/specialization1.C: Remove dg-warning.
            * g++.dg/warn/forward-inner.C: Add -Wredundant-decls. Check
            alias-declaration using elaborated-type-specifier.
            * g++.dg/warn/pr36999.C: Add -Wredundant-decls.

Patch

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 54ca875ce54..5287ab34752 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -18917,8 +18917,10 @@  cp_parser_elaborated_type_specifier (cp_parser* parser,
              here.  */
 
           if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)
-              && !is_friend && !processing_explicit_instantiation)
-            warning (0, "declaration %qD does not declare anything", decl);
+	      && !is_friend && is_declaration
+	      && !processing_explicit_instantiation)
+	    warning (OPT_Wredundant_decls,
+		     "declaration %qD does not declare anything", decl);
 
 	  type = TREE_TYPE (decl);
 	}
diff --git a/gcc/testsuite/g++.dg/parse/specialization1.C b/gcc/testsuite/g++.dg/parse/specialization1.C
index 44a98baa2f4..6d83bc4f254 100644
--- a/gcc/testsuite/g++.dg/parse/specialization1.C
+++ b/gcc/testsuite/g++.dg/parse/specialization1.C
@@ -4,4 +4,3 @@ 
 
 template <typename T> class A;
 template <typename T> class A<T>::B; // { dg-error "declaration" "err" }
-// { dg-warning "declaration" "warn" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/g++.dg/warn/forward-inner.C b/gcc/testsuite/g++.dg/warn/forward-inner.C
index 5336d4ed946..1c10ec44a54 100644
--- a/gcc/testsuite/g++.dg/warn/forward-inner.C
+++ b/gcc/testsuite/g++.dg/warn/forward-inner.C
@@ -1,5 +1,6 @@ 
 // Check that the compiler warns about inner-style forward declarations in
 // contexts where they're not actually illegal, but merely useless.
+// { dg-options "-Wredundant-decls" }
 
 // Verify warnings for and within classes, and by extension, struct and union.
 class C1;
@@ -70,7 +71,7 @@  template class TC6<int>::TC7;  // Valid explicit instantiation, no warning
 
 
 // Verify that friend declarations, also easy to confuse with forward
-// declrations, are similarly not warned about.
+// declarations, are similarly not warned about.
 class C8 {
  public:
   class C9 { };
@@ -79,3 +80,10 @@  class C10 {
  public:
   friend class C8::C9;         // Valid friend declaration, no warning
 };
+
+#if __cplusplus >= 201103L
+// Verify that alias-declarations using an elaborated-type-specifier and
+// nested-name-specifier are not warned about (PR c++/66159).
+struct C11;
+using A1 = struct ::C11; // Valid alias-decl, no warning
+#endif
diff --git a/gcc/testsuite/g++.dg/warn/pr36999.C b/gcc/testsuite/g++.dg/warn/pr36999.C
index ce2286efcf4..6f69e192d02 100644
--- a/gcc/testsuite/g++.dg/warn/pr36999.C
+++ b/gcc/testsuite/g++.dg/warn/pr36999.C
@@ -1,5 +1,6 @@ 
 /* PR36999: Erroneous "does not declare anything" warnings.  */
 /* { dg-do compile } */
+/* { dg-options "-Wredundant-decls" } */
 
 class C1 {
  public: class C2 { };