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

Reply via email to