[clang] [CIR] Fix use-after-free when emitting ternary with a throw-expression arm (PR #208850)

Akshay K via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 13 17:54:56 PDT 2026


================
@@ -2929,6 +2929,12 @@ mlir::Value ScalarExprEmitter::VisitAbstractConditionalOperator(
       yieldTy = branch.getType();
       cir::YieldOp::create(b, loc, branch);
     } else {
+      // A noreturn branch (e.g. throw) leaves the insertion point in a dead
+      // block that LexicalScope cleanup erases; no yield is needed and saving
+      // an insertion point into it would dangle.
+      mlir::Block *curBlock = b.getInsertionBlock();
+      if (curBlock->empty() && !curBlock->isEntryBlock())
----------------
kumarak wrote:

Thanks, @andykaylor, for the review. The condition was checking for a noreturn expression, and it will be an entry block when one of the ternary arms is void. That is when it takes the path of saving the insertion point and patching it later with the yield.

I’ve updated the patch to avoid saving the insertion points entirely. After creating the `cir.ternary`, it now inspects the generated regions and adds a `cir.yield` only where a region does not already have a terminator. This leaves noreturn arms (`throw`) terminated by `cir.unreachable`.

Please let me know if this is closer to what you had in mind.

https://github.com/llvm/llvm-project/pull/208850


More information about the cfe-commits mailing list