diff options
-rw-r--r-- | clang/lib/Analysis/CFG.cpp | 13 | ||||
-rw-r--r-- | clang/test/SemaCXX/return-noreturn.cpp | 16 |
2 files changed, 27 insertions, 2 deletions
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index 20438b47877..b9698d550bf 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -3711,15 +3711,24 @@ CFGBlock *CFGBuilder::VisitConditionalOperatorForTemporaryDtors( VisitForTemporaryDtors(E->getCond(), false, Context); CFGBlock *ConditionBlock = Block; CFGBlock *ConditionSucc = Succ; + TryResult ConditionVal = tryEvaluateBool(E->getCond()); TempDtorContext TrueContext(/*IsConditional=*/true); - VisitForTemporaryDtors(E->getTrueExpr(), BindToTemporary, TrueContext); + if (!ConditionVal.isFalse()) { + VisitForTemporaryDtors(E->getTrueExpr(), BindToTemporary, TrueContext); + if (ConditionVal.isTrue()) + return Block; + } CFGBlock *TrueBlock = Block; Block = ConditionBlock; Succ = ConditionSucc; TempDtorContext FalseContext(/*IsConditional=*/true); - VisitForTemporaryDtors(E->getFalseExpr(), BindToTemporary, FalseContext); + if (!ConditionVal.isTrue()) { + VisitForTemporaryDtors(E->getFalseExpr(), BindToTemporary, FalseContext); + if (ConditionVal.isFalse()) + return Block; + } if (TrueContext.TerminatorExpr && FalseContext.TerminatorExpr) { InsertTempDtorDecisionBlock(FalseContext, TrueBlock); diff --git a/clang/test/SemaCXX/return-noreturn.cpp b/clang/test/SemaCXX/return-noreturn.cpp index bafeafcf1cf..8490be9be38 100644 --- a/clang/test/SemaCXX/return-noreturn.cpp +++ b/clang/test/SemaCXX/return-noreturn.cpp @@ -159,6 +159,22 @@ int testTernaryUnconditionalNoreturn() { true ? NoReturn() : NoReturn(); } +int testTernaryStaticallyConditionalNoretrunOnTrue() { + true ? NoReturn() : Return(); +} + +int testTernaryStaticallyConditionalRetrunOnTrue() { + true ? Return() : NoReturn(); +} // expected-warning {{control reaches end of non-void function}} + +int testTernaryStaticallyConditionalNoretrunOnFalse() { + false ? Return() : NoReturn(); +} + +int testTernaryStaticallyConditionalRetrunOnFalse() { + false ? NoReturn() : Return(); +} // expected-warning {{control reaches end of non-void function}} + int testTernaryConditionalNoreturnTrueBranch(bool value) { value ? (NoReturn() || NoReturn()) : Return(); } // expected-warning {{control may reach end of non-void function}} |