On 9/5/24 3:15 AM, Jakub Jelinek wrote:
Hi!

This is a continuation of the series for the ignorability of standard
attributes, on top of
https://gcc.gnu.org/pipermail/gcc-patches/2024-August/661904.html
https://gcc.gnu.org/pipermail/gcc-patches/2024-August/661905.html
https://gcc.gnu.org/pipermail/gcc-patches/2024-August/661906.html

I've added a test for assume attribute diagnostics appertaining to various
entities (mostly invalid) and while doing that, I've discovered that
attributes on exception declarations were mostly ignored, this patch
adds the missing cp_decl_attributes call and also in the
cp_parser_type_specifier_seq case differentiates between attributes and
std_attributes to be able to differentiate between attributes which apply
to the declaration using type-specifier-seq and attributes after the type
specifiers.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

2024-09-05  Jakub Jelinek  <ja...@redhat.com>

        PR c++/110345
        * parser.cc (cp_parser_type_specifier_seq): Chain cxx11_attribute_p
        attributes after any type specifier in the is_declaration case
        to std_attributes rather than attributes.  Set also ds_attribute
        or ds_std_attribute locations if not yet set.
        (cp_parser_exception_declaration): Pass &type_specifiers.attributes
        instead of NULL as last argument, call cp_decl_attributes.

        * g++.dg/cpp0x/attr-assume1.C: New test.
        * g++.dg/cpp0x/attr-deprecated1.C: Add tests for attributes
        after type specifiers before parameter or exception declarations
        and after parameter or exception declaration declarators.

--- gcc/cp/parser.cc.jj 2024-09-04 12:36:51.903244117 +0200
+++ gcc/cp/parser.cc    2024-09-04 15:13:22.875960509 +0200
@@ -25375,9 +25375,24 @@ cp_parser_type_specifier_seq (cp_parser*
                  || tok->type == CPP_EQ || tok->type == CPP_OPEN_BRACE)
                break;
            }
-         type_specifier_seq->attributes
-           = attr_chainon (type_specifier_seq->attributes,
-                           cp_parser_attributes_opt (parser));
+         location_t attr_loc = cp_lexer_peek_token (parser->lexer)->location;
+         tree attrs = cp_parser_attributes_opt (parser);
+         if (seen_type_specifier
+             && is_declaration
+             && cxx11_attribute_p (attrs))
+           {
+             type_specifier_seq->std_attributes
+               = attr_chainon (type_specifier_seq->std_attributes, attrs);
+             if (type_specifier_seq->locations[ds_std_attribute] == 0)
+               type_specifier_seq->locations[ds_std_attribute] = attr_loc;
+           }
+         else
+           {
+             type_specifier_seq->attributes
+               = attr_chainon (type_specifier_seq->attributes, attrs);
+             if (type_specifier_seq->locations[ds_attribute] == 0)
+               type_specifier_seq->locations[ds_attribute] = attr_loc;
+           }
          continue;
        }
@@ -29630,7 +29645,12 @@ cp_parser_exception_declaration (cp_pars
    if (!type_specifiers.any_specifiers_p)
      return error_mark_node;
- return grokdeclarator (declarator, &type_specifiers, CATCHPARM, 1, NULL);
+  tree decl = grokdeclarator (declarator, &type_specifiers, CATCHPARM, 1,
+                             &type_specifiers.attributes);
+  if (decl != error_mark_node && type_specifiers.attributes)
+    cplus_decl_attributes (&decl, type_specifiers.attributes, 0);
+
+  return decl;
  }
