https://gcc.gnu.org/g:7eb2acb7221b5a219ece1a693d9ac594f229a61a

commit r15-6334-g7eb2acb7221b5a219ece1a693d9ac594f229a61a
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Wed Dec 18 12:00:13 2024 +0100

    c++: Fix up pedantic handling of alignas [PR110345]
    
    The following patch on top of the PR110345 P2552R3 series
    emits pedantic pedwarns for alignas appertaining to incorrect entities.
    As the middle-end and attribute exclusions look for "aligned" attribute,
    the patch transforms alignas into "internal "::aligned attribute (didn't
    use [[aligned (x)]] so that people can't type it that way).
    
    2024-12-18  Jakub Jelinek  <ja...@redhat.com>
    
            PR c++/110345
    gcc/c-family/
            * c-common.h (attr_aligned_exclusions): Declare.
            (handle_aligned_attribute): Likewise.
            * c-attribs.cc (handle_aligned_attribute): No longer
            static.
            (attr_aligned_exclusions): Use extern instead of static.
    gcc/cp/
            * cp-tree.h (enum cp_tree_index): Add CPTI_INTERNAL_IDENTIFIER.
            (internal_identifier): Define.
            (internal_attribute_table): Declare.
            * parser.cc (cp_parser_exception_declaration): Error on alignas
            on exception declaration.
            (cp_parser_std_attribute_spec): Turn alignas into internal
            ns aligned attribute rather than gnu.
            * decl.cc (initialize_predefined_identifiers): Initialize
            internal_identifier.
            * tree.cc (handle_alignas_attribute): New function.
            (internal_attributes): New variable.
            (internal_attribute_table): Likewise.
            * cp-objcp-common.h (cp_objcp_attribute_table): Add
            internal_attribute_table entry.
    gcc/testsuite/
            * g++.dg/cpp0x/alignas1.C: Add dg-options "".
            * g++.dg/cpp0x/alignas2.C: Likewise.
            * g++.dg/cpp0x/alignas7.C: Likewise.
            * g++.dg/cpp0x/alignas21.C: New test.
            * g++.dg/ext/bitfield9.C: Expect a warning.
            * g++.dg/cpp2a/is-layout-compatible3.C: Add dg-options -pedantic.
            Expect a warning.

Diff:
---
 gcc/c-family/c-attribs.cc                          |   5 +-
 gcc/c-family/c-common.h                            |   2 +
 gcc/cp/cp-objcp-common.h                           |   3 +-
 gcc/cp/cp-tree.h                                   |   3 +
 gcc/cp/decl.cc                                     |   1 +
 gcc/cp/parser.cc                                   |  12 +-
 gcc/cp/tree.cc                                     |  41 ++++++
 gcc/testsuite/g++.dg/cpp0x/alignas1.C              |   1 +
 gcc/testsuite/g++.dg/cpp0x/alignas2.C              |   1 +
 gcc/testsuite/g++.dg/cpp0x/alignas21.C             | 156 +++++++++++++++++++++
 gcc/testsuite/g++.dg/cpp0x/alignas7.C              |   1 +
 gcc/testsuite/g++.dg/cpp2a/is-layout-compatible3.C |   3 +-
 gcc/testsuite/g++.dg/ext/bitfield9.C               |   2 +-
 13 files changed, 223 insertions(+), 8 deletions(-)

diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index eb76a9e1c66f..3bb2cb5f83c2 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -101,7 +101,6 @@ static tree handle_destructor_attribute (tree *, tree, 
tree, int, bool *);
 static tree handle_mode_attribute (tree *, tree, tree, int, bool *);
 static tree handle_section_attribute (tree *, tree, tree, int, bool *);
 static tree handle_special_var_sec_attribute (tree *, tree, tree, int, bool *);
-static tree handle_aligned_attribute (tree *, tree, tree, int, bool *);
 static tree handle_warn_if_not_aligned_attribute (tree *, tree, tree,
                                                  int, bool *);
 static tree handle_strict_flex_array_attribute (tree *, tree, tree,
@@ -195,7 +194,7 @@ static tree handle_null_terminated_string_arg_attribute 
(tree *, tree, tree, int
   { name, function, type, variable }
 
 /* Define attributes that are mutually exclusive with one another.  */
-static const struct attribute_spec::exclusions attr_aligned_exclusions[] =
+extern const struct attribute_spec::exclusions attr_aligned_exclusions[] =
 {
   /* Attribute name     exclusion applies to:
                        function, type, variable */
@@ -2816,7 +2815,7 @@ common_handle_aligned_attribute (tree *node, tree name, 
tree args, int flags,
 /* Handle a "aligned" attribute; arguments as in
    struct attribute_spec.handler.  */
 
-static tree
+tree
 handle_aligned_attribute (tree *node, tree name, tree args,
                          int flags, bool *no_add_attrs)
 {
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index ac574e922e3b..13406e27609b 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1666,8 +1666,10 @@ extern int parse_tm_stmt_attr (tree, int);
 extern int tm_attr_to_mask (tree);
 extern tree tm_mask_to_attr (int);
 extern tree find_tm_attribute (tree);
+extern const struct attribute_spec::exclusions attr_aligned_exclusions[];
 extern const struct attribute_spec::exclusions attr_cold_hot_exclusions[];
 extern const struct attribute_spec::exclusions attr_noreturn_exclusions[];
+extern tree handle_aligned_attribute (tree *, tree, tree, int, bool *);
 extern tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
 extern tree handle_musttail_attribute (tree *, tree, tree, int, bool *);
 extern bool has_attribute (location_t, tree, tree, tree (*)(tree));
diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h
index e9c5ac40020c..5b3abb547d25 100644
--- a/gcc/cp/cp-objcp-common.h
+++ b/gcc/cp/cp-objcp-common.h
@@ -129,7 +129,8 @@ static const scoped_attribute_specs *const 
cp_objcp_attribute_table[] =
   &cxx_gnu_attribute_table,
   &c_common_gnu_attribute_table,
   &c_common_clang_attribute_table,
-  &c_common_format_attribute_table
+  &c_common_format_attribute_table,
+  &internal_attribute_table
 };
 
 #undef LANG_HOOKS_ATTRIBUTE_TABLE
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index c5e0fc5c440d..6833035664b0 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -192,6 +192,7 @@ enum cp_tree_index
     CPTI_HEAP_VEC_UNINIT_IDENTIFIER,
     CPTI_HEAP_VEC_IDENTIFIER,
     CPTI_OMP_IDENTIFIER,
+    CPTI_INTERNAL_IDENTIFIER,
 
     CPTI_LANG_NAME_C,
     CPTI_LANG_NAME_CPLUSPLUS,
@@ -345,6 +346,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
 #define heap_vec_uninit_identifier     
cp_global_trees[CPTI_HEAP_VEC_UNINIT_IDENTIFIER]
 #define heap_vec_identifier            
cp_global_trees[CPTI_HEAP_VEC_IDENTIFIER]
 #define omp_identifier                 cp_global_trees[CPTI_OMP_IDENTIFIER]
+#define internal_identifier            
cp_global_trees[CPTI_INTERNAL_IDENTIFIER]
 #define lang_name_c                    cp_global_trees[CPTI_LANG_NAME_C]
 #define lang_name_cplusplus            
cp_global_trees[CPTI_LANG_NAME_CPLUSPLUS]
 
@@ -8215,6 +8217,7 @@ extern bool is_byte_access_type                   (tree);
 extern bool is_byte_access_type_not_plain_char (tree);
 extern const struct scoped_attribute_specs cxx_gnu_attribute_table;
 extern const struct scoped_attribute_specs std_attribute_table;
+extern const struct scoped_attribute_specs internal_attribute_table;
 extern tree make_ptrmem_cst                    (tree, tree);
 extern tree cp_build_type_attribute_variant     (tree, tree);
 extern tree cp_build_reference_type            (tree, bool);
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 135747b75e2b..2716ac5495a5 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -4840,6 +4840,7 @@ initialize_predefined_identifiers (void)
     {"heap [] uninit", &heap_vec_uninit_identifier, cik_normal},
     {"heap []", &heap_vec_identifier, cik_normal},
     {"omp", &omp_identifier, cik_normal},
+    {"internal ", &internal_identifier, cik_normal},
     {NULL, NULL, cik_normal}
   };
 
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 3f4b1e9e3e35..2ad6886af9c3 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -29945,7 +29945,15 @@ cp_parser_exception_declaration (cp_parser* parser)
   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);
+    {
+      cplus_decl_attributes (&decl, type_specifiers.attributes, 0);
+      if (pedantic && lookup_attribute ("internal ", "aligned",
+                                       DECL_ATTRIBUTES (decl)))
+       pedwarn (type_specifiers.locations[ds_attribute]
+                ? type_specifiers.locations[ds_attribute]
+                : input_location, OPT_Wpedantic,
+                "%<alignas%> on exception declaration");
+    }
 
   return decl;
 }
@@ -31396,7 +31404,7 @@ cp_parser_std_attribute_spec (cp_parser *parser)
       /* Build the C++-11 representation of an 'aligned'
         attribute.  */
       attributes
-       = build_tree_list (build_tree_list (gnu_identifier,
+       = build_tree_list (build_tree_list (internal_identifier,
                                            aligned_identifier), alignas_expr);
     }
 
diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index 939d2b060fb4..97ce1f66d2fd 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -5114,6 +5114,35 @@ handle_likeliness_attribute (tree *node, tree name, tree 
args,
     return error_mark_node;
 }
 
+/* The C++11 alignment specifier.  It mostly maps to GNU aligned attribute,
+   but we need to do some extra pedantic checking.  */
+
+static tree
+handle_alignas_attribute (tree *node, tree name, tree args, int flags,
+                         bool *no_add_attrs)
+{
+  tree t = *node;
+  tree ret = handle_aligned_attribute (node, name, args, flags, no_add_attrs);
+  if (pedantic)
+    {
+      if (TREE_CODE (*node) == FUNCTION_DECL)
+       pedwarn (input_location, OPT_Wattributes,
+                "%<alignas%> on function declaration");
+      else if (TREE_CODE (*node) == ENUMERAL_TYPE)
+       pedwarn (input_location, OPT_Wattributes,
+                "%<alignas%> on enumerated type");
+      else if (TYPE_P (*node) && t != *node)
+       pedwarn (input_location, OPT_Wattributes,
+                "%<alignas%> on a type other than class");
+      else if (TREE_CODE (*node) == FIELD_DECL && DECL_C_BIT_FIELD (*node))
+       pedwarn (input_location, OPT_Wattributes, "%<alignas%> on bit-field");
+      else if (TREE_CODE (t) == TYPE_DECL)
+       pedwarn (input_location, OPT_Wattributes,
+                "%<alignas%> on a type alias");
+    }
+  return ret;
+}
+
 /* Table of valid C++ attributes.  */
 static const attribute_spec cxx_gnu_attributes[] =
 {
@@ -5162,6 +5191,18 @@ const scoped_attribute_specs std_attribute_table =
   nullptr, { std_attributes }
 };
 
+/* Table of internal attributes.  */
+static const attribute_spec internal_attributes[] =
+{
+  { "aligned", 0, 1, false, false, false, false,
+    handle_alignas_attribute, attr_aligned_exclusions }
+};
+
+const scoped_attribute_specs internal_attribute_table =
+{
+  "internal ", { internal_attributes }
+};
+
 /* Handle an "init_priority" attribute; arguments as in
    struct attribute_spec.handler.  */
 static tree
diff --git a/gcc/testsuite/g++.dg/cpp0x/alignas1.C 
b/gcc/testsuite/g++.dg/cpp0x/alignas1.C
index d73c875d6374..71380956d476 100644
--- a/gcc/testsuite/g++.dg/cpp0x/alignas1.C
+++ b/gcc/testsuite/g++.dg/cpp0x/alignas1.C
@@ -1,5 +1,6 @@
 // PR c++/65734
 // { dg-do compile { target c++11 } }
+// { dg-options "" }
 
 template <class T> struct A
 {
diff --git a/gcc/testsuite/g++.dg/cpp0x/alignas2.C 
b/gcc/testsuite/g++.dg/cpp0x/alignas2.C
index 2e7d051c886d..b359154bfd44 100644
--- a/gcc/testsuite/g++.dg/cpp0x/alignas2.C
+++ b/gcc/testsuite/g++.dg/cpp0x/alignas2.C
@@ -1,5 +1,6 @@
 // PR c++/65734
 // { dg-do compile { target c++11 } }
+// { dg-options "" }
 
 template <typename T>
 struct BVector
diff --git a/gcc/testsuite/g++.dg/cpp0x/alignas21.C 
b/gcc/testsuite/g++.dg/cpp0x/alignas21.C
new file mode 100644
index 000000000000..b7be7c5ce926
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alignas21.C
@@ -0,0 +1,156 @@
+// 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)
+{
+  alignas (int) int x1;
+  alignas ("foobar") int x2;                   // { dg-error "'alignas' 
argument has non-integral type 'const char \\\[7\\\]'" }
+  alignas (0) int x3;                          // { dg-warning "requested 
alignment '0' is not a positive power of 2" }
+  alignas ("foo", "bar", "baz") int x4;                // { dg-error 
"'alignas' argument has non-integral type 'const char \\\[4\\\]'" }
+                                               // { dg-error "expected '\\\)' 
before ',' token" "" { target *-*-* } .-1 }
+                                               // { dg-error "expected 
declaration before ',' token" "" { target *-*-* } .-2 }
+                                               // { dg-error "expected 
primary-expression before ',' token" "" { target *-*-* } .-3 }
+  alignas (0, 1, 2) int x5;                    // { dg-error "expected '\\\)' 
before ',' token" }
+                                               // { dg-error "expected 
declaration before ',' token" "" { target *-*-* } .-1 }
+                                               // { dg-error "expected 
primary-expression before ',' token" "" { target *-*-* } .-2 }
+
+  auto a = [] alignas (int) () {};             // { dg-error "'alignas' on 
function declaration" }
+  auto b = [] constexpr alignas (int) {};      // { dg-error "'alignas' on a 
type other than class" }
+                                               // { 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 alignas (int) {};       // { dg-error "'alignas' on a 
type other than class" }
+                                               // { dg-error "parameter 
declaration before lambda exception specification only optional with" "" { 
target c++20_down } .-1 }
+  auto d = [] () alignas (int) {};             // { dg-error "'alignas' on a 
type other than class" }
+  auto e = new int [n] alignas (int);          // { dg-warning "attributes 
ignored on outermost array type in new expression" }
+  auto e2 = new int [n] alignas (int) [42];    // { dg-warning "attributes 
ignored on outermost array type in new expression" }
+  auto f = new int [n][42] alignas (int);      // { dg-error "'alignas' on a 
type other than class" }
+  alignas (int);                               // { dg-warning "attributes at 
the beginning of statement are ignored" }
+  alignas (int) {}                             // { dg-warning "attributes at 
the beginning of statement are ignored" }
+  alignas (int) if (true) {}                   // { dg-warning "attributes at 
the beginning of statement are ignored" }
+  alignas (int) while (false) {}               // { dg-warning "attributes at 
the beginning of statement are ignored" }
+  alignas (int) goto lab;                      // { dg-warning "attributes at 
the beginning of statement are ignored" }
+  alignas (int) lab:;                          // { dg-error "alignment may 
not be specified for 'lab'" }
+  alignas (int) try {} catch (int) {}          // { dg-warning "attributes at 
the beginning of statement are ignored" }
+  if (alignas (int) int x = 0) {}
+  switch (n)
+    {
+    alignas (int) case 1:                      // { dg-error "alignment may 
not be specified for" }
+    alignas (int) break;                       // { dg-warning "attributes at 
the beginning of statement are ignored" }
+    alignas (int) default:                     // { dg-error "alignment may 
not be specified for" }
+        break;
+    }
+  for (alignas (int) auto a : arr) {}
+  for (alignas (int) auto [a, b] : arr2) {}    // { dg-error "structured 
bindings only available with" "" { target c++14_down } }
+  alignas (int) asm ("");                      // { dg-warning "attributes 
ignored on 'asm' declaration" }
+  try {} catch (alignas (int) int x) {}                // { dg-error 
"'alignas' on exception declaration" }
+  try {} catch (alignas (int) int) {}          // { dg-error "'alignas' on 
exception declaration" }
+  try {} catch (int alignas (int) x) {}                // { dg-warning 
"attribute ignored" }
+  try {} catch (int alignas (int)) {}          // { dg-warning "attribute 
ignored" }
+  try {} catch (int x alignas (int)) {}                // { dg-error 
"'alignas' on exception declaration" }
+}
+
+alignas (int) int bar ();                      // { dg-error "'alignas' on 
function declaration" }
+using foobar alignas (int) = int;              // { dg-error "'alignas' on a 
type alias" }
+alignas (int) int a;
+alignas (int) auto [b, c] = arr;               // { dg-error "structured 
bindings only available with" "" { target c++14_down } }
+alignas (int);                                 // { dg-warning "attribute 
ignored" }
+inline alignas (int) void baz () {}            // { dg-warning "attribute 
ignored" }
+                                               // { dg-error "standard 
attributes in middle of decl-specifiers" "" { target *-*-* } .-1 }
+constexpr alignas (int) int qux () { return 0; }       // { dg-warning 
"attribute ignored" }
+                                               // { dg-error "standard 
attributes in middle of decl-specifiers" "" { target *-*-* } .-1 }
+int alignas (int) d;                           // { dg-warning "attribute 
ignored" }
+int const alignas (int) e = 1;                 // { dg-warning "attribute 
ignored" }
+struct A {} alignas (int);                     // { dg-warning "attribute 
ignored in declaration of 'struct A'" }
+struct A alignas (int);                                // { dg-warning 
"attribute ignored" }
+struct A alignas (int) a1;                     // { dg-warning "attribute 
ignored" }
+A alignas (int) a2;                            // { dg-warning "attribute 
ignored" }
+enum B { B0 } alignas (int);                   // { dg-warning "attribute 
ignored in declaration of 'enum B'" }
+enum B alignas (int);                          // { dg-warning "attribute 
ignored" }
+enum B alignas (int) b1;                       // { dg-warning "attribute 
ignored" }
+B alignas (int) b2;                            // { dg-warning "attribute 
ignored" }
+struct alignas (int) C {};
+int f alignas (int);
+struct alignas (int) Y;
+int g[2] alignas (int);                                // { dg-error 
"'alignas' on a type other than class" }
+int g2 alignas (int) [2];
+int corge () alignas (int);                    // { dg-error "'alignas' on a 
type other than class" }
+int *alignas (int) h;                          // { dg-error "'alignas' on a 
type other than class" }
+int & alignas (int) i = f;                     // { dg-error "'alignas' on a 
type other than class" }
+int S::* alignas (int) k;                      // { dg-error "'alignas' on a 
type other than class" }
+auto l = sizeof (int [2] alignas (int));       // { dg-error "'alignas' on a 
type other than class" }
+int freddy (alignas (int) int a,               // { dg-error "alignment may 
not be specified for 'a'" }
+           alignas (int) int,                  // { dg-error "alignment may 
not be specified for '<anonymous>'" }
+           alignas (int) int c = 0,            // { dg-error "alignment may 
not be specified for 'c'" }
+           alignas (int) int = 0);             // { dg-error "alignment may 
not be specified for '<anonymous>'" }
+void
+corge (alignas (int) int a,                    // { dg-error "alignment may 
not be specified for 'a'" }
+       alignas (int) int,                      // { dg-error "alignment may 
not be specified for '<anonymous>'" }
+       alignas (int) int c = 0,                        // { dg-error 
"alignment may not be specified for 'c'" }
+       alignas (int) int = 0)                  // { dg-error "alignment may 
not be specified for '<anonymous>'" }
+{
+}
+alignas (int) void
+garply ()                                      // { dg-error "'alignas' on 
function declaration" }
+{
+}
+int grault (int alignas (int) a,               // { dg-warning "attribute 
ignored" }
+           int alignas (int),                  // { dg-warning "attribute 
ignored" }
+           int alignas (int) c = 0,            // { dg-warning "attribute 
ignored" }
+           int alignas (int) = 0);             // { dg-warning "attribute 
ignored" }
+void
+waldo (int alignas (int) a,                    // { dg-warning "attribute 
ignored" }
+       int alignas (int),                      // { dg-warning "attribute 
ignored" }
+       int alignas (int) c = 0,                        // { dg-warning 
"attribute ignored" }
+       int alignas (int) = 0)                  // { dg-warning "attribute 
ignored" }
+{
+}
+int plugh (int a alignas (int),                        // { dg-error 
"alignment may not be specified for 'a'" }
+           int b alignas (int) = 0);           // { dg-error "alignment may 
not be specified for 'b'" }
+void
+thud (int a alignas (int),                     // { dg-error "alignment may 
not be specified for 'a'" }
+      int b alignas (int) = 0)                 // { dg-error "alignment may 
not be specified for 'b'" }
+{
+}
+enum alignas (int) D { D0 };                   // { dg-error "'alignas' on 
enumerated type" }
+enum class alignas (int) E { E0 };             // { dg-error "'alignas' on 
enumerated type" }
+enum F {};
+enum alignas (int) F;                          // { dg-warning "type 
attributes ignored after type is already defined" }
+enum G {
+  G0 alignas (int),                            // { dg-error "alignment may 
not be specified for 'G0'" }
+  G1 alignas (int) = 2                         // { dg-error "alignment may 
not be specified for 'G1'" }
+};
+namespace alignas (int) H { using H0 = int; }  // { dg-error "expected 
identifier before 'alignas'" }
+                                               // { dg-error "H' does not name 
a type" "" { target *-*-* } .-1 }
+namespace alignas (int) {}                     // { dg-error "expected 
identifier before 'alignas'" }
+                                               // { dg-error "expected 
unqualified-id before '\\\{' token" "" { target *-*-* } .-1 }
+alignas (int) using namespace H;
+                                               // { dg-error "'H' is not a 
namespace-name" "" { target *-*-* } .-1 }
+struct alignas (int) I
+{
+  alignas (int);                               // { dg-error "declaration does 
not declare anything" }
+  alignas (int) int i;
+  alignas (int) int foo ();                    // { dg-error "'alignas' on 
function declaration" }
+  alignas (int) int bar () { return 1; }       // { dg-error "'alignas' on 
function declaration" }
+  alignas (int) int : 0;                       // { dg-error "'alignas' on 
bit-field" }
+  alignas (int) int i2 : 5;                    // { dg-error "'alignas' on 
bit-field" }
+  alignas (int) static int i3;
+  static int i4;
+};
+alignas (int) int I::i4 = 0;
+struct J : alignas (int) C {};                 // { dg-warning "attributes on 
base specifiers are ignored" }
+#if __cpp_concepts >= 201907L
+template <typename T>
+concept K alignas (int) = requires { true; };  // { dg-error "alignment may 
not be specified for 'K'" "" { target c++20 } }
+#endif
+typedef int L alignas (int);                   // { dg-error "'alignas' on a 
type alias" }
+template <typename T>
+struct M {};
+template <>
+struct alignas (int) M<int> { int m; };
+typedef int N[2] alignas (int);                        // { dg-error 
"'alignas' on a type other than class" }
+typedef int O alignas (int) [2];               // { dg-error "'alignas' on a 
type alias" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/alignas7.C 
b/gcc/testsuite/g++.dg/cpp0x/alignas7.C
index a209250af9b7..90cac3fe2433 100644
--- a/gcc/testsuite/g++.dg/cpp0x/alignas7.C
+++ b/gcc/testsuite/g++.dg/cpp0x/alignas7.C
@@ -1,5 +1,6 @@
 // PR c++/71513
 // { dg-do compile { target c++11 } }
