Skip to content

Commit 5175cd7

Browse files
committed
Disallow _BitInt as an underlying type for an enumeration
As mentioned in #69619, C23 6.7.2.2p5 explicitly prohibits using a _BitInt as an underlying type to an enumeration. While we had this in the _ExtInt implementation, the justification for that limitation in C is compelling, so this is being removed to be compatible with the C23 standard. Fixes: #69619
1 parent 67770cb commit 5175cd7

File tree

6 files changed

+8
-44
lines changed

6 files changed

+8
-44
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,9 @@ Bug Fixes in This Version
409409
operator in C. No longer issuing a confusing diagnostic along the lines of
410410
"incompatible operand types ('foo' and 'foo')" with extensions such as matrix
411411
types. Fixes (`#69008 <https://github.com/llvm/llvm-project/issues/69008>`_)
412+
- Clang no longer permits using the `_BitInt` types as an underlying type for an
413+
enumeration as specified in the C23 Standard.
414+
Fixes (`#69619 <https://github.com/llvm/llvm-project/issues/69619>`_)
412415

413416
Bug Fixes to Compiler Builtins
414417
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2613,7 +2613,7 @@ def err_final_function_overridden : Error<
26132613

26142614
// C++11 scoped enumerations
26152615
def err_enum_invalid_underlying : Error<
2616-
"non-integral type %0 is an invalid underlying type">;
2616+
"%select{non-integral type %0|%0}1 is an invalid underlying type">;
26172617
def err_enumerator_too_large : Error<
26182618
"enumerator value is not representable in the underlying type %0">;
26192619
def ext_enumerator_too_large : Extension<

clang/lib/Sema/SemaDecl.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16722,10 +16722,8 @@ bool Sema::CheckEnumUnderlyingType(TypeSourceInfo *TI) {
1672216722
if (BT->isInteger())
1672316723
return false;
1672416724

16725-
if (T->isBitIntType())
16726-
return false;
16727-
16728-
return Diag(UnderlyingLoc, diag::err_enum_invalid_underlying) << T;
16725+
return Diag(UnderlyingLoc, diag::err_enum_invalid_underlying)
16726+
<< T << T->isBitIntType();
1672916727
}
1673016728

1673116729
/// Check whether this is a valid redeclaration of a previous enumeration.

clang/test/CodeGenCXX/ext-int.cpp

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -98,19 +98,6 @@ void BitfieldAssignment() {
9898
// CHECK: %[[SETC:.+]] = or i8 %[[CLEARC]], 64
9999
}
100100

