Skip to content

Commit 36cbcec

Browse files
authored
[CIR] Ternary with const cond and throw in the live part (#168432)
Ternary with a constant condition and throw in the live part
1 parent ed0c36c commit 36cbcec

File tree

2 files changed

+46
-3
lines changed

2 files changed

+46
-3
lines changed

clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2388,9 +2388,9 @@ mlir::Value ScalarExprEmitter::VisitAbstractConditionalOperator(
23882388
// type, so evaluating it returns a null Value. However, a conditional
23892389
// with non-void type must return a non-null Value.
23902390
if (!result && !e->getType()->isVoidType()) {
2391-
cgf.cgm.errorNYI(e->getSourceRange(),
2392-
"throw expression in conditional operator");
2393-
result = {};
2391+
result = builder.getConstant(
2392+
loc, cir::PoisonAttr::get(builder.getContext(),
2393+
cgf.convertType(e->getType())));
23942394
}
23952395

23962396
return result;

clang/test/CIR/CodeGen/ternary-throw.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,3 +195,46 @@ const int& test_cond_const_false_throw_true() {
195195
// OGCG-NOT: __cxa_throw
196196
// OGCG: ret ptr %[[A]]
197197

198+
const int &test_cond_const_true_throw_true() {
199+
const int a = 30;
200+
return true ? throw 0 : a;
201+
}
202+
203+
// CIR-LABEL: cir.func{{.*}} @_Z31test_cond_const_true_throw_truev(
204+
// CIR: %[[RET_ADDR:.*]] = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>, ["__retval"]
205+
// CIR: %[[A_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init, const]
206+
// CIR: %[[CONST_30:.*]] = cir.const #cir.int<30> : !s32i
207+
// CIR: cir.store{{.*}} %[[CONST_30]], %[[A_ADDR]] : !s32i, !cir.ptr<!s32i>
208+
// CIR: %[[EXCEPTION:.*]] = cir.alloc.exception 4 -> !cir.ptr<!s32i>
209+
// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !s32i
210+
// CIR: cir.store{{.*}} %[[CONST_0]], %[[EXCEPTION]] : !s32i, !cir.ptr<!s32i>
211+
// CIR: cir.throw %[[EXCEPTION]] : !cir.ptr<!s32i>, @_ZTIi
212+
// CIR: cir.unreachable
213+
// CIR: ^[[NO_PRED_LABEL:.*]]:
214+
// CIR: %[[CONST_NULL:.*]] = cir.const #cir.ptr<null> : !cir.ptr<!s32i>
215+
// CIR: cir.store %[[CONST_NULL]], %[[RET_ADDR]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>
216+
// CIR: %[[TMP_RET:.*]] = cir.load %[[RET_ADDR]] : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
217+
// CIR: cir.return %[[TMP_RET]] : !cir.ptr<!s32i>
218+
219+
// LLVM-LABEL: define{{.*}} ptr @_Z31test_cond_const_true_throw_truev(
220+
// LLVM: %[[RET_ADDR:.*]] = alloca ptr, i64 1, align 8
221+
// LLVM: %[[A_ADDR:.*]] = alloca i32, i64 1, align 4
222+
// LLVM: store i32 30, ptr %[[A_ADDR]], align 4
223+
// LLVM: %[[EXCEPTION:.*]] = call ptr @__cxa_allocate_exception(i64 4)
224+
// LLVM: store i32 0, ptr %[[EXCEPTION]], align 16
225+
// LLVM: call void @__cxa_throw(ptr %[[EXCEPTION]], ptr @_ZTIi, ptr null)
226+
// LLVM: unreachable
227+
// LLVM: [[NO_PRED_LABEL:.*]]:
228+
// LLVM: store ptr null, ptr %[[RET_ADDR]], align 8
229+
// LLVM: %[[TMP_RET:.*]] = load ptr, ptr %[[RET_ADDR]], align 8
230+
// LLVM: ret ptr %[[TMP_RET]]
231+
232+
// OGCG-LABEL: define{{.*}} ptr @_Z31test_cond_const_true_throw_truev(
233+
// OGCG: %[[A_ADDR:.*]] = alloca i32, align 4
234+
// OGCG: store i32 30, ptr %[[A_ADDR]], align 4
235+
// OGCG: %[[EXCEPTION:.*]] = call ptr @__cxa_allocate_exception(i64 4)
236+
// OGCG: store i32 0, ptr %[[EXCEPTION]], align 16
237+
// OGCG: call void @__cxa_throw(ptr %[[EXCEPTION]], ptr @_ZTIi, ptr null)
238+
// OGCG: unreachable
239+
// OGCG: [[NO_PRED_LABEL:.*]]:
240+
// OGCG: ret ptr [[UNDEF:.*]]

0 commit comments

Comments
 (0)