+// { dg-options "" }
 
 template < int N, typename T >
 struct A
diff --git a/gcc/testsuite/g++.dg/cpp2a/is-layout-compatible3.C 
b/gcc/testsuite/g++.dg/cpp2a/is-layout-compatible3.C
index 8f48ba8679a1..499ba4977d41 100644
--- a/gcc/testsuite/g++.dg/cpp2a/is-layout-compatible3.C
+++ b/gcc/testsuite/g++.dg/cpp2a/is-layout-compatible3.C
@@ -1,5 +1,6 @@
 // P0466R5
 // { dg-do compile { target c++20 } }
+// { dg-options "-pedantic" }
 
 namespace std
 {
@@ -34,7 +35,7 @@ union N { J v; };
 union O { int a; int b; };
 union P { int a : 1; int b : 12; };
 enum Q : int { Q1, Q2 };
-enum alignas(16) R : int { R1, R2 };
+enum alignas(16) R : int { R1, R2 };           // { dg-warning "'alignas' on 
enumerated type" }
 struct U { [[no_unique_address]] S a1; [[no_unique_address]] S a2; 
[[no_unique_address]] S a3; };
 struct V { [[no_unique_address]] S b1; [[no_unique_address]] T b2; 
[[no_unique_address]] S b3; };
 struct alignas(16) A : public I {};
diff --git a/gcc/testsuite/g++.dg/ext/bitfield9.C 
b/gcc/testsuite/g++.dg/ext/bitfield9.C
index 4a4ebf23c1fb..a3b1bf18e1be 100644
--- a/gcc/testsuite/g++.dg/ext/bitfield9.C
+++ b/gcc/testsuite/g++.dg/ext/bitfield9.C
@@ -3,7 +3,7 @@
 
 struct S
 {
-  char a:4;
+  char a:4;                    // { dg-warning "alignas' on bit-field" "" { 
target *-*-* } .+1 }
   char b:8 alignas(int);       // { dg-warning "ISO C\\+\\+ allows bit-field 
attributes only before the ':' token" }
   char c:8 [[gnu::aligned(8)]];        // { dg-warning "ISO C\\+\\+ allows 
bit-field attributes only before the ':' token" }
                                // { dg-error "two consecutive '\\\[' shall 
only introduce an attribute before '\\\[' token" "" { target *-*-* } .-1 }

Reply via email to