https://gcc.gnu.org/g:2f90f3850eaf9d703d9eb63d5f0347158aa11027

commit r15-2948-g2f90f3850eaf9d703d9eb63d5f0347158aa11027
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Fri Aug 16 11:43:18 2024 +0200

    c++: Pedwarn on [[]]; at class scope [PR110345]
    
    For C++ 26 P2552R3 I went through all the spots (except modules) where
    attribute-specifier-seq appears in the grammar and tried to construct
    a testcase in all those spots, for now for [[deprecated]] attribute.
    
    The fourth issue is that we just emit (when enabled) -Wextra-semi warning
    not just for lone semicolon at class scope (correct), but also for
    [[]]; or [[whatever]]; there too.
    While just semicolon is valid in C++11 and newer,
    https://eel.is/c++draft/class.mem#nt:member-declaration
    allows empty-declaration, unlike namespace scope or block scope
    something like attribute-declaration or empty statement with attributes
    applied for it aren't supported.
    While syntactically it matches
    attribute-specifier-seq [opt] decl-specifier-seq [opt] 
member-declarator-list [opt] ;
    with the latter two omitted, there is
    https://eel.is/c++draft/class.mem#general-3
    which says that is not valid.
    
    So, the following patch emits a pedwarn in that case.
    
    2024-08-16  Jakub Jelinek  <ja...@redhat.com>
    
            PR c++/110345
            * parser.cc (cp_parser_member_declaration): Call 
maybe_warn_extra_semi
            only if it is empty-declaration, if there are some tokens like
            attribute, pedwarn that the declaration doesn't declare anything.
    
            * g++.dg/cpp0x/gen-attrs-84.C: New test.

Diff:
---
 gcc/cp/parser.cc                          | 6 +++++-
 gcc/testsuite/g++.dg/cpp0x/gen-attrs-84.C | 8 ++++++++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 852efe45076..c9654cfff9d 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -28259,7 +28259,11 @@ cp_parser_member_declaration (cp_parser* parser)
       if (!decl_specifiers.any_specifiers_p)
        {
          cp_token *token = cp_lexer_peek_token (parser->lexer);
-         maybe_warn_extra_semi (token->location, extra_semi_kind::member);
+         if (decl_spec_token_start == token)
+           maybe_warn_extra_semi (token->location, extra_semi_kind::member);
+         else
+           pedwarn (decl_spec_token_start->location, OPT_Wpedantic,
+                    "declaration does not declare anything");
        }
       else
        {
diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-84.C 
b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-84.C
new file mode 100644
index 00000000000..c573918cd06
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-84.C
@@ -0,0 +1,8 @@
+// { dg-do compile { target c++11 } }
+
+struct A {
+  [[]];                        // { dg-error "declaration does not declare 
anything" }
+};
+struct B {
+  [[gnu::deprecated]]; // { dg-error "declaration does not declare anything" }
+};

Reply via email to