summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManuel Klimek <klimek@google.com>2014-08-07 14:25:43 +0000
committerManuel Klimek <klimek@google.com>2014-08-07 14:25:43 +0000
commit0ce91081044ecc1f0896c8157e97c95479124e11 (patch)
tree0933d1d78e3c3830238fa388cb5bf26ba653461e
parentb0ece4e07d007df7f2b6e341fbea6b2bca5a6a16 (diff)
downloadbcm5719-llvm-0ce91081044ecc1f0896c8157e97c95479124e11.tar.gz
bcm5719-llvm-0ce91081044ecc1f0896c8157e97c95479124e11.zip
Only have one path in the CFG for ternaries if the condition is known.
The return type analysis requires that the CFG is simplified when the truth values of branches are statically known at analysis time. llvm-svn: 215114
-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