/* Parse a throw-expression.
--- gcc/testsuite/g++.dg/cpp0x/attr-assume1.C.jj        2024-09-04 
12:47:19.356072957 +0200
+++ gcc/testsuite/g++.dg/cpp0x/attr-assume1.C   2024-09-04 15:28:42.486057664 
+0200
@@ -0,0 +1,151 @@
+// C++ 26 P2552R3 - On the ignorability of standard attributes
+// { dg-do compile { target c++11 } }
+
+int arr[2];
+struct S { int a, b; };
+S arr2[2];
+
+void
+foo (int n)
+{
+  [[assume (n > 0)]];
+  [[assume]];                                  // { dg-error "wrong number of 
arguments specified for 'assume' attribute" }
+  [[assume ("abc")]];
+  [[assume (1, 2, 3)]];                                // { dg-error "wrong number 
of arguments specified for 'assume' attribute" }
+
+  [[assume (true)]] int x1;                    // { dg-error "'assume' attribute 
ignored" }
+
+  auto a = [] [[assume (true)]] () {};         // { dg-error "'assume' attribute 
ignored" }
+  auto b = [] constexpr [[assume (true)]] {};  // { dg-error "'assume' attribute 
ignored" }
+                                               // { dg-error "parameter declaration before 
lambda declaration specifiers only optional with" "" { target c++20_down } .-1 }
+                                               // { dg-error "'constexpr' lambda only 
available with" "" { target c++14_down } .-2 }
+  auto c = [] noexcept [[assume (true)]] {};   // { dg-error "'assume' attribute 
ignored" }
+                                               // { dg-error "parameter declaration before 
lambda exception specification only optional with" "" { target c++20_down } .-1 }
+  auto d = [] () [[assume (true)]] {};         // { dg-error "'assume' attribute 
ignored" }
+  auto e = new int [n] [[assume (true)]];      // { dg-warning "attributes ignored 
on outermost array type in new expression" }
+  auto e2 = new int [n] [[assume (true)]] [42];        // { dg-warning "attributes 
ignored on outermost array type in new expression" }
+  auto f = new int [n][42] [[assume (true)]];  // { dg-error "'assume' attribute 
ignored" }
+  [[assume (true)]];
+  [[assume (true)]] {}                         // { dg-warning "attributes at the 
beginning of statement are ignored" }
+  [[assume (true)]] if (true) {}               // { dg-warning "attributes at the 
beginning of statement are ignored" }
+  [[assume (true)]] while (false) {}           // { dg-warning "attributes at the 
beginning of statement are ignored" }
+  [[assume (true)]] goto lab;                  // { dg-warning "attributes at the 
beginning of statement are ignored" }
+  [[assume (true)]] lab:;                      // { dg-error "'assume' attribute 
ignored" }
+  [[assume (true)]] try {} catch (int) {}      // { dg-warning "attributes at the 
beginning of statement are ignored" }
+  if ([[assume (true)]] int x = 0) {}          // { dg-error "'assume' attribute 
ignored" }
+  switch (n)
+    {
+    [[assume (true)]] case 1:                  // { dg-error "'assume' attribute 
ignored" }
+    [[assume (true)]] break;                   // { dg-warning "attributes at the 
beginning of statement are ignored" }
+    [[assume (true)]] default:                 // { dg-error "'assume' attribute 
ignored" }
+        break;
+    }
+  for ([[assume (true)]] auto a : arr) {}      // { dg-error "'assume' attribute 
ignored" }
+  for ([[assume (true)]] auto [a, b] : arr2) {}        // { dg-error "'assume' 
attribute ignored" }
+                                               // { dg-error "structured bindings only 
available with" "" { target c++14_down } .-1 }
+  [[assume (true)]] asm ("");                        // { dg-warning "attributes 
ignored on 'asm' declaration" }
+  try {} catch ([[assume (true)]] int x) {}    // { dg-error "'assume' attribute 
ignored" }
+  try {} catch ([[assume (true)]] int) {}      // { dg-error "'assume' attribute 
ignored" }
+  try {} catch (int [[assume (true)]] x) {}    // { dg-warning "attribute 
ignored" }
+  try {} catch (int [[assume (true)]]) {}      // { dg-warning "attribute 
ignored" }
+  try {} catch (int x [[assume (true)]]) {}    // { dg-error "'assume' attribute 
ignored" }
+}
+
+[[assume (true)]] int bar ();                  // { dg-error "'assume' attribute 
ignored" }
+using foobar [[assume (true)]] = int;          // { dg-error "'assume' attribute 
ignored" }
+[[assume (true)]] int a;                       // { dg-error "'assume' attribute 
ignored" }
+[[assume (true)]] auto [b, c] = arr;           // { dg-error "'assume' attribute 
ignored" }
+                                               // { dg-error "structured bindings only 
available with" "" { target c++14_down } .-1 }
+[[assume (true)]];                             // { dg-warning "attribute 
ignored" }
+inline [[assume (true)]] void baz () {}                // { dg-warning "attribute 
ignored" }
+                                               // { dg-error "standard attributes in middle 
of decl-specifiers" "" { target *-*-* } .-1 }
+constexpr [[assume (true)]] int qux () { return 0; }   // { dg-warning "attribute 
ignored" }
+                                               // { dg-error "standard attributes in middle 
of decl-specifiers" "" { target *-*-* } .-1 }
+int [[assume (true)]] d;                       // { dg-warning "attribute 
ignored" }
+int const [[assume (true)]] e = 1;             // { dg-warning "attribute 
ignored" }
+struct A {} [[assume (true)]];                 // { dg-warning "attribute ignored 
in declaration of 'struct A'" }
+struct A [[assume (true)]];                    // { dg-warning "attribute 
ignored" }
+struct A [[assume (true)]] a1;                 // { dg-warning "attribute 
ignored" }
+A [[assume (true)]] a2;                                // { dg-warning "attribute 
ignored" }
+enum B { B0 } [[assume (true)]];               // { dg-warning "attribute ignored 
in declaration of 'enum B'" }
+enum B [[assume (true)]];                      // { dg-warning "attribute 
ignored" }
+enum B [[assume (true)]] b1;                   // { dg-warning "attribute 
ignored" }
+B [[assume (true)]] b2;                                // { dg-warning "attribute 
ignored" }
+struct [[assume (true)]] C {};                 // { dg-error "'assume' attribute 
ignored" }
+int f [[assume (true)]];                       // { dg-error "'assume' attribute 
ignored" }
+int g[2] [[assume (true)]];                    // { dg-error "'assume' attribute 
ignored" }
+int g2 [[assume (true)]] [2];                  // { dg-error "'assume' attribute 
ignored" }
+int corge () [[assume (true)]];                        // { dg-error "'assume' 
attribute ignored" }
+int *[[assume (true)]] h;                      // { dg-error "'assume' attribute 
ignored" }
+int & [[assume (true)]] i = f;                     // { dg-error "'assume' 
attribute ignored" }
+int && [[assume (true)]] j = 0;                        // { dg-error "'assume' 
attribute ignored" }
+int S::* [[assume (true)]] k;                  // { dg-error "'assume' attribute 
ignored" }
+auto l = sizeof (int [2] [[assume (true)]]);   // { dg-error "'assume' attribute 
ignored" }
+int freddy ([[assume (true)]] int a,           // { dg-error "'assume' attribute 
ignored" }
+           [[assume (true)]] int,              // { dg-error "'assume' attribute 
ignored" }
+           [[assume (true)]] int c = 0,        // { dg-error "'assume' attribute 
ignored" }
+           [[assume (true)]] int = 0);         // { dg-error "'assume' attribute 
ignored" }
+void
+corge ([[assume (true)]] int a,                        // { dg-error "'assume' 
attribute ignored" }
+       [[assume (true)]] int,                  // { dg-error "'assume' attribute 
ignored" }
+       [[assume (true)]] int c = 0,            // { dg-error "'assume' attribute 
ignored" }
+       [[assume (true)]] int = 0)              // { dg-error "'assume' attribute 
ignored" }
+{
+}
+[[assume (true)]] void
+garply ()                                      // { dg-error "'assume' attribute 
ignored" }
+{
+}
+int grault (int [[assume (true)]] a,           // { dg-warning "attribute 
ignored" }
+           int [[assume (true)]],              // { dg-warning "attribute 
ignored" }
+           int [[assume (true)]] c = 0,        // { dg-warning "attribute 
ignored" }
+           int [[assume (true)]] = 0);         // { dg-warning "attribute 
ignored" }
+void
+waldo (int [[assume (true)]] a,                        // { dg-warning "attribute 
ignored" }
+       int [[assume (true)]],                  // { dg-warning "attribute 
ignored" }
+       int [[assume (true)]] c = 0,            // { dg-warning "attribute 
ignored" }
+       int [[assume (true)]] = 0)              // { dg-warning "attribute 
ignored" }
+{
+}
+int plugh (int a [[assume (true)]],            // { dg-error "'assume' attribute 
ignored" }
+           int b [[assume (true)]] = 0);       // { dg-error "'assume' attribute 
ignored" }
+void
+thud (int a [[assume (true)]],                 // { dg-error "'assume' attribute 
ignored" }
+      int b [[assume (true)]] = 0)             // { dg-error "'assume' attribute 
ignored" }
+{
+}
+enum [[assume (true)]] D { D0 };               // { dg-error "'assume' attribute 
ignored" }
+enum class [[assume (true)]] E { E0 };         // { dg-error "'assume' attribute 
ignored" }
+enum F {};
+enum [[assume (true)]] F;                      // { dg-warning "type attributes 
ignored after type is already defined" }
+enum G {
+  G0 [[assume (true)]],                                // { dg-error "'assume' 
attribute ignored" }
+  G1 [[assume (true)]] = 2                     // { dg-error "'assume' attribute 
ignored" }
+};
+namespace [[assume (true)]] H { using H0 = int; }      // { dg-warning "'assume' 
attribute directive ignored" } */
+namespace [[assume (true)]] {}                 // { dg-warning "'assume' attribute 
directive ignored" }
+[[assume (true)]] using namespace H;           // { dg-warning "'assume' attribute 
directive ignored" }
+struct [[assume (true)]] I                     // { dg-error "'assume' attribute 
ignored" }
+{
+  [[assume (true)]];                           // { dg-error "declaration does not 
declare anything" }
+  [[assume (true)]] int i;                     // { dg-error "'assume' attribute 
ignored" }
+  [[assume (true)]] int foo ();                        // { dg-error "'assume' 
attribute ignored" }
+  [[assume (true)]] int bar () { return 1; }   // { dg-error "'assume' attribute 
ignored" }
+  [[assume (true)]] int : 0;                   // { dg-error "'assume' attribute 
ignored" }
+  [[assume (true)]] int i2 : 5;                        // { dg-error "'assume' 
attribute ignored" }
+  [[assume (true)]] static int i3;             // { dg-error "'assume' attribute 
ignored" }
+  static int i4;
+};
+[[assume (true)]] int I::i4 = 0;               // { dg-error "'assume' attribute 
ignored" }
+struct J : [[assume (true)]] C {};             // { dg-warning "attributes on base 
specifiers are ignored" }
+#if __cpp_concepts >= 201907L
+template <typename T>
+concept K [[assume (true)]] = requires { true; };      // { dg-error "'assume' attribute 
ignored" "" { target c++20 } }
+#endif
+typedef int L [[assume (true)]];               // { dg-error "'assume' attribute 
ignored" }
+template <typename T>
+struct M {};
+template <>
+struct [[assume (true)]] M<int> { int m; };      // { dg-error "'assume' attribute 
ignored" }
+typedef int N[2] [[assume (true)]];            // { dg-error "'assume' attribute 
ignored" }
+typedef int O [[assume (true)]] [2];           // { dg-error "'assume' attribute 
ignored" }
--- gcc/testsuite/g++.dg/cpp0x/attr-deprecated1.C.jj    2024-09-04 
12:36:51.904244104 +0200
+++ gcc/testsuite/g++.dg/cpp0x/attr-deprecated1.C       2024-09-04 
15:29:38.233337176 +0200
@@ -46,6 +46,9 @@ foo (int n)
    [[deprecated]] asm ("");                  // { dg-warning "attributes ignored on 
