summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Analysis/CFG.cpp13
-rw-r--r--clang/test/SemaCXX/return-noreturn.cpp16
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}}
OpenPOWER on IntegriCloud