diff options
author | David Majnemer <david.majnemer@gmail.com> | 2013-06-04 17:38:44 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2013-06-04 17:38:44 +0000 |
commit | f69ce860487ec0b1eceb23f8391614d5772aae3b (patch) | |
tree | d6ac45b5978f12878f0ad4741560a5dacbb93743 /clang/lib/Analysis/CFG.cpp | |
parent | 33a35dff8305e01d15fbf881f500ac7ad1b020f1 (diff) | |
download | bcm5719-llvm-f69ce860487ec0b1eceb23f8391614d5772aae3b.tar.gz bcm5719-llvm-f69ce860487ec0b1eceb23f8391614d5772aae3b.zip |
Analysis: Add a CFG successor to a SwitchStmt if it is both empty and fully covered
Consider the case where a SwitchStmt satisfied isAllEnumCasesCovered()
as well as having no cases at all (i.e. the enum it covers has no
enumerators).
In this case, we should add a successor to repair the CFG.
This fixes PR16212.
llvm-svn: 183237
Diffstat (limited to 'clang/lib/Analysis/CFG.cpp')
-rw-r--r-- | clang/lib/Analysis/CFG.cpp | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index e06e6617508..9945dcb36ce 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -2671,9 +2671,15 @@ CFGBlock *CFGBuilder::VisitSwitchStmt(SwitchStmt *Terminator) { // If we have no "default:" case, the default transition is to the code // following the switch body. Moreover, take into account if all the // cases of a switch are covered (e.g., switching on an enum value). + // + // Note: We add a successor to a switch that is considered covered yet has no + // case statements if the enumeration has no enumerators. + bool SwitchAlwaysHasSuccessor = false; + SwitchAlwaysHasSuccessor |= switchExclusivelyCovered; + SwitchAlwaysHasSuccessor |= Terminator->isAllEnumCasesCovered() && + Terminator->getSwitchCaseList(); addSuccessor(SwitchTerminatedBlock, - switchExclusivelyCovered || Terminator->isAllEnumCasesCovered() - ? 0 : DefaultCaseBlock); + SwitchAlwaysHasSuccessor ? 0 : DefaultCaseBlock); // Add the terminator and condition in the switch block. SwitchTerminatedBlock->setTerminator(Terminator); |