'asm' declaration" }
    try {} catch ([[deprecated]] int x) {}
    try {} catch ([[deprecated]] int) {}
+  try {} catch (int [[deprecated]] x) {}       // { dg-warning "attribute 
ignored" }
+  try {} catch (int [[deprecated]]) {}         // { dg-warning "attribute 
ignored" }
+  try {} catch (int x [[deprecated]]) {}
  }
[[deprecated]] int bar ();
@@ -93,6 +96,24 @@ corge ([[deprecated]] int a,
  garply ()
  {
  }
+int grault (int [[deprecated]] a,              // { dg-warning "attribute 
ignored" }
+           int [[deprecated]],                 // { dg-warning "attribute 
ignored" }
+           int [[deprecated]] c = 0,           // { dg-warning "attribute 
ignored" }
+           int [[deprecated]] = 0);            // { dg-warning "attribute 
ignored" }
+void
+waldo (int [[deprecated]] a,                   // { dg-warning "attribute 
ignored" }
+       int [[deprecated]],                     // { dg-warning "attribute 
ignored" }
+       int [[deprecated]] c = 0,               // { dg-warning "attribute 
ignored" }
+       int [[deprecated]] = 0)                 // { dg-warning "attribute 
ignored" }
+{
+}
+int plugh (int a [[deprecated]],
+           int b [[deprecated]] = 0);
+void
+thud (int a [[deprecated]],
+      int b [[deprecated]] = 0)
+{
+}
  enum [[deprecated]] D { D0 };
  enum class [[deprecated]] E { E0 };
  enum F {};

        Jakub


Reply via email to