From dc2fdc2c413dd4cfda859ae62ee8e2baa0542ea8 Mon Sep 17 00:00:00 2001 From: Manuel Klimek Date: Thu, 7 Aug 2014 14:25:43 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@215114 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/CFG.cpp | 13 +++++++++++-- test/SemaCXX/return-noreturn.cpp | 16 ++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index 20438b4787..b9698d550b 100644 --- a/lib/Analysis/CFG.cpp +++ b/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/test/SemaCXX/return-noreturn.cpp b/test/SemaCXX/return-noreturn.cpp index bafeafcf1c..8490be9be3 100644 --- a/test/SemaCXX/return-noreturn.cpp +++ b/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}} -- 2.40.0