[clang] [LifetimeSafety] Fix crash on ternary operator when one of the expressions is `throw` (PR #190345)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 3 06:48:24 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-temporal-safety
@llvm/pr-subscribers-clang-analysis
Author: NeKon69
<details>
<summary>Changes</summary>
`throw` is a special case: it produces void, but it can still appear in the ternary operator. Ignore it when flowing origins.
Closes #<!-- -->183895
---
Full diff: https://github.com/llvm/llvm-project/pull/190345.diff
2 Files Affected:
- (modified) clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp (+16-2)
- (added) clang/test/Sema/warn-lifetime-safety-conditional-throw.cpp (+9)
``````````diff
diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
index 75f2978d848b7..5eb2fcd150576 100644
--- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
@@ -94,6 +94,10 @@ static const Loan *createLoan(FactManager &FactMgr,
return FactMgr.getLoanMgr().createLoan(Path, MTE);
}
+static bool producesConditionalResult(const Expr *E) {
+ return !isa<CXXThrowExpr>(E->IgnoreParenImpCasts());
+}
+
void FactsGenerator::run() {
llvm::TimeTraceScope TimeProfile("FactGenerator");
const CFG &Cfg = *AC.getCFG();
@@ -404,8 +408,18 @@ void FactsGenerator::VisitConditionalOperator(const ConditionalOperator *CO) {
if (hasOrigins(CO)) {
// Merge origins from both branches of the conditional operator.
// We kill to clear the initial state and merge both origins into it.
- killAndFlowOrigin(*CO, *CO->getTrueExpr());
- flowOrigin(*CO, *CO->getFalseExpr());
+ const Expr *TrueExpr = CO->getTrueExpr();
+ const Expr *FalseExpr = CO->getFalseExpr();
+ bool Initialized = false;
+ for (const Expr *Branch : {TrueExpr, FalseExpr}) {
+ if (!producesConditionalResult(Branch))
+ continue;
+ if (!Initialized) {
+ killAndFlowOrigin(*CO, *Branch);
+ Initialized = true;
+ } else
+ flowOrigin(*CO, *Branch);
+ }
}
}
diff --git a/clang/test/Sema/warn-lifetime-safety-conditional-throw.cpp b/clang/test/Sema/warn-lifetime-safety-conditional-throw.cpp
new file mode 100644
index 0000000000000..2437618d131cd
--- /dev/null
+++ b/clang/test/Sema/warn-lifetime-safety-conditional-throw.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -Wlifetime-safety -Wno-dangling -verify %s
+
+// expected-no-diagnostics
+
+void conditional_throw_branches(bool cond, int *value) {
+ (void)(cond ? throw 1 : value);
+ (void)(cond ? value : throw 1);
+ (void)(cond ? throw 1 : throw 2);
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/190345
More information about the cfe-commits
mailing list