https://github.com/flash1729 updated https://github.com/llvm/llvm-project/pull/220573
>From 62fe00fbb9fbb5a7f51efd7f6b9cf4db4326967d Mon Sep 17 00:00:00 2001 From: flash1729 <[email protected]> Date: Mon, 17 Aug 2026 06:22:56 +0530 Subject: [PATCH 1/3] [clang][Sema] Check conditional branches inside a comma operand A conditional operator appearing as the right operand of a comma operator was converted to the context type as a whole. In C the type of a conditional between two enumerators is int, so returning '(void)0, c ? E1_One : E1_Zero' from a function returning that enumeration was reported as an int to enum conversion, even though the same code is valid in C++. Recurse into the conditional so each branch is checked against the context type, matching what CheckConditionalOperand already does outside of a comma operator. A branch that genuinely needs the conversion is still diagnosed. Fixes #185400 --- clang/docs/ReleaseNotes.md | 5 +++++ clang/lib/Sema/SemaChecking.cpp | 10 ++++++++++ clang/test/Sema/implicit-int-enum-conversion.c | 12 ++++++++++++ 3 files changed, 27 insertions(+) diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index b11e1d28a8b8f..6ba63470ecd1b 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -474,6 +474,11 @@ features cannot lower the translation-unit ABI level; dimension that is a zero integer constant, as in `struct Empty vla[n]` or `int vla[n][0]`. (#GH28328) +- `-Wimplicit-int-enum-cast` no longer warns about a conditional operator used + as the right operand of a comma operator when each branch of the conditional + is already of the target enumeration type. The branches are now checked + individually, as they are outside of a comma operator. (#GH185400) + ### Improvements to Clang's time-trace ### Improvements to Coverage Mapping diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index f0a1a529841b2..f6f29c1bfaae3 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -14042,6 +14042,16 @@ static void CheckCommaOperand( bool ExtraCheckForImplicitConversion, llvm::SmallVectorImpl<AnalyzeImplicitConversionsWorkItem> &WorkList) { E = E->IgnoreParenImpCasts(); + + // A conditional operand is fed into the context type branch by branch, the + // same way CheckConditionalOperand does, so that a conditional whose + // branches each convert cleanly is not reported through the type of the + // conditional as a whole. CheckConditionalOperator analyzes the + // subexpressions itself, so do not add this one to the work list. + if (ExtraCheckForImplicitConversion && E->getType() != T) + if (auto *CO = dyn_cast<AbstractConditionalOperator>(E)) + return CheckConditionalOperator(S, CO, CC, T); + WorkList.push_back({E, CC, false}); if (ExtraCheckForImplicitConversion && E->getType() != T) diff --git a/clang/test/Sema/implicit-int-enum-conversion.c b/clang/test/Sema/implicit-int-enum-conversion.c index 36717f36dd083..d452f326ba4ea 100644 --- a/clang/test/Sema/implicit-int-enum-conversion.c +++ b/clang/test/Sema/implicit-int-enum-conversion.c @@ -72,3 +72,15 @@ enum E1 comma4(void) { return ((void)1, 2); // expected-warning {{implicit conversion from 'int' to enumeration type 'enum E1' is invalid in C++}} \ cxx-error {{cannot initialize return object of type 'enum E1' with an rvalue of type 'int'}} } + +// The branches of a conditional operand are each converted to the context +// type, so a conditional between enumerators of the target type is fine in +// C++ and must not be diagnosed here either. +enum E1 comma5(int c) { + return ((void)0, c ? E1_One : E1_Zero); +} + +enum E1 comma6(int c) { + return ((void)0, c ? E1_One : 2); // expected-warning {{implicit conversion from 'int' to enumeration type 'enum E1' is invalid in C++}} \ + cxx-error {{cannot initialize return object of type 'enum E1' with an rvalue of type 'int'}} +} >From 4509c5d643671de3bceab481593f9dc9554a0bfa Mon Sep 17 00:00:00 2001 From: flash1729 <[email protected]> Date: Fri, 4 Sep 2026 22:46:23 +0530 Subject: [PATCH 2/3] Make the C++ expectation for a conditional comma operand explicit --- clang/test/Sema/implicit-int-enum-conversion.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/clang/test/Sema/implicit-int-enum-conversion.c b/clang/test/Sema/implicit-int-enum-conversion.c index d452f326ba4ea..eb5948e74d3b8 100644 --- a/clang/test/Sema/implicit-int-enum-conversion.c +++ b/clang/test/Sema/implicit-int-enum-conversion.c @@ -77,9 +77,15 @@ enum E1 comma4(void) { // type, so a conditional between enumerators of the target type is fine in // C++ and must not be diagnosed here either. enum E1 comma5(int c) { - return ((void)0, c ? E1_One : E1_Zero); + return ((void)0, c ? E1_One : E1_Zero); // Okay, no conversion in C++ } +#ifdef __cplusplus +// In C++ the enumerators already have the enumeration type, so the conditional +// has type E1 and there is nothing to convert. +static_assert(__is_same(decltype(true ? E1_One : E1_Zero), E1), ""); +#endif + enum E1 comma6(int c) { return ((void)0, c ? E1_One : 2); // expected-warning {{implicit conversion from 'int' to enumeration type 'enum E1' is invalid in C++}} \ cxx-error {{cannot initialize return object of type 'enum E1' with an rvalue of type 'int'}} >From 4d557d90006c15a96256cd43b84abc404eae3000 Mon Sep 17 00:00:00 2001 From: flash1729 <[email protected]> Date: Sat, 5 Sep 2026 01:28:06 +0530 Subject: [PATCH 3/3] Drop the redundant C++ static_assert; comma5 compiling as C++ already covers it --- clang/test/Sema/implicit-int-enum-conversion.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/clang/test/Sema/implicit-int-enum-conversion.c b/clang/test/Sema/implicit-int-enum-conversion.c index eb5948e74d3b8..ab9ffc23f0c57 100644 --- a/clang/test/Sema/implicit-int-enum-conversion.c +++ b/clang/test/Sema/implicit-int-enum-conversion.c @@ -80,12 +80,6 @@ enum E1 comma5(int c) { return ((void)0, c ? E1_One : E1_Zero); // Okay, no conversion in C++ } -#ifdef __cplusplus -// In C++ the enumerators already have the enumeration type, so the conditional -// has type E1 and there is nothing to convert. -static_assert(__is_same(decltype(true ? E1_One : E1_Zero), E1), ""); -#endif - enum E1 comma6(int c) { return ((void)0, c ? E1_One : 2); // expected-warning {{implicit conversion from 'int' to enumeration type 'enum E1' is invalid in C++}} \ cxx-error {{cannot initialize return object of type 'enum E1' with an rvalue of type 'int'}} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
