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 <jakub@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.
This commit is contained in:
parent
190d9a2b38
commit
7eb2acb722
13 changed files with 223 additions and 8 deletions
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// PR c++/65734
|
||||
// { dg-do compile { target c++11 } }
|
||||
// { dg-options "" }
|
||||
|
||||
template <class T> struct A
|
||||
{
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// PR c++/65734
|
||||
// { dg-do compile { target c++11 } }
|
||||
// { dg-options "" }
|
||||
|
||||
template <typename T>
|
||||
struct BVector
|
||||
|
|
156
gcc/testsuite/g++.dg/cpp0x/alignas21.C
Normal file
156
gcc/testsuite/g++.dg/cpp0x/alignas21.C
Normal file
|
@ -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" }
|
|
@ -1,5 +1,6 @@
|
|||
// PR c++/71513
|
||||
// { dg-do compile { target c++11 } }
|
||||
// { dg-options "" }
|
||||
|
||||
template < int N, typename T >
|
||||
struct A
|
||||
|
|
|
@ -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 {};
|
||||
|
|
|
@ -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 }
|
||||
|
|
Loading…
Add table
Reference in a new issue