101-
enum AsEnumUnderlyingType : _BitInt(9) {
102-
A,B,C
103-
};
104-
105-
void UnderlyingTypeUsage(AsEnumUnderlyingType Param) {
106-
// LIN: define{{.*}} void @_Z19UnderlyingTypeUsage20AsEnumUnderlyingType(i9 signext %
107-
// WIN64: define dso_local void @"?UnderlyingTypeUsage@@YAXW4AsEnumUnderlyingType@@@Z"(i9 %
108-
// WIN32: define dso_local void @"?UnderlyingTypeUsage@@YAXW4AsEnumUnderlyingType@@@Z"(i9 signext %
109-
AsEnumUnderlyingType Var;
110-
// CHECK: alloca i9, align 2
111-
// CHECK: store i9 %{{.*}}, align 2
112-
}
113-
114101
unsigned _BitInt(33) ManglingTestRetParam(unsigned _BitInt(33) Param) {
115102
// LIN64: define{{.*}} i64 @_Z20ManglingTestRetParamDU33_(i64 %
116103
// LIN32: define{{.*}} i33 @_Z20ManglingTestRetParamDU33_(i33 %

clang/test/SemaCXX/ext-int.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,8 @@ void ConstexprBitsize() {
211211
static_assert(is_same<decltype(F), _BitInt(42)>::value, "");
212212
}
213213

214-
// Useable as an underlying type.
215-
enum AsEnumUnderlyingType : _BitInt(33) {
214+
// Not useable as an underlying type.
215+
enum AsEnumUnderlyingType : _BitInt(33) { // expected-error{{'_BitInt(33)' is an invalid underlying type}}
216216
};
217217

218218
void overloaded(int);

clang/test/SemaCXX/type-traits.cpp

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4002,12 +4002,6 @@ enum class UnscopedInt128 : __int128 {};
40024002
enum class ScopedInt128 : __int128 {};
40034003
enum class UnscopedUInt128 : unsigned __int128 {};
40044004
enum class ScopedUInt128 : unsigned __int128 {};
4005-
enum UnscopedBit : unsigned _BitInt(1) {};
4006-
enum ScopedBit : unsigned _BitInt(1) {};
4007-
enum UnscopedIrregular : _BitInt(21) {};
4008-
enum UnscopedUIrregular : unsigned _BitInt(21) {};
4009-
enum class ScopedIrregular : _BitInt(21) {};
4010-
enum class ScopedUIrregular : unsigned _BitInt(21) {};
40114005

40124006
void make_signed() {
40134007
check_make_signed<char, signed char>();
@@ -4050,11 +4044,6 @@ void make_signed() {
40504044
check_make_signed<UnscopedUInt128, __int128>();
40514045
check_make_signed<ScopedUInt128, __int128>();
40524046

4053-
check_make_signed<UnscopedIrregular, _BitInt(21)>();
4054-
check_make_signed<UnscopedUIrregular, _BitInt(21)>();
4055-
check_make_signed<ScopedIrregular, _BitInt(21)>();
4056-
check_make_signed<ScopedUIrregular, _BitInt(21)>();
4057-
40584047
{ using ExpectedError = __make_signed(bool); }
40594048
// expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'bool'}}
40604049
{ using ExpectedError = __make_signed(UnscopedBool); }
@@ -4063,10 +4052,6 @@ void make_signed() {
40634052
// expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'ScopedBool' whose underlying type is 'bool'}}
40644053
{ using ExpectedError = __make_signed(unsigned _BitInt(1)); }
40654054
// expected-error@*:*{{'make_signed' is only compatible with non-_BitInt(1) integers and enum types, but was given 'unsigned _BitInt(1)'}}
4066-
{ using ExpectedError = __make_signed(UnscopedBit); }
4067-
// expected-error@*:*{{'make_signed' is only compatible with non-_BitInt(1) integers and enum types, but was given 'UnscopedBit' whose underlying type is 'unsigned _BitInt(1)'}}
4068-
{ using ExpectedError = __make_signed(ScopedBit); }
4069-
// expected-error@*:*{{'make_signed' is only compatible with non-_BitInt(1) integers and enum types, but was given 'ScopedBit' whose underlying type is 'unsigned _BitInt(1)'}}
40704055
{ using ExpectedError = __make_signed(int[]); }
40714056
// expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'int[]'}}
40724057
{ using ExpectedError = __make_signed(int[5]); }
@@ -4147,11 +4132,6 @@ void make_unsigned() {
41474132
check_make_unsigned<UnscopedUInt128, unsigned __int128>();
41484133
check_make_unsigned<ScopedUInt128, unsigned __int128>();
41494134

4150-
check_make_unsigned<UnscopedIrregular, unsigned _BitInt(21)>();
4151-
check_make_unsigned<UnscopedUIrregular, unsigned _BitInt(21)>();
4152-
check_make_unsigned<ScopedIrregular, unsigned _BitInt(21)>();
4153-
check_make_unsigned<ScopedUIrregular, unsigned _BitInt(21)>();
4154-
41554135
{ using ExpectedError = __make_unsigned(bool); }
41564136
// expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'bool'}}
41574137
{ using ExpectedError = __make_unsigned(UnscopedBool); }
@@ -4160,10 +4140,6 @@ void make_unsigned() {
41604140
// expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'ScopedBool' whose underlying type is 'bool'}}
41614141
{ using ExpectedError = __make_unsigned(unsigned _BitInt(1)); }
41624142
// expected-error@*:*{{'make_unsigned' is only compatible with non-_BitInt(1) integers and enum types, but was given 'unsigned _BitInt(1)'}}
4163-
{ using ExpectedError = __make_unsigned(UnscopedBit); }
4164-
// expected-error@*:*{{'make_unsigned' is only compatible with non-_BitInt(1) integers and enum types, but was given 'UnscopedBit'}}
4165-
{ using ExpectedError = __make_unsigned(ScopedBit); }
4166-
// expected-error@*:*{{'make_unsigned' is only compatible with non-_BitInt(1) integers and enum types, but was given 'ScopedBit'}}
41674143
{ using ExpectedError = __make_unsigned(int[]); }
41684144
// expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'int[]'}}
41694145
{ using ExpectedError = __make_unsigned(int[5]); }

0 commit comments

Comments
 (0)