[clang] 5175cd7 - Disallow _BitInt as an underlying type for an enumeration

via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 19 11:02:34 PDT 2023


Author: erichkeane
Date: 2023-10-19T11:02:29-07:00
New Revision: 5175cd777c57190ab9860c304796d386e4df9b8f

URL: https://github.com/llvm/llvm-project/commit/5175cd777c57190ab9860c304796d386e4df9b8f
DIFF: https://github.com/llvm/llvm-project/commit/5175cd777c57190ab9860c304796d386e4df9b8f.diff

LOG: 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

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/Sema/SemaDecl.cpp
    clang/test/CodeGenCXX/ext-int.cpp
    clang/test/SemaCXX/ext-int.cpp
    clang/test/SemaCXX/type-traits.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index eee48431d716878..fc8caf9221b9d29 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 <https://github.com/llvm/llvm-project/issues/69008>`_)
+- Clang no longer permits using the `_BitInt` types as an underlying type for an
+  enumeration as specified in the C23 Standard.
+  Fixes (`#69619 <https://github.com/llvm/llvm-project/issues/69619>`_)
 
 Bug Fixes to Compiler Builtins
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index a6b21f0af1c0642..6b499d112b79f48 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 e3387b5b669c603..b363b0db79f164d 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 7676dec791f3f62..5a4270aef28542e 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 4dd7cd3b7b2b6e2..000b871ccd3433a 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<decltype(F), _BitInt(42)>::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 275ddcbae73930d..c5d196a2590f8d7 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<char, signed char>();
@@ -4050,11 +4044,6 @@ void make_signed() {
   check_make_signed<UnscopedUInt128, __int128>();
   check_make_signed<ScopedUInt128, __int128>();
 
-  check_make_signed<UnscopedIrregular, _BitInt(21)>();
-  check_make_signed<UnscopedUIrregular, _BitInt(21)>();
-  check_make_signed<ScopedIrregular, _BitInt(21)>();
-  check_make_signed<ScopedUIrregular, _BitInt(21)>();
-
   { 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<UnscopedUInt128, unsigned __int128>();
   check_make_unsigned<ScopedUInt128, unsigned __int128>();
 
-  check_make_unsigned<UnscopedIrregular, unsigned _BitInt(21)>();
-  check_make_unsigned<UnscopedUIrregular, unsigned _BitInt(21)>();
-  check_make_unsigned<ScopedIrregular, unsigned _BitInt(21)>();
-  check_make_unsigned<ScopedUIrregular, unsigned _BitInt(21)>();
-
   { 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]); }


        


More information about the cfe-commits mailing list