[Clang] treat fixed-underlying enum constants as the enumerated type in C23 to follow the spec#172211
Merged
a-tarasyuk merged 17 commits intollvm:mainfrom Jan 6, 2026
Merged
[Clang] treat fixed-underlying enum constants as the enumerated type in C23 to follow the spec#172211a-tarasyuk merged 17 commits intollvm:mainfrom
a-tarasyuk merged 17 commits intollvm:mainfrom
Conversation
…in C23 to follow the spec
Member
|
@llvm/pr-subscribers-clang Author: Oleksandr T. (a-tarasyuk) ChangesFixes #172118 This patch resolves an issue where C23 fixed-underlying enum constants were incorrectly treated as the underlying integer type instead of the enumeration type. According to C23 > The enumeration member type of an enumerated type with a fixed underlying type is the same as the type itself. Full diff: https://github.com/llvm/llvm-project/pull/172211.diff 4 Files Affected:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index feaf92ad4415f..66ec693e69826 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -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
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index db711ee08c8da..7dbce349d48af 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -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 {
@@ -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);
diff --git a/clang/test/Sema/c23-switch.c b/clang/test/Sema/c23-switch.c
new file mode 100644
index 0000000000000..32be0bb8e6a48
--- /dev/null
+++ b/clang/test/Sema/c23-switch.c
@@ -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}}
+}
diff --git a/clang/test/SemaCXX/bitfield-preferred-type-sizing.cpp b/clang/test/SemaCXX/bitfield-preferred-type-sizing.cpp
index 5eaa3eb2d85e3..71367cfc7ec4d 100644
--- a/clang/test/SemaCXX/bitfield-preferred-type-sizing.cpp
+++ b/clang/test/SemaCXX/bitfield-preferred-type-sizing.cpp
@@ -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}}
@@ -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);
|
🪟 Windows x64 Test Results
✅ The build succeeded and all tests passed. |
Member
Author
|
@Fznamznon, thank you for your feedback. I have added more tests based on the issue you pointed out. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #172118
This patch resolves an issue where C23 fixed-underlying enum constants were incorrectly treated as the underlying integer type instead of the enumeration type.
According to C23
6.7.2.2p15: