https://github.com/flash1729 created 
https://github.com/llvm/llvm-project/pull/220573

In C, a conditional between two enumerators has type int, so returning
`(side(), c ? A : B)` from a function returning that enum made
`-Wimplicit-int-enum-cast` claim the code is invalid in C++, even though
compiling it as C++ accepts it. The comma path converted the whole
conditional to the context type, while `CheckConditionalOperand` already
checks conditionals branch by branch.

Give `CheckCommaOperand` the same behavior: recurse into a conditional
right operand so each branch is checked individually. A branch that
genuinely needs the conversion still warns.

Fixes #185400

>From 317a5819bd05fb8293826cf195860009d343beae Mon Sep 17 00:00:00 2001
From: flash1729 <[email protected]>
Date: Mon, 17 Aug 2026 06:22:56 +0530
Subject: [PATCH] [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 a616bd41f3560..a1492d41b3d1a 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -438,6 +438,11 @@ features cannot lower the translation-unit ABI level;
 
 - Clang now diagnoses more details when a constraint evaluates to false.
 
+- `-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 5c831e6cdebce..feb2b41f0a84a 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -14039,6 +14039,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'}}
+}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to