Skip to content

Commit a603f56

Browse files
EndilllChuanqiXu9
authored andcommitted
[clang] CWG 2354: prohibit alignas for enums
Reviewed By: aaron.ballman, erichkeane Differential Revision: https://reviews.llvm.org/D121723
1 parent 989f1c7 commit a603f56

File tree

6 files changed

+20
-43
lines changed

6 files changed

+20
-43
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3022,8 +3022,9 @@ def err_aligned_attribute_argument_not_int : Error<
30223022
def err_align_value_attribute_argument_not_int : Error<
30233023
"'align_value' attribute requires integer constant">;
30243024
def err_alignas_attribute_wrong_decl_type : Error<
3025-
"%0 attribute cannot be applied to a %select{function parameter|"
3026-
"variable with 'register' storage class|'catch' variable|bit-field}1">;
3025+
"%0 attribute cannot be applied to %select{a function parameter|"
3026+
"a variable with 'register' storage class|a 'catch' variable|a bit-field|"
3027+
"an enumeration}1">;
30273028
def err_alignas_missing_on_definition : Error<
30283029
"%0 must be specified on definition if it is specified on any declaration">;
30293030
def note_alignas_on_declaration : Note<"declared with %0 attribute here">;

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4290,6 +4290,9 @@ void Sema::AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
42904290
// declared with the register storage class specifier. An
42914291
// alignment-specifier may also be applied to the declaration of a class
42924292
// or enumeration type.
4293+
// CWG 2354:
4294+
// CWG agreed to remove permission for alignas to be applied to
4295+
// enumerations.
42934296
// C11 6.7.5/2:
42944297
// An alignment attribute shall not be specified in a declaration of
42954298
// a typedef, or a bit-field, or a function, or a parameter, or an
@@ -4305,6 +4308,9 @@ void Sema::AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
43054308
} else if (const auto *FD = dyn_cast<FieldDecl>(D)) {
43064309
if (FD->isBitField())
43074310
DiagKind = 3;
4311+
} else if (const auto *ED = dyn_cast<EnumDecl>(D)) {
4312+
if (ED->getLangOpts().CPlusPlus)
4313+
DiagKind = 4;
43084314
} else if (!isa<TagDecl>(D)) {
43094315
Diag(AttrLoc, diag::err_attribute_wrong_decl_type) << &TmpAttr
43104316
<< (TmpAttr.isC11() ? ExpectedVariableOrField

clang/test/CXX/dcl.dcl/dcl.attr/dcl.align/p5.cpp

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,6 @@ alignas(1) int n7 alignas(2), // expected-error {{less than minimum alignment}}
1111
alignas(8) int n9 alignas(2); // ok, overaligned
1212
alignas(1) extern int n10; // expected-error {{less than minimum alignment}}
1313

14-
enum alignas(1) E1 {}; // expected-error {{requested alignment is less than minimum alignment of 4 for type 'E1'}}
15-
enum alignas(1) E2 : char {}; // ok
16-
enum alignas(4) E3 { e3 = 0 }; // ok
17-
enum alignas(4) E4 { e4 = 1ull << 33 }; // expected-error {{requested alignment is less than minimum alignment of 8 for type 'E4'}}
18-
enum alignas(8) E5 {};
19-
static_assert(alignof(E5) == 8, "");
20-
2114
typedef __attribute__((aligned(16))) int IntAlign16;
2215
enum E6 : IntAlign16 {};
2316
static_assert(alignof(E6) == 4, "");
@@ -62,15 +55,6 @@ template struct X<2, 2, short>;
6255
template struct X<16, 8, S1>;
6356
template struct X<4, 4, S1>; // expected-note {{instantiation}}
6457

65-
template<int N, typename T>
66-
struct Y {
67-
enum alignas(N) E : T {}; // expected-error {{requested alignment is less than minimum}}
68-
};
69-
template struct Y<1, char>;
70-
template struct Y<2, char>;
71-
template struct Y<1, short>; // expected-note {{instantiation}}
72-
template struct Y<2, short>;
73-
7458
template<int N, typename T>
7559
void f() {
7660
alignas(N) T v; // expected-error {{requested alignment is less than minimum}}

clang/test/CXX/dcl.dcl/dcl.attr/dcl.align/p6.cpp

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,6 @@ int n8; // expected-error {{'alignas' must be specified on definition if it is s
2727
int n9; // expected-error {{'alignas' must be specified on definition if it is specified on any declaration}}
2828
alignas(4) extern int n9; // expected-note {{declared with 'alignas' attribute here}}
2929

30-
31-
enum alignas(2) E : char; // expected-note {{declared with 'alignas' attribute here}}
32-
enum E : char {}; // expected-error {{'alignas' must be specified on definition if it is specified on any declaration}}
33-
34-
enum alignas(4) F : char; // expected-note {{previous declaration is here}}
35-
enum alignas(2) F : char; // expected-error {{redeclaration has different alignment requirement (2 vs 4)}}
36-
37-
enum G : char;
38-
enum alignas(8) G : char {};
39-
enum G : char;
40-
41-
enum H : char {}; // expected-error {{'alignas' must be specified on definition if it is specified on any declaration}}
42-
enum alignas(1) H : char; // expected-note {{declared with 'alignas' attribute here}}
43-
44-
4530
struct S;
4631
struct alignas(16) S; // expected-note {{declared with 'alignas' attribute here}}
4732
struct S;
@@ -73,14 +58,5 @@ alignas(O) alignas(P) char X<M, N, O, P>::Buffer[32]; // expected-error {{redecl
7358
char *x1848 = X<1,8,4,8>::Buffer; // ok
7459
char *x1248 = X<1,2,4,8>::Buffer; // expected-note {{in instantiation of}}
7560

76-
template<int M, int N, int O, int P> struct Y {
77-
enum alignas(M) alignas(N) E : char;
78-
};
79-
template<int M, int N, int O, int P>
80-
enum alignas(O) alignas(P) Y<M,N,O,P>::E : char { e };
81-
int y1848 = Y<1,8,4,8>::e;
82-
// FIXME: We should reject this.
83-
int y1248 = Y<1,2,4,8>::e;
84-
8561
// Don't crash here.
8662
alignas(4) struct Incomplete incomplete; // expected-error {{incomplete type}} expected-note {{forward declaration}}

clang/test/CXX/drs/dr2354.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %clang_cc1 -x c++ -verify %s
2+
3+
// dr2354: 15
4+
5+
namespace DR2354 {
6+
7+
enum alignas(64) A {}; // expected-error {{'alignas' attribute cannot be applied to an enumeration}}
8+
enum struct alignas(64) B {}; // expected-error {{'alignas' attribute cannot be applied to an enumeration}}
9+
10+
} // namespace DR2354

clang/www/cxx_dr_status.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13938,7 +13938,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
1393813938
<td><a href="https://wg21.link/cwg2354">2354</a></td>
1393913939
<td>CD5</td>
1394013940
<td>Extended alignment and object representation</td>
13941-
<td class="none" align="center">Unknown</td>
13941+
<td class="unreleased" align="center">Clang 15</td>
1394213942
</tr>
1394313943
<tr class="open" id="2355">
1394413944
<td><a href="https://wg21.link/cwg2355">2355</a></td>

0 commit comments

Comments
 (0)