Commit 5175cd77 authored by erichkeane's avatar erichkeane
Browse files

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
parent 67770cbb
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+1 −1
Original line number Diff line number Diff line
@@ -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<
+2 −4
Original line number Diff line number Diff line
@@ -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.
+0 −13
Original line number Diff line number Diff line
@@ -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 %
+2 −2
Original line number Diff line number Diff line
@@ -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);
Loading