diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index eee48431d7168..fc8caf9221b9d 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -409,6 +409,9 @@ Bug Fixes in This Version operator in C. No longer issuing a confusing diagnostic along the lines of "incompatible operand types ('foo' and 'foo')" with extensions such as matrix types. Fixes (`#69008 `_) +- Clang no longer permits using the `_BitInt` types as an underlying type for an + enumeration as specified in the C23 Standard. + Fixes (`#69619 `_) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index a6b21f0af1c06..6b499d112b79f 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2613,7 +2613,7 @@ def err_final_function_overridden : Error< // C++11 scoped enumerations def err_enum_invalid_underlying : Error< - "non-integral type %0 is an invalid underlying type">; + "%select{non-integral type %0|%0}1 is an invalid underlying type">; def err_enumerator_too_large : Error< "enumerator value is not representable in the underlying type %0">; def ext_enumerator_too_large : Extension< diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index e3387b5b669c6..b363b0db79f16 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -16722,10 +16722,8 @@ bool Sema::CheckEnumUnderlyingType(TypeSourceInfo *TI) { if (BT->isInteger()) return false; - if (T->isBitIntType()) - return false; - - return Diag(UnderlyingLoc, diag::err_enum_invalid_underlying) << T; + return Diag(UnderlyingLoc, diag::err_enum_invalid_underlying) + << T << T->isBitIntType(); } /// Check whether this is a valid redeclaration of a previous enumeration. diff --git a/clang/test/CodeGenCXX/ext-int.cpp b/clang/test/CodeGenCXX/ext-int.cpp index 7676dec791f3f..5a4270aef2854 100644 --- a/clang/test/CodeGenCXX/ext-int.cpp +++ b/clang/test/CodeGenCXX/ext-int.cpp @@ -98,19 +98,6 @@ void BitfieldAssignment() { // CHECK: %[[SETC:.+]] = or i8 %[[CLEARC]], 64 } -enum AsEnumUnderlyingType : _BitInt(9) { - A,B,C -}; - -void UnderlyingTypeUsage(AsEnumUnderlyingType Param) { - // LIN: define{{.*}} void @_Z19UnderlyingTypeUsage20AsEnumUnderlyingType(i9 signext % - // WIN64: define dso_local void @"?UnderlyingTypeUsage@@YAXW4AsEnumUnderlyingType@@@Z"(i9 % - // WIN32: define dso_local void @"?UnderlyingTypeUsage@@YAXW4AsEnumUnderlyingType@@@Z"(i9 signext % - AsEnumUnderlyingType Var; - // CHECK: alloca i9, align 2 - // CHECK: store i9 %{{.*}}, align 2 -} - unsigned _BitInt(33) ManglingTestRetParam(unsigned _BitInt(33) Param) { // LIN64: define{{.*}} i64 @_Z20ManglingTestRetParamDU33_(i64 % // LIN32: define{{.*}} i33 @_Z20ManglingTestRetParamDU33_(i33 % diff --git a/clang/test/SemaCXX/ext-int.cpp b/clang/test/SemaCXX/ext-int.cpp index 4dd7cd3b7b2b6..000b871ccd343 100644 --- a/clang/test/SemaCXX/ext-int.cpp +++ b/clang/test/SemaCXX/ext-int.cpp @@ -211,8 +211,8 @@ void ConstexprBitsize() { static_assert(is_same::value, ""); } -// Useable as an underlying type. -enum AsEnumUnderlyingType : _BitInt(33) { +// Not useable as an underlying type. +enum AsEnumUnderlyingType : _BitInt(33) { // expected-error{{'_BitInt(33)' is an invalid underlying type}} }; void overloaded(int); diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp index 275ddcbae7393..c5d196a2590f8 100644 --- a/clang/test/SemaCXX/type-traits.cpp +++ b/clang/test/SemaCXX/type-traits.cpp @@ -4002,12 +4002,6 @@ enum class UnscopedInt128 : __int128 {}; enum class ScopedInt128 : __int128 {}; enum class UnscopedUInt128 : unsigned __int128 {}; enum class ScopedUInt128 : unsigned __int128 {}; -enum UnscopedBit : unsigned _BitInt(1) {}; -enum ScopedBit : unsigned _BitInt(1) {}; -enum UnscopedIrregular : _BitInt(21) {}; -enum UnscopedUIrregular : unsigned _BitInt(21) {}; -enum class ScopedIrregular : _BitInt(21) {}; -enum class ScopedUIrregular : unsigned _BitInt(21) {}; void make_signed() { check_make_signed(); @@ -4050,11 +4044,6 @@ void make_signed() { check_make_signed(); check_make_signed(); - check_make_signed(); - check_make_signed(); - check_make_signed(); - check_make_signed(); - { using ExpectedError = __make_signed(bool); } // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'bool'}} { using ExpectedError = __make_signed(UnscopedBool); } @@ -4063,10 +4052,6 @@ void make_signed() { // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'ScopedBool' whose underlying type is 'bool'}} { using ExpectedError = __make_signed(unsigned _BitInt(1)); } // expected-error@*:*{{'make_signed' is only compatible with non-_BitInt(1) integers and enum types, but was given 'unsigned _BitInt(1)'}} - { using ExpectedError = __make_signed(UnscopedBit); } - // 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)'}} - { using ExpectedError = __make_signed(ScopedBit); } - // 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)'}} { using ExpectedError = __make_signed(int[]); } // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'int[]'}} { using ExpectedError = __make_signed(int[5]); } @@ -4147,11 +4132,6 @@ void make_unsigned() { check_make_unsigned(); check_make_unsigned(); - check_make_unsigned(); - check_make_unsigned(); - check_make_unsigned(); - check_make_unsigned(); - { using ExpectedError = __make_unsigned(bool); } // expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'bool'}} { using ExpectedError = __make_unsigned(UnscopedBool); } @@ -4160,10 +4140,6 @@ void make_unsigned() { // expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'ScopedBool' whose underlying type is 'bool'}} { using ExpectedError = __make_unsigned(unsigned _BitInt(1)); } // expected-error@*:*{{'make_unsigned' is only compatible with non-_BitInt(1) integers and enum types, but was given 'unsigned _BitInt(1)'}} - { using ExpectedError = __make_unsigned(UnscopedBit); } - // expected-error@*:*{{'make_unsigned' is only compatible with non-_BitInt(1) integers and enum types, but was given 'UnscopedBit'}} - { using ExpectedError = __make_unsigned(ScopedBit); } - // expected-error@*:*{{'make_unsigned' is only compatible with non-_BitInt(1) integers and enum types, but was given 'ScopedBit'}} { using ExpectedError = __make_unsigned(int[]); } // expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'int[]'}} { using ExpectedError = __make_unsigned(int[5]); }