From 42efb1c92b23e39302be6b74e2d313f00cc98650 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Fri, 7 Mar 2014 02:25:53 +0000 Subject: [PATCH] [-Wunreachable-code] Correctly expand artificial reachability to pruned '&&' and '||' branches involving configuration values. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@203194 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/CFG.cpp | 12 ++++++------ lib/Analysis/ReachableCode.cpp | 16 ++++++++++++---- test/Sema/warn-unreachable.c | 4 ++-- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index 1ed27e61cb..f11db625cd 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -1326,8 +1326,8 @@ CFGBuilder::VisitLogicalOperator(BinaryOperator *B, else { RHSBlock->setTerminator(Term); TryResult KnownVal = tryEvaluateBool(RHS); - addSuccessor(RHSBlock, KnownVal.isFalse() ? NULL : TrueBlock); - addSuccessor(RHSBlock, KnownVal.isTrue() ? NULL : FalseBlock); + addSuccessor(RHSBlock, TrueBlock, !KnownVal.isFalse()); + addSuccessor(RHSBlock, FalseBlock, !KnownVal.isTrue()); } Block = RHSBlock; @@ -1370,12 +1370,12 @@ CFGBuilder::VisitLogicalOperator(BinaryOperator *B, // Now link the LHSBlock with RHSBlock. if (B->getOpcode() == BO_LOr) { - addSuccessor(LHSBlock, KnownVal.isFalse() ? NULL : TrueBlock); - addSuccessor(LHSBlock, KnownVal.isTrue() ? NULL : RHSBlock); + addSuccessor(LHSBlock, TrueBlock, !KnownVal.isFalse()); + addSuccessor(LHSBlock, RHSBlock, !KnownVal.isTrue()); } else { assert(B->getOpcode() == BO_LAnd); - addSuccessor(LHSBlock, KnownVal.isFalse() ? NULL : RHSBlock); - addSuccessor(LHSBlock, KnownVal.isTrue() ? NULL : FalseBlock); + addSuccessor(LHSBlock, RHSBlock, !KnownVal.isFalse()); + addSuccessor(LHSBlock, FalseBlock, !KnownVal.isTrue()); } return std::make_pair(EntryLHSBlock, ExitBlock); diff --git a/lib/Analysis/ReachableCode.cpp b/lib/Analysis/ReachableCode.cpp index fa31dc1b06..09abcc9b7d 100644 --- a/lib/Analysis/ReachableCode.cpp +++ b/lib/Analysis/ReachableCode.cpp @@ -459,9 +459,13 @@ static bool isConfigurationValue(const Stmt *S) { /// Returns true if we should always explore all successors of a block. static bool shouldTreatSuccessorsAsReachable(const CFGBlock *B) { - if (const Stmt *Term = B->getTerminator()) + if (const Stmt *Term = B->getTerminator()) { if (isa(Term)) return true; + // Specially handle '||' and '&&'. + if (isa(Term)) + return isConfigurationValue(Term); + } return isConfigurationValue(B->getTerminatorCondition()); } @@ -491,9 +495,9 @@ unsigned ScanReachableFromBlock(const CFGBlock *Start, // and that we should forge ahead and explore those branches anyway. // This allows us to potentially uncover some "always unreachable" code // within the "sometimes unreachable" code. - bool TreatAllSuccessorsAsReachable = shouldTreatSuccessorsAsReachable(item); - // Look at the successors and mark then reachable. + Optional TreatAllSuccessorsAsReachable; + for (CFGBlock::const_succ_iterator I = item->succ_begin(), E = item->succ_end(); I != E; ++I) { const CFGBlock *B = *I; @@ -502,7 +506,11 @@ unsigned ScanReachableFromBlock(const CFGBlock *Start, if (!UB) break; - if (TreatAllSuccessorsAsReachable) { + if (!TreatAllSuccessorsAsReachable.hasValue()) + TreatAllSuccessorsAsReachable = + shouldTreatSuccessorsAsReachable(item); + + if (TreatAllSuccessorsAsReachable.getValue()) { B = UB; break; } diff --git a/test/Sema/warn-unreachable.c b/test/Sema/warn-unreachable.c index 4df2ec6dcc..f32134bbdb 100644 --- a/test/Sema/warn-unreachable.c +++ b/test/Sema/warn-unreachable.c @@ -275,8 +275,8 @@ int sizeof_int(int x, int y) { return 1; // no-warning if (sizeof(long) != sizeof(int)) return 0; // no-warning - if (x && y && sizeof(long) > sizeof(int)) - return 0; + if (x && y && sizeof(long) < sizeof(char)) + return 0; // no-warning return 2; // no-warning } -- 2.40.0