Skip to content

Conversation

@AmrDeveloper
Copy link
Member

Ternary with a constant condition and throw in the live part

@AmrDeveloper AmrDeveloper requested a review from mmha November 17, 2025 20:29
@llvmbot llvmbot added clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project labels Nov 17, 2025
@llvmbot
Copy link
Member

llvmbot commented Nov 17, 2025

@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clangir

Author: Amr Hesham (AmrDeveloper)

Changes

Ternary with a constant condition and throw in the live part


Full diff: https://github.com/llvm/llvm-project/pull/168432.diff

2 Files Affected:

  • (modified) clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp (+3-3)
  • (modified) clang/test/CIR/CodeGen/ternary-throw.cpp (+43)
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 3b0977d213325..4f909ec681691 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -2379,9 +2379,9 @@ mlir::Value ScalarExprEmitter::VisitAbstractConditionalOperator(
       // type, so evaluating it returns a null Value.  However, a conditional
       // with non-void type must return a non-null Value.
       if (!result && !e->getType()->isVoidType()) {
-        cgf.cgm.errorNYI(e->getSourceRange(),
-                         "throw expression in conditional operator");
-        result = {};
+        result = builder.getConstant(
+            loc, cir::PoisonAttr::get(builder.getContext(),
+                                      cgf.convertType(e->getType())));
       }
 
       return result;
diff --git a/clang/test/CIR/CodeGen/ternary-throw.cpp b/clang/test/CIR/CodeGen/ternary-throw.cpp
index fb8897fa18a74..74168c19ca7c3 100644
--- a/clang/test/CIR/CodeGen/ternary-throw.cpp
+++ b/clang/test/CIR/CodeGen/ternary-throw.cpp
@@ -195,3 +195,46 @@ const int& test_cond_const_false_throw_true() {
 // OGCG-NOT: __cxa_throw
 // OGCG: ret ptr %[[A]]
 
+const int &test_cond_const_true_throw_true() {
+  const int a = 30;
+  return true ? throw 0 : a;
+}
+
+// CIR-LABEL: cir.func{{.*}} @_Z31test_cond_const_true_throw_truev(
+// CIR:  %[[RET_ADDR:.*]] = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>, ["__retval"]
+// CIR:  %[[A_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init, const]
+// CIR:  %[[CONST_30:.*]] = cir.const #cir.int<30> : !s32i
+// CIR:  cir.store{{.*}} %[[CONST_30]], %[[A_ADDR]] : !s32i, !cir.ptr<!s32i>
+// CIR:  %[[EXCEPTION:.*]] = cir.alloc.exception 4 -> !cir.ptr<!s32i>
+// CIR:  %[[CONST_0:.*]] = cir.const #cir.int<0> : !s32i
+// CIR:  cir.store{{.*}} %[[CONST_0]], %[[EXCEPTION]] : !s32i, !cir.ptr<!s32i>
+// CIR:  cir.throw %[[EXCEPTION]] : !cir.ptr<!s32i>, @_ZTIi
+// CIR:  cir.unreachable
+// CIR: ^[[NO_PRED_LABEL:.*]]:
+// CIR:   %[[CONST_NULL:.*]] = cir.const #cir.ptr<null> : !cir.ptr<!s32i>
+// CIR:   cir.store %[[CONST_NULL]], %[[RET_ADDR]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>
+// CIR:   %[[TMP_RET:.*]] = cir.load %[[RET_ADDR]] : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
+// CIR:   cir.return %[[TMP_RET]] : !cir.ptr<!s32i>
+
+// LLVM-LABEL: define{{.*}} ptr @_Z31test_cond_const_true_throw_truev(
+// LLVM:  %[[RET_ADDR:.*]] = alloca ptr, i64 1, align 8
+// LLVM:  %[[A_ADDR:.*]] = alloca i32, i64 1, align 4
+// LLVM:  store i32 30, ptr %[[A_ADDR]], align 4
+// LLVM:  %[[EXCEPTION:.*]] = call ptr @__cxa_allocate_exception(i64 4)
+// LLVM:  store i32 0, ptr %[[EXCEPTION]], align 16
+// LLVM:  call void @__cxa_throw(ptr %[[EXCEPTION]], ptr @_ZTIi, ptr null)
+// LLVM:  unreachable
+// LLVM: [[NO_PRED_LABEL:.*]]:
+// LLVM:  store ptr null, ptr %[[RET_ADDR]], align 8
+// LLVM:  %[[TMP_RET:.*]] = load ptr, ptr %[[RET_ADDR]], align 8
+// LLVM:  ret ptr %[[TMP_RET]]
+
+// OGCG-LABEL: define{{.*}} ptr @_Z31test_cond_const_true_throw_truev(
+// OGCG:  %[[A_ADDR:.*]] = alloca i32, align 4
+// OGCG:  store i32 30, ptr %[[A_ADDR]], align 4
+// OGCG:  %[[EXCEPTION:.*]] = call ptr @__cxa_allocate_exception(i64 4)
+// OGCG:  store i32 0, ptr %[[EXCEPTION]], align 16
+// OGCG:  call void @__cxa_throw(ptr %[[EXCEPTION]], ptr @_ZTIi, ptr null)
+// OGCG:  unreachable
+// OGCG: [[NO_PRED_LABEL:.*]]:
+// OGCG:  ret ptr [[UNDEF:.*]]

@github-actions
Copy link

🐧 Linux x64 Test Results

  • 111972 tests passed
  • 4073 tests skipped

Copy link
Contributor

@andykaylor andykaylor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@AmrDeveloper AmrDeveloper merged commit 36cbcec into llvm:main Nov 19, 2025
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants