Skip to content
1 change: 1 addition & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,7 @@ Bug Fixes in This Version
- Fixed false-positive shadow diagnostics for lambdas in explicit object member functions. (#GH163731)
- Fix an assertion failure when a ``target_clones`` attribute is only on the
forward declaration of a multiversioned function. (#GH165517) (#GH129483)
- Clang now treats enumeration constants of fixed-underlying enums as the enumerated type. (#GH172118)

Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
8 changes: 6 additions & 2 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20814,10 +20814,12 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange,
NewSign = true;
} else if (ECD->getType() == BestType) {
// Already the right type!
if (getLangOpts().CPlusPlus)
if (getLangOpts().CPlusPlus || (getLangOpts().C23 && Enum->isFixed()))
// C++ [dcl.enum]p4: Following the closing brace of an
// enum-specifier, each enumerator has the type of its
// enumeration.
// C23 6.7.2.2p15: For an enumerated type with fixed underlying type,
// the enumeration member type is the enumerated type.
ECD->setType(EnumType);
continue;
} else {
Expand All @@ -20837,10 +20839,12 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange,
ECD->setInitExpr(ImplicitCastExpr::Create(
Context, NewTy, CK_IntegralCast, ECD->getInitExpr(),
/*base paths*/ nullptr, VK_PRValue, FPOptionsOverride()));
if (getLangOpts().CPlusPlus)
if (getLangOpts().CPlusPlus || (getLangOpts().C23 && Enum->isFixed()))
// C++ [dcl.enum]p4: Following the closing brace of an
// enum-specifier, each enumerator has the type of its
// enumeration.
// C23 6.7.2.2p15: For an enumerated type with fixed underlying type, the
// enumeration member type is the enumerated type.
ECD->setType(EnumType);
else
ECD->setType(NewTy);
Expand Down
20 changes: 20 additions & 0 deletions clang/test/Sema/c23-switch.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// RUN: %clang_cc1 -std=c23 -fsyntax-only -verify -Wswitch %s

typedef enum : long { E0 } E;
void test1(E e) {
auto v = E0;
switch (v) { } // expected-warning {{enumeration value 'E0' not handled in switch}}
}

void test2(E e) {
__auto_type v = E0;
switch (v) { } // expected-warning {{enumeration value 'E0' not handled in switch}}
}

void test3(_Bool b, E e) {
__auto_type v = E0;
if (b) {
v = e;
}
switch (v) { } // expected-warning {{enumeration value 'E0' not handled in switch}}
}
6 changes: 3 additions & 3 deletions clang/test/SemaCXX/bitfield-preferred-type-sizing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -377,9 +377,9 @@ void write_high_constantA(S_A *s) {
void write_high_constantB(S_B *s) {
s->field1 = ENUM_CLASS_REF(B, B_d);
// cpp-warning@-1 {{implicit truncation from 'B' to bit-field changes value from 3 to 1}}
// c-warning@-2 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}
// c-warning@-2 {{implicit truncation from 'enum B' to bit-field changes value from 3 to -1}}
s->field2 = ENUM_CLASS_REF(B, B_d);
// c-warning@-1 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}
// c-warning@-1 {{implicit truncation from 'enum B' to bit-field changes value from 3 to -1}}
s->field3 = ENUM_CLASS_REF(B, B_d);
s->field4 = (unsigned)ENUM_CLASS_REF(B, B_d);
// expected-warning@-1 {{implicit truncation from 'unsigned int' to bit-field changes value from 3 to 1}}
Expand All @@ -396,7 +396,7 @@ void write_high_constantB(S_B *s) {
void write_high_constantC(S_C *s) {
s->field1 = ENUM_CLASS_REF(C, C_d);
// cpp-warning@-1 {{implicit truncation from 'C' to bit-field changes value from 3 to 1}}
// c-warning@-2 {{implicit truncation from 'unsigned int' to bit-field changes value from 3 to 1}}
// c-warning@-2 {{implicit truncation from 'enum C' to bit-field changes value from 3 to 1}}
s->field2 = ENUM_CLASS_REF(C, C_d);
s->field3 = ENUM_CLASS_REF(C, C_d);
s->field4 = (unsigned)ENUM_CLASS_REF(C, C_d);
Expand Down