https://github.com/NeKon69 updated 
https://github.com/llvm/llvm-project/pull/190345

>From 813689c7f7392ec5c44d90ec8a030a9ba102985d Mon Sep 17 00:00:00 2001
From: NeKon69 <[email protected]>
Date: Fri, 3 Apr 2026 16:32:34 +0300
Subject: [PATCH 01/16] [LifetimeSafety] Apply the fix

---
 .../Analysis/LifetimeSafety/FactsGenerator.cpp | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp 
b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
index 75f2978d848b7..6108d34275092 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);
+    }
   }
 }
 

>From c43162e8d4de5a033ddc84a275f6fe3a44db78f7 Mon Sep 17 00:00:00 2001
From: NeKon69 <[email protected]>
Date: Fri, 3 Apr 2026 16:41:36 +0300
Subject: [PATCH 02/16] add a test file

---
 .../test/Sema/warn-lifetime-safety-conditional-throw.cpp | 9 +++++++++
 1 file changed, 9 insertions(+)
 create mode 100644 clang/test/Sema/warn-lifetime-safety-conditional-throw.cpp

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);
+}

>From ac67df326082b1a1ed7237742789b85bafaff45e Mon Sep 17 00:00:00 2001
From: NeKon69 <[email protected]>
Date: Fri, 3 Apr 2026 16:43:14 +0300
Subject: [PATCH 03/16] update functions body to represent what it actually
 does

---
 clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp 
b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
index 6108d34275092..5eb2fcd150576 100644
--- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
@@ -95,7 +95,7 @@ static const Loan *createLoan(FactManager &FactMgr,
 }
 
 static bool producesConditionalResult(const Expr *E) {
-  return isa<CXXThrowExpr>(E->IgnoreParenImpCasts());
+  return !isa<CXXThrowExpr>(E->IgnoreParenImpCasts());
 }
 
 void FactsGenerator::run() {
@@ -412,7 +412,7 @@ void FactsGenerator::VisitConditionalOperator(const 
ConditionalOperator *CO) {
     const Expr *FalseExpr = CO->getFalseExpr();
     bool Initialized = false;
     for (const Expr *Branch : {TrueExpr, FalseExpr}) {
-      if (producesConditionalResult(Branch))
+      if (!producesConditionalResult(Branch))
         continue;
       if (!Initialized) {
         killAndFlowOrigin(*CO, *Branch);

>From 4c89bd55fcb8d8a41c45962b4943358959325d33 Mon Sep 17 00:00:00 2001
From: NeKon69 <[email protected]>
Date: Sun, 5 Apr 2026 14:01:44 +0300
Subject: [PATCH 04/16] [LifetimeSafety] Improve ternary handling to ignore
 [[noreturn]] arms

---
 .../Analyses/LifetimeSafety/FactsGenerator.h  |  2 +
 .../LifetimeSafety/FactsGenerator.cpp         | 42 ++++++++++++-------
 ...warn-lifetime-safety-conditional-throw.cpp | 41 ++++++++++++++++--
 3 files changed, 66 insertions(+), 19 deletions(-)

diff --git 
a/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h 
b/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h
index 8fe2436b04086..c17b603c00ddb 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h
@@ -66,6 +66,8 @@ class FactsGenerator : public 
ConstStmtVisitor<FactsGenerator> {
 
   void handlePointerArithmetic(const BinaryOperator *BO);
 
+  void handleTernaryOperator(const ConditionalOperator *CO);
+
   void handleCXXCtorInitializer(const CXXCtorInitializer *CII);
 
   void handleLifetimeEnds(const CFGLifetimeEnds &LifetimeEnds);
diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp 
b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
index 5eb2fcd150576..617c3d53fd508 100644
--- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
@@ -94,8 +94,8 @@ static const Loan *createLoan(FactManager &FactMgr,
   return FactMgr.getLoanMgr().createLoan(Path, MTE);
 }
 
-static bool producesConditionalResult(const Expr *E) {
-  return !isa<CXXThrowExpr>(E->IgnoreParenImpCasts());
+static bool isThrowExpr(const Expr *E) {
+  return isa<CXXThrowExpr>(E->IgnoreParenImpCasts());
 }
 
 void FactsGenerator::run() {
@@ -404,22 +404,32 @@ void FactsGenerator::VisitBinaryOperator(const 
BinaryOperator *BO) {
   // TODO: Handle assignments involving dereference like `*p = q`.
 }
 
+void FactsGenerator::handleTernaryOperator(const ConditionalOperator *CO) {
+  const auto *Map = AC.getCFGStmtMap();
+  const Expr *TrueExpr = CO->getTrueExpr();
+  const Expr *FalseExpr = CO->getFalseExpr();
+  bool TBHasConditionResult =
+      Map->getBlock(TrueExpr)->hasNoReturnElement() || isThrowExpr(TrueExpr);
+  bool FBHasConditionResult =
+      Map->getBlock(FalseExpr)->hasNoReturnElement() || isThrowExpr(FalseExpr);
+  bool FirstFlow = true;
+  auto HandleFlow = [&](const Expr *E, bool HasNoReturn) {
+    if (HasNoReturn)
+      return;
+    if (FirstFlow) {
+      killAndFlowOrigin(*CO, *E);
+      FirstFlow = false;
+    } else {
+      flowOrigin(*CO, *E);
+    }
+  };
+  HandleFlow(TrueExpr, TBHasConditionResult);
+  HandleFlow(FalseExpr, FBHasConditionResult);
+}
+
 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.
-    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);
-    }
+    handleTernaryOperator(CO);
   }
 }
 
diff --git a/clang/test/Sema/warn-lifetime-safety-conditional-throw.cpp 
b/clang/test/Sema/warn-lifetime-safety-conditional-throw.cpp
index 2437618d131cd..874d885c4bce5 100644
--- a/clang/test/Sema/warn-lifetime-safety-conditional-throw.cpp
+++ b/clang/test/Sema/warn-lifetime-safety-conditional-throw.cpp
@@ -1,9 +1,44 @@
 // 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 throw_branches(bool cond, int *value) {
   (void)(cond ? throw 1 : value);
   (void)(cond ? value : throw 1);
   (void)(cond ? throw 1 : throw 2);
 }
+
+int *f(int *p [[clang::lifetimebound]]);
+[[noreturn]] int *noret_f(int *p [[clang::lifetimebound]]);
+
+
+constexpr bool kTrue = true;
+constexpr bool kFalse = false;
+
+int *constexpr_dead_false(int *num) {
+  int local = 0;
+  return kTrue ? num : f(&local);
+}
+
+int *constexpr_dead_true(int *num) {
+  int local = 0;
+  return kFalse ? f(&local) : num;
+}
+
+int *constexpr_live_false(int *num) {
+  int local = 0;
+  return kFalse ? num : f(&local); // expected-warning {{address of stack 
memory is returned later}} // expected-note {{returned here}}
+}
+
+int *constexpr_live_true(int *num) {
+  int local = 0;
+  return kTrue ? f(&local) : num; // expected-warning {{address of stack 
memory is returned later}} // expected-note {{returned here}}
+}
+
+int *noreturn_dead_false(bool cond, int *num) {
+  int local = 0;
+  return cond ? num : noret_f(&local);
+}
+
+int *noreturn_dead_true(bool cond, int *num) {
+  int local = 0;
+  return cond ? noret_f(&local) : num;
+}

>From 0f1052c3d855559a2ac424ac36923dd09a4d63a0 Mon Sep 17 00:00:00 2001
From: NeKon69 <[email protected]>
Date: Mon, 6 Apr 2026 22:35:49 +0300
Subject: [PATCH 05/16] [LifetimeSafety] use isInevitablySinking to handle
 ternary, update tests to include nested ones

---
 .../LifetimeSafety/FactsGenerator.cpp         | 16 ++++++++--------
 ...warn-lifetime-safety-conditional-throw.cpp | 19 +++++++++++--------
 2 files changed, 19 insertions(+), 16 deletions(-)

diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp 
b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
index 617c3d53fd508..7c61e590037df 100644
--- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
@@ -406,12 +406,13 @@ void FactsGenerator::VisitBinaryOperator(const 
BinaryOperator *BO) {
 
 void FactsGenerator::handleTernaryOperator(const ConditionalOperator *CO) {
   const auto *Map = AC.getCFGStmtMap();
+
   const Expr *TrueExpr = CO->getTrueExpr();
   const Expr *FalseExpr = CO->getFalseExpr();
-  bool TBHasConditionResult =
-      Map->getBlock(TrueExpr)->hasNoReturnElement() || isThrowExpr(TrueExpr);
-  bool FBHasConditionResult =
-      Map->getBlock(FalseExpr)->hasNoReturnElement() || isThrowExpr(FalseExpr);
+
+  bool TBIsSinking = Map->getBlock(TrueExpr)->isInevitablySinking();
+  bool FBIsSinking = Map->getBlock(FalseExpr)->isInevitablySinking();
+
   bool FirstFlow = true;
   auto HandleFlow = [&](const Expr *E, bool HasNoReturn) {
     if (HasNoReturn)
@@ -419,12 +420,11 @@ void FactsGenerator::handleTernaryOperator(const 
ConditionalOperator *CO) {
     if (FirstFlow) {
       killAndFlowOrigin(*CO, *E);
       FirstFlow = false;
-    } else {
+    } else
       flowOrigin(*CO, *E);
-    }
   };
-  HandleFlow(TrueExpr, TBHasConditionResult);
-  HandleFlow(FalseExpr, FBHasConditionResult);
+  HandleFlow(TrueExpr, TBIsSinking);
+  HandleFlow(FalseExpr, FBIsSinking);
 }
 
 void FactsGenerator::VisitConditionalOperator(const ConditionalOperator *CO) {
diff --git a/clang/test/Sema/warn-lifetime-safety-conditional-throw.cpp 
b/clang/test/Sema/warn-lifetime-safety-conditional-throw.cpp
index 874d885c4bce5..5e3a9f01d89b2 100644
--- a/clang/test/Sema/warn-lifetime-safety-conditional-throw.cpp
+++ b/clang/test/Sema/warn-lifetime-safety-conditional-throw.cpp
@@ -2,10 +2,14 @@
 
 void throw_branches(bool cond, int *value) {
   (void)(cond ? throw 1 : value);
-  (void)(cond ? value : throw 1);
   (void)(cond ? throw 1 : throw 2);
 }
 
+void nested_throw_branches(bool cond, bool cond2, int *value) {
+  (void)(cond ? (cond2 ? throw 1 : value) : throw 2);
+  (void)(cond ? throw 1 : (cond2 ? value : throw 2));
+}
+
 int *f(int *p [[clang::lifetimebound]]);
 [[noreturn]] int *noret_f(int *p [[clang::lifetimebound]]);
 
@@ -18,9 +22,9 @@ int *constexpr_dead_false(int *num) {
   return kTrue ? num : f(&local);
 }
 
-int *constexpr_dead_true(int *num) {
+int *constexpr_dead_nested(int *num) {
   int local = 0;
-  return kFalse ? f(&local) : num;
+  return kTrue ? (kTrue ? num : f(&local)) : num;
 }
 
 int *constexpr_live_false(int *num) {
@@ -28,17 +32,16 @@ int *constexpr_live_false(int *num) {
   return kFalse ? num : f(&local); // expected-warning {{address of stack 
memory is returned later}} // expected-note {{returned here}}
 }
 
-int *constexpr_live_true(int *num) {
+int *constexpr_live_nested(int *num) {
   int local = 0;
-  return kTrue ? f(&local) : num; // expected-warning {{address of stack 
memory is returned later}} // expected-note {{returned here}}
-}
+  return kTrue ? (kFalse ? num : f(&local)) : num; } // expected-warning 
{{address of stack memory is returned later}} // expected-note {{returned here}}
 
 int *noreturn_dead_false(bool cond, int *num) {
   int local = 0;
   return cond ? num : noret_f(&local);
 }
 
-int *noreturn_dead_true(bool cond, int *num) {
+int *noreturn_dead_nested(bool cond, bool cond2, int *num) {
   int local = 0;
-  return cond ? noret_f(&local) : num;
+  return cond ? (cond2 ? num : noret_f(&local)) : num;
 }

>From c6f0ed8ac1c56dfecfedc9c08f8c16c0a2128fe9 Mon Sep 17 00:00:00 2001
From: NeKon69 <[email protected]>
Date: Mon, 6 Apr 2026 22:53:28 +0300
Subject: [PATCH 06/16] delete unused function

---
 clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp 
b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
index 7c61e590037df..1fb83ef0d0288 100644
--- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
@@ -94,10 +94,6 @@ static const Loan *createLoan(FactManager &FactMgr,
   return FactMgr.getLoanMgr().createLoan(Path, MTE);
 }
 
-static bool isThrowExpr(const Expr *E) {
-  return isa<CXXThrowExpr>(E->IgnoreParenImpCasts());
-}
-
 void FactsGenerator::run() {
   llvm::TimeTraceScope TimeProfile("FactGenerator");
   const CFG &Cfg = *AC.getCFG();

>From 10f358965cb967b0ae41b34d2fae93fddd914295 Mon Sep 17 00:00:00 2001
From: NeKon69 <[email protected]>
Date: Tue, 7 Apr 2026 16:59:17 +0300
Subject: [PATCH 07/16] push test code

---
 .../Analysis/LifetimeSafety/FactsGenerator.cpp  | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp 
b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
index 1fb83ef0d0288..62d2c0db45572 100644
--- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
@@ -402,16 +402,21 @@ void FactsGenerator::VisitBinaryOperator(const 
BinaryOperator *BO) {
 
 void FactsGenerator::handleTernaryOperator(const ConditionalOperator *CO) {
   const auto *Map = AC.getCFGStmtMap();
+  const auto *const COBlock = Map->getBlock(CO);
 
   const Expr *TrueExpr = CO->getTrueExpr();
   const Expr *FalseExpr = CO->getFalseExpr();
 
-  bool TBIsSinking = Map->getBlock(TrueExpr)->isInevitablySinking();
-  bool FBIsSinking = Map->getBlock(FalseExpr)->isInevitablySinking();
+  COBlock->dump();
+  const auto *TI = COBlock->succ_begin();
+  const auto *FI = TI + 1;
+
+  bool TBHasEdge = TI->getReachableBlock() != nullptr;
+  bool FBHasEdge = FI->getReachableBlock() != nullptr;
 
   bool FirstFlow = true;
-  auto HandleFlow = [&](const Expr *E, bool HasNoReturn) {
-    if (HasNoReturn)
+  auto HandleFlow = [&](const Expr *E, bool HasAnEdge) {
+    if (!HasAnEdge)
       return;
     if (FirstFlow) {
       killAndFlowOrigin(*CO, *E);
@@ -419,8 +424,8 @@ void FactsGenerator::handleTernaryOperator(const 
ConditionalOperator *CO) {
     } else
       flowOrigin(*CO, *E);
   };
-  HandleFlow(TrueExpr, TBIsSinking);
-  HandleFlow(FalseExpr, FBIsSinking);
+  HandleFlow(TrueExpr, TBHasEdge);
+  HandleFlow(FalseExpr, FBHasEdge);
 }
 
 void FactsGenerator::VisitConditionalOperator(const ConditionalOperator *CO) {

>From 8f7a0615d38eb78e34be7c662ce8cd0ab24293bf Mon Sep 17 00:00:00 2001
From: NeKon69 <[email protected]>
Date: Tue, 7 Apr 2026 20:48:46 +0300
Subject: [PATCH 08/16] [LifetimeSafety] implement unpolished logic

---
 .../Analyses/LifetimeSafety/FactsGenerator.h  |  1 +
 .../LifetimeSafety/FactsGenerator.cpp         | 47 ++++++++++++++-----
 2 files changed, 37 insertions(+), 11 deletions(-)

diff --git 
a/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h 
b/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h
index c17b603c00ddb..b15e0bf69884f 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h
@@ -136,6 +136,7 @@ class FactsGenerator : public 
ConstStmtVisitor<FactsGenerator> {
   // corresponding to the left-hand side is updated to be a "write", thereby
   // exempting it from the check.
   llvm::DenseMap<const Expr *, UseFact *> UseFacts;
+  const CFGBlock *CurrentBlock;
 };
 
 } // namespace clang::lifetimes::internal
diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp 
b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
index 62d2c0db45572..c9ebee2b8307d 100644
--- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
@@ -103,6 +103,7 @@ void FactsGenerator::run() {
   for (const CFGBlock *Block : *AC.getAnalysis<PostOrderCFGView>()) {
     CurrentBlockFacts.clear();
     EscapesInCurrentBlock.clear();
+    CurrentBlock = Block;
     if (Block == &Cfg.getEntry())
       CurrentBlockFacts.append(PlaceholderLoanFacts.begin(),
                                PlaceholderLoanFacts.end());
@@ -401,18 +402,42 @@ void FactsGenerator::VisitBinaryOperator(const 
BinaryOperator *BO) {
 }
 
 void FactsGenerator::handleTernaryOperator(const ConditionalOperator *CO) {
-  const auto *Map = AC.getCFGStmtMap();
-  const auto *const COBlock = Map->getBlock(CO);
-
-  const Expr *TrueExpr = CO->getTrueExpr();
-  const Expr *FalseExpr = CO->getFalseExpr();
-
-  COBlock->dump();
-  const auto *TI = COBlock->succ_begin();
-  const auto *FI = TI + 1;
+  const Expr *TrueExpr = CO->getTrueExpr()->IgnoreParenImpCasts();
+  const Expr *FalseExpr = CO->getFalseExpr()->IgnoreParenImpCasts();
+
+  const auto Preds = CurrentBlock->preds();
+  auto PredHasStmt = [](const CFGBlock::AdjacentBlock &Pred, const Stmt *S) {
+    return llvm::any_of(*Pred, [S](const CFGElement &Elt) {
+      if (auto CS = Elt.getAs<CFGStmt>()) {
+        // S->dump();
+        // CS->getStmt()->dump();
+        return CS->getStmt() == S;
+      }
+      return false;
+    });
+  };
 
-  bool TBHasEdge = TI->getReachableBlock() != nullptr;
-  bool FBHasEdge = FI->getReachableBlock() != nullptr;
+  bool TBHasEdge = true;
+  bool FBHasEdge = true;
+
+  // CurrentBlock->dump();
+  switch (CurrentBlock->pred_size()) {
+  case 0:
+    return;
+  case 1:
+    TBHasEdge = PredHasStmt(*Preds.begin(), TrueExpr);
+    FBHasEdge = !TBHasEdge;
+    break;
+  case 2: {
+    const auto *It = Preds.begin();
+    TBHasEdge = It->isReachable();
+    FBHasEdge = (++It)->isReachable();
+    break;
+  }
+  default:
+    llvm_unreachable("expected at most 2 successors");
+    return;
+  }
 
   bool FirstFlow = true;
   auto HandleFlow = [&](const Expr *E, bool HasAnEdge) {

>From da3ed0ce9a88feb086d23acf85a41b118300fb53 Mon Sep 17 00:00:00 2001
From: NeKon69 <[email protected]>
Date: Tue, 7 Apr 2026 22:18:30 +0300
Subject: [PATCH 09/16] fix test crashes

---
 clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp 
b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
index c9ebee2b8307d..6f9bff839c44c 100644
--- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
@@ -402,15 +402,13 @@ void FactsGenerator::VisitBinaryOperator(const 
BinaryOperator *BO) {
 }
 
 void FactsGenerator::handleTernaryOperator(const ConditionalOperator *CO) {
-  const Expr *TrueExpr = CO->getTrueExpr()->IgnoreParenImpCasts();
-  const Expr *FalseExpr = CO->getFalseExpr()->IgnoreParenImpCasts();
+  const Expr *TrueExpr = CO->getTrueExpr();
+  const Expr *FalseExpr = CO->getFalseExpr();
 
   const auto Preds = CurrentBlock->preds();
   auto PredHasStmt = [](const CFGBlock::AdjacentBlock &Pred, const Stmt *S) {
     return llvm::any_of(*Pred, [S](const CFGElement &Elt) {
       if (auto CS = Elt.getAs<CFGStmt>()) {
-        // S->dump();
-        // CS->getStmt()->dump();
         return CS->getStmt() == S;
       }
       return false;
@@ -420,12 +418,11 @@ void FactsGenerator::handleTernaryOperator(const 
ConditionalOperator *CO) {
   bool TBHasEdge = true;
   bool FBHasEdge = true;
 
-  // CurrentBlock->dump();
   switch (CurrentBlock->pred_size()) {
   case 0:
     return;
   case 1:
-    TBHasEdge = PredHasStmt(*Preds.begin(), TrueExpr);
+    TBHasEdge = PredHasStmt(*Preds.begin(), TrueExpr->IgnoreParenImpCasts());
     FBHasEdge = !TBHasEdge;
     break;
   case 2: {

>From 3eae67bdbfb79d08871a7f4650b30213c9709294 Mon Sep 17 00:00:00 2001
From: NeKon69 <[email protected]>
Date: Tue, 7 Apr 2026 22:19:58 +0300
Subject: [PATCH 10/16] rename test file

---
 ...al-throw.cpp => warn-lifetime-safety-conditional-operator.cpp} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename clang/test/Sema/{warn-lifetime-safety-conditional-throw.cpp => 
warn-lifetime-safety-conditional-operator.cpp} (100%)

diff --git a/clang/test/Sema/warn-lifetime-safety-conditional-throw.cpp 
b/clang/test/Sema/warn-lifetime-safety-conditional-operator.cpp
similarity index 100%
rename from clang/test/Sema/warn-lifetime-safety-conditional-throw.cpp
rename to clang/test/Sema/warn-lifetime-safety-conditional-operator.cpp

>From 175b883a3e7b9df6e51b856f9c0fb28c0c5378c6 Mon Sep 17 00:00:00 2001
From: NeKon69 <[email protected]>
Date: Wed, 8 Apr 2026 23:02:27 +0300
Subject: [PATCH 11/16] update assert message

---
 clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp 
b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
index 6f9bff839c44c..7b5ee28e32c56 100644
--- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
@@ -432,7 +432,7 @@ void FactsGenerator::handleTernaryOperator(const 
ConditionalOperator *CO) {
     break;
   }
   default:
-    llvm_unreachable("expected at most 2 successors");
+    llvm_unreachable("expected at most 2 predecessors");
     return;
   }
 

>From 19ec7d421419087889469b5fc3f8bcc30038e422 Mon Sep 17 00:00:00 2001
From: NeKon69 <[email protected]>
Date: Wed, 8 Apr 2026 23:04:40 +0300
Subject: [PATCH 12/16] fix formatting in one of the tests

---
 clang/test/Sema/warn-lifetime-safety-conditional-operator.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/test/Sema/warn-lifetime-safety-conditional-operator.cpp 
b/clang/test/Sema/warn-lifetime-safety-conditional-operator.cpp
index 5e3a9f01d89b2..b6800b5e39809 100644
--- a/clang/test/Sema/warn-lifetime-safety-conditional-operator.cpp
+++ b/clang/test/Sema/warn-lifetime-safety-conditional-operator.cpp
@@ -34,8 +34,8 @@ int *constexpr_live_false(int *num) {
 
 int *constexpr_live_nested(int *num) {
   int local = 0;
-  return kTrue ? (kFalse ? num : f(&local)) : num; } // expected-warning 
{{address of stack memory is returned later}} // expected-note {{returned here}}
-
+  return kTrue ? (kFalse ? num : f(&local)) : num; // expected-warning 
{{address of stack memory is returned later}} // expected-note {{returned here}}
+}
 int *noreturn_dead_false(bool cond, int *num) {
   int local = 0;
   return cond ? num : noret_f(&local);

>From 6a5124c2e1b360babf1c79b9507342a27921665e Mon Sep 17 00:00:00 2001
From: NeKon69 <[email protected]>
Date: Thu, 9 Apr 2026 20:33:49 +0300
Subject: [PATCH 13/16] address review suggestions

---
 .../Analyses/LifetimeSafety/FactsGenerator.h  |  2 -
 .../LifetimeSafety/FactsGenerator.cpp         | 98 +++++++++----------
 clang/test/Sema/warn-lifetime-safety.cpp      | 55 +++++++++++
 3 files changed, 103 insertions(+), 52 deletions(-)

diff --git 
a/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h 
b/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h
index b15e0bf69884f..2dbadb27981a7 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h
@@ -66,8 +66,6 @@ class FactsGenerator : public 
ConstStmtVisitor<FactsGenerator> {
 
   void handlePointerArithmetic(const BinaryOperator *BO);
 
-  void handleTernaryOperator(const ConditionalOperator *CO);
-
   void handleCXXCtorInitializer(const CXXCtorInitializer *CII);
 
   void handleLifetimeEnds(const CFGLifetimeEnds &LifetimeEnds);
diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp 
b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
index 7b5ee28e32c56..5a821f37e3ad4 100644
--- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
@@ -401,58 +401,56 @@ void FactsGenerator::VisitBinaryOperator(const 
BinaryOperator *BO) {
   // TODO: Handle assignments involving dereference like `*p = q`.
 }
 
-void FactsGenerator::handleTernaryOperator(const ConditionalOperator *CO) {
-  const Expr *TrueExpr = CO->getTrueExpr();
-  const Expr *FalseExpr = CO->getFalseExpr();
-
-  const auto Preds = CurrentBlock->preds();
-  auto PredHasStmt = [](const CFGBlock::AdjacentBlock &Pred, const Stmt *S) {
-    return llvm::any_of(*Pred, [S](const CFGElement &Elt) {
-      if (auto CS = Elt.getAs<CFGStmt>()) {
-        return CS->getStmt() == S;
-      }
-      return false;
-    });
-  };
-
-  bool TBHasEdge = true;
-  bool FBHasEdge = true;
-
-  switch (CurrentBlock->pred_size()) {
-  case 0:
-    return;
-  case 1:
-    TBHasEdge = PredHasStmt(*Preds.begin(), TrueExpr->IgnoreParenImpCasts());
-    FBHasEdge = !TBHasEdge;
-    break;
-  case 2: {
-    const auto *It = Preds.begin();
-    TBHasEdge = It->isReachable();
-    FBHasEdge = (++It)->isReachable();
-    break;
-  }
-  default:
-    llvm_unreachable("expected at most 2 predecessors");
-    return;
-  }
-
-  bool FirstFlow = true;
-  auto HandleFlow = [&](const Expr *E, bool HasAnEdge) {
-    if (!HasAnEdge)
-      return;
-    if (FirstFlow) {
-      killAndFlowOrigin(*CO, *E);
-      FirstFlow = false;
-    } else
-      flowOrigin(*CO, *E);
-  };
-  HandleFlow(TrueExpr, TBHasEdge);
-  HandleFlow(FalseExpr, FBHasEdge);
-}
-
 void FactsGenerator::VisitConditionalOperator(const ConditionalOperator *CO) {
   if (hasOrigins(CO)) {
-    handleTernaryOperator(CO);
+    const Expr *TrueExpr = CO->getTrueExpr();
+    const Expr *FalseExpr = CO->getFalseExpr();
+
+    const auto Preds = CurrentBlock->preds();
+    auto PredHasStmt = [](const CFGBlock::AdjacentBlock &Pred, const Stmt *S) {
+      return llvm::any_of(*Pred, [S](const CFGElement &Elt) {
+        if (auto CS = Elt.getAs<CFGStmt>())
+          return CS->getStmt() == S;
+        return false;
+      });
+    };
+
+    // Skip origin flow from conditional operator arms that cannot produce the
+    // result value: throw arms and calls to noreturn functions.
+    bool TBHasEdge = true;
+    bool FBHasEdge = true;
+
+    switch (CurrentBlock->pred_size()) {
+    case 0:
+      return;
+    case 1:
+      TBHasEdge = PredHasStmt(*Preds.begin(), TrueExpr->IgnoreParenImpCasts());
+      FBHasEdge = !TBHasEdge;
+      break;
+    case 2: {
+      const auto *It = Preds.begin();
+      TBHasEdge = It->isReachable();
+      FBHasEdge = (++It)->isReachable();
+      break;
+    }
+    default:
+      llvm_unreachable("expected at most 2 predecessors");
+      return;
+    }
+
+    bool FirstFlow = true;
+    auto HandleFlow = [&](const Expr *E) {
+      if (FirstFlow) {
+        killAndFlowOrigin(*CO, *E);
+        FirstFlow = false;
+      } else
+        flowOrigin(*CO, *E);
+    };
+
+    if (TBHasEdge)
+      HandleFlow(TrueExpr);
+    if (FBHasEdge)
+      HandleFlow(FalseExpr);
   }
 }
 
diff --git a/clang/test/Sema/warn-lifetime-safety.cpp 
b/clang/test/Sema/warn-lifetime-safety.cpp
index 9b867e0fe1567..46e366744c798 100644
--- a/clang/test/Sema/warn-lifetime-safety.cpp
+++ b/clang/test/Sema/warn-lifetime-safety.cpp
@@ -2418,3 +2418,58 @@ void owner_outlives_lifetimebound_source() {
 }
 
 } // namespace track_origins_for_lifetimebound_record_type
+
+namespace conditional_operator_control_flow {
+// https://github.com/llvm/llvm-project/issues/183895
+
+#ifdef __cpp_exceptions
+
+void throw_branches(bool cond, int *value) {
+  (void)(cond ? throw 1 : value);
+  (void)(cond ? throw 1 : throw 2);
+}
+
+void nested_throw_branches(bool cond, bool cond2, int *value) {
+  (void)(cond ? (cond2 ? throw 1 : value) : throw 2);
+  (void)(cond ? throw 1 : (cond2 ? value : throw 2));
+}
+
+#endif
+
+int *f(int *p [[clang::lifetimebound]]);
+[[noreturn]] int *noret_f(int *p [[clang::lifetimebound]]);
+
+
+constexpr bool kTrue = true;
+constexpr bool kFalse = false;
+
+int *constexpr_dead_false(int *num) {
+  int local = 0;
+  return kTrue ? num : f(&local);
+}
+
+int *constexpr_dead_nested(int *num) {
+  int local = 0;
+  return kTrue ? (kTrue ? num : f(&local)) : num; 
+}
+
+int *constexpr_live_false(int *num) {
+  int local = 0;
+  return kFalse ? num : f(&local); // expected-warning {{address of stack 
memory is returned later}} // expected-note {{returned here}}
+}
+
+int *constexpr_live_nested(int *num) {
+  int local = 0;
+  return kTrue ? (kFalse ? num : f(&local)) : num; // expected-warning 
{{address of stack memory is returned later}} // expected-note {{returned here}}
+}
+int *noreturn_dead_false(bool cond, int *num) {
+  int local = 0;
+  return cond ? num : noret_f(&local);
+}
+
+int *noreturn_dead_nested(bool cond, bool cond2, int *num) {
+  int local = 0;
+  return cond ? (cond2 ? num : noret_f(&local)) : num;
+}
+
+} // namespace conditional_operator_control_flow

>From 70f9fa421a74d8fc436b8ba320b90c16f5fcbc99 Mon Sep 17 00:00:00 2001
From: NeKon69 <[email protected]>
Date: Thu, 9 Apr 2026 20:34:26 +0300
Subject: [PATCH 14/16] delete old test file

---
 ...n-lifetime-safety-conditional-operator.cpp | 47 -------------------
 1 file changed, 47 deletions(-)
 delete mode 100644 
clang/test/Sema/warn-lifetime-safety-conditional-operator.cpp

diff --git a/clang/test/Sema/warn-lifetime-safety-conditional-operator.cpp 
b/clang/test/Sema/warn-lifetime-safety-conditional-operator.cpp
deleted file mode 100644
index b6800b5e39809..0000000000000
--- a/clang/test/Sema/warn-lifetime-safety-conditional-operator.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -Wlifetime-safety 
-Wno-dangling -verify %s
-
-void throw_branches(bool cond, int *value) {
-  (void)(cond ? throw 1 : value);
-  (void)(cond ? throw 1 : throw 2);
-}
-
-void nested_throw_branches(bool cond, bool cond2, int *value) {
-  (void)(cond ? (cond2 ? throw 1 : value) : throw 2);
-  (void)(cond ? throw 1 : (cond2 ? value : throw 2));
-}
-
-int *f(int *p [[clang::lifetimebound]]);
-[[noreturn]] int *noret_f(int *p [[clang::lifetimebound]]);
-
-
-constexpr bool kTrue = true;
-constexpr bool kFalse = false;
-
-int *constexpr_dead_false(int *num) {
-  int local = 0;
-  return kTrue ? num : f(&local);
-}
-
-int *constexpr_dead_nested(int *num) {
-  int local = 0;
-  return kTrue ? (kTrue ? num : f(&local)) : num;
-}
-
-int *constexpr_live_false(int *num) {
-  int local = 0;
-  return kFalse ? num : f(&local); // expected-warning {{address of stack 
memory is returned later}} // expected-note {{returned here}}
-}
-
-int *constexpr_live_nested(int *num) {
-  int local = 0;
-  return kTrue ? (kFalse ? num : f(&local)) : num; // expected-warning 
{{address of stack memory is returned later}} // expected-note {{returned here}}
-}
-int *noreturn_dead_false(bool cond, int *num) {
-  int local = 0;
-  return cond ? num : noret_f(&local);
-}
-
-int *noreturn_dead_nested(bool cond, bool cond2, int *num) {
-  int local = 0;
-  return cond ? (cond2 ? num : noret_f(&local)) : num;
-}

>From 303be90b8c21d4a555bdedd0f86f37ba16e81b50 Mon Sep 17 00:00:00 2001
From: NeKon69 <[email protected]>
Date: Thu, 9 Apr 2026 22:36:58 +0300
Subject: [PATCH 15/16] return if no origins exist, update the test with
 additional run with enabled exceptions, set PruneTriviallyFalseEdges to true.

---
 .../LifetimeSafety/FactsGenerator.cpp         | 97 ++++++++++---------
 clang/lib/Sema/AnalysisBasedWarnings.cpp      |  2 +-
 clang/test/Sema/warn-lifetime-safety.cpp      |  1 +
 3 files changed, 51 insertions(+), 49 deletions(-)

diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp 
b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
index 5a821f37e3ad4..ffe47d999736d 100644
--- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
@@ -402,56 +402,57 @@ void FactsGenerator::VisitBinaryOperator(const 
BinaryOperator *BO) {
 }
 
 void FactsGenerator::VisitConditionalOperator(const ConditionalOperator *CO) {
-  if (hasOrigins(CO)) {
-    const Expr *TrueExpr = CO->getTrueExpr();
-    const Expr *FalseExpr = CO->getFalseExpr();
-
-    const auto Preds = CurrentBlock->preds();
-    auto PredHasStmt = [](const CFGBlock::AdjacentBlock &Pred, const Stmt *S) {
-      return llvm::any_of(*Pred, [S](const CFGElement &Elt) {
-        if (auto CS = Elt.getAs<CFGStmt>())
-          return CS->getStmt() == S;
-        return false;
-      });
-    };
-
-    // Skip origin flow from conditional operator arms that cannot produce the
-    // result value: throw arms and calls to noreturn functions.
-    bool TBHasEdge = true;
-    bool FBHasEdge = true;
-
-    switch (CurrentBlock->pred_size()) {
-    case 0:
-      return;
-    case 1:
-      TBHasEdge = PredHasStmt(*Preds.begin(), TrueExpr->IgnoreParenImpCasts());
-      FBHasEdge = !TBHasEdge;
-      break;
-    case 2: {
-      const auto *It = Preds.begin();
-      TBHasEdge = It->isReachable();
-      FBHasEdge = (++It)->isReachable();
-      break;
-    }
-    default:
-      llvm_unreachable("expected at most 2 predecessors");
-      return;
-    }
+  if (!hasOrigins(CO))
+    return;
+
+  const Expr *TrueExpr = CO->getTrueExpr();
+  const Expr *FalseExpr = CO->getFalseExpr();
 
-    bool FirstFlow = true;
-    auto HandleFlow = [&](const Expr *E) {
-      if (FirstFlow) {
-        killAndFlowOrigin(*CO, *E);
-        FirstFlow = false;
-      } else
-        flowOrigin(*CO, *E);
-    };
-
-    if (TBHasEdge)
-      HandleFlow(TrueExpr);
-    if (FBHasEdge)
-      HandleFlow(FalseExpr);
+  const auto Preds = CurrentBlock->preds();
+  auto PredHasStmt = [](const CFGBlock::AdjacentBlock &Pred, const Stmt *S) {
+    return llvm::any_of(*Pred, [S](const CFGElement &Elt) {
+      if (auto CS = Elt.getAs<CFGStmt>())
+        return CS->getStmt() == S;
+      return false;
+    });
+  };
+
+  // Skip origin flow from conditional operator arms that cannot produce the
+  // result value: throw arms and calls to noreturn functions.
+  bool TBHasEdge = true;
+  bool FBHasEdge = true;
+
+  switch (CurrentBlock->pred_size()) {
+  case 0:
+    return;
+  case 1:
+    TBHasEdge = PredHasStmt(*Preds.begin(), TrueExpr->IgnoreParenImpCasts());
+    FBHasEdge = !TBHasEdge;
+    break;
+  case 2: {
+    const auto *It = Preds.begin();
+    TBHasEdge = It->isReachable();
+    FBHasEdge = (++It)->isReachable();
+    break;
+  }
+  default:
+    llvm_unreachable("expected at most 2 predecessors");
+    return;
   }
+
+  bool FirstFlow = true;
+  auto HandleFlow = [&](const Expr *E) {
+    if (FirstFlow) {
+      killAndFlowOrigin(*CO, *E);
+      FirstFlow = false;
+    } else
+      flowOrigin(*CO, *E);
+  };
+
+  if (TBHasEdge)
+    HandleFlow(TrueExpr);
+  if (FBHasEdge)
+    HandleFlow(FalseExpr);
 }
 
 void FactsGenerator::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *OCE) {
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp 
b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 37ed7488bb927..48957caf61e5a 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -2922,7 +2922,7 @@ LifetimeSafetyTUAnalysis(Sema &S, TranslationUnitDecl *TU,
     if (!FD)
       continue;
     AnalysisDeclContext AC(nullptr, FD);
-    AC.getCFGBuildOptions().PruneTriviallyFalseEdges = false;
+    AC.getCFGBuildOptions().PruneTriviallyFalseEdges = true;
     AC.getCFGBuildOptions().AddLifetime = true;
     AC.getCFGBuildOptions().AddParameterLifetimes = true;
     AC.getCFGBuildOptions().setAllAlwaysAdd();
diff --git a/clang/test/Sema/warn-lifetime-safety.cpp 
b/clang/test/Sema/warn-lifetime-safety.cpp
index 46e366744c798..b45fa2a60a2ea 100644
--- a/clang/test/Sema/warn-lifetime-safety.cpp
+++ b/clang/test/Sema/warn-lifetime-safety.cpp
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -Wlifetime-safety -Wno-dangling 
-verify=expected,function %s
 // RUN: %clang_cc1 -fsyntax-only -flifetime-safety-inference 
-fexperimental-lifetime-safety-tu-analysis -Wlifetime-safety -Wno-dangling 
-verify=expected,tu %s
+// RUN: %clang_cc1 -fsyntax-only -Wlifetime-safety -Wno-dangling 
-fcxx-exceptions -verify=expected,function,exception %s
 
 #include "Inputs/lifetime-analysis.h"
 

>From e8fa6af82bd8e2a8176af259d86180f39901b7a8 Mon Sep 17 00:00:00 2001
From: NeKon69 <[email protected]>
Date: Fri, 10 Apr 2026 19:08:47 +0300
Subject: [PATCH 16/16] address review comments

---
 .../LifetimeSafety/FactsGenerator.cpp         | 21 ++++++++++---------
 clang/test/Sema/warn-lifetime-safety.cpp      |  2 +-
 2 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp 
b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
index ffe47d999736d..9d386803ca22d 100644
--- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
@@ -409,13 +409,6 @@ void FactsGenerator::VisitConditionalOperator(const 
ConditionalOperator *CO) {
   const Expr *FalseExpr = CO->getFalseExpr();
 
   const auto Preds = CurrentBlock->preds();
-  auto PredHasStmt = [](const CFGBlock::AdjacentBlock &Pred, const Stmt *S) {
-    return llvm::any_of(*Pred, [S](const CFGElement &Elt) {
-      if (auto CS = Elt.getAs<CFGStmt>())
-        return CS->getStmt() == S;
-      return false;
-    });
-  };
 
   // Skip origin flow from conditional operator arms that cannot produce the
   // result value: throw arms and calls to noreturn functions.
@@ -425,10 +418,17 @@ void FactsGenerator::VisitConditionalOperator(const 
ConditionalOperator *CO) {
   switch (CurrentBlock->pred_size()) {
   case 0:
     return;
-  case 1:
-    TBHasEdge = PredHasStmt(*Preds.begin(), TrueExpr->IgnoreParenImpCasts());
+  case 1: {
+    TBHasEdge = llvm::any_of(**Preds.begin(),
+                             [ExpectedStmt = TrueExpr->IgnoreParenImpCasts()](
+                                 const CFGElement &Elt) {
+                               if (auto CS = Elt.getAs<CFGStmt>())
+                                 return CS->getStmt() == ExpectedStmt;
+                               return false;
+                             });
     FBHasEdge = !TBHasEdge;
     break;
+  }
   case 2: {
     const auto *It = Preds.begin();
     TBHasEdge = It->isReachable();
@@ -445,8 +445,9 @@ void FactsGenerator::VisitConditionalOperator(const 
ConditionalOperator *CO) {
     if (FirstFlow) {
       killAndFlowOrigin(*CO, *E);
       FirstFlow = false;
-    } else
+    } else {
       flowOrigin(*CO, *E);
+    }
   };
 
   if (TBHasEdge)
diff --git a/clang/test/Sema/warn-lifetime-safety.cpp 
b/clang/test/Sema/warn-lifetime-safety.cpp
index b45fa2a60a2ea..0251a1d37ee59 100644
--- a/clang/test/Sema/warn-lifetime-safety.cpp
+++ b/clang/test/Sema/warn-lifetime-safety.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -Wlifetime-safety -Wno-dangling 
-verify=expected,function %s
 // RUN: %clang_cc1 -fsyntax-only -flifetime-safety-inference 
-fexperimental-lifetime-safety-tu-analysis -Wlifetime-safety -Wno-dangling 
-verify=expected,tu %s
-// RUN: %clang_cc1 -fsyntax-only -Wlifetime-safety -Wno-dangling 
-fcxx-exceptions -verify=expected,function,exception %s
+// RUN: %clang_cc1 -fsyntax-only -Wlifetime-safety -Wno-dangling 
-fcxx-exceptions -verify=expected,function %s
 
 #include "Inputs/lifetime-analysis.h"
 

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to