diff options
| author | Ted Kremenek <kremenek@apple.com> | 2014-02-27 00:24:00 +0000 |
|---|---|---|
| committer | Ted Kremenek <kremenek@apple.com> | 2014-02-27 00:24:00 +0000 |
| commit | 4b6fee6cc4f367bf6a6728cd8ae02928a422d8ce (patch) | |
| tree | cbfb44fa698024af9f3c0a051f642ed3cecfd3dc /clang/lib/Analysis/CFG.cpp | |
| parent | 2eab2bd86d82637df6df12a3792e5f0513a88e35 (diff) | |
| download | bcm5719-llvm-4b6fee6cc4f367bf6a6728cd8ae02928a422d8ce.tar.gz bcm5719-llvm-4b6fee6cc4f367bf6a6728cd8ae02928a422d8ce.zip | |
Rework CFG edges to encode potentially unreachable edges, instead of just making them NULL.
This is to support some analyses, like -Wunreachable-code, that
will need to recover the original unprunned CFG edges in order
to suppress issues that aren't really bugs in practice.
There are two important changes here:
- AdjacentBlock replaces CFGBlock* for CFG successors/predecessors.
This has the size of 2 pointers, instead of 1. This is unlikely
to have a significant memory impact on Sema since a single
CFG usually exists at one time, but could impact the memory
usage of the static analyzer. This could possibly be optimized
down to a single pointer with some cleverness.
- Predecessors can now contain null predecessors, which means
some analyses doing a reverse traversal will need to take into
account. This already exists for successors, which contain
successor slots for specific branch kinds (e.g., 'if') that
expect a fixed number of successors, even if a branch is
not reachable.
llvm-svn: 202325
Diffstat (limited to 'clang/lib/Analysis/CFG.cpp')
| -rw-r--r-- | clang/lib/Analysis/CFG.cpp | 51 |
1 files changed, 46 insertions, 5 deletions
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index 6d12ea762db..72272c0d34f 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -483,8 +483,16 @@ private: void prependAutomaticObjDtorsWithTerminator(CFGBlock *Blk, LocalScope::const_iterator B, LocalScope::const_iterator E); - void addSuccessor(CFGBlock *B, CFGBlock *S) { - B->addSuccessor(S, cfg->getBumpVectorContext()); + void addSuccessor(CFGBlock *B, CFGBlock *S, bool IsReachable = true) { + B->addSuccessor(CFGBlock::AdjacentBlock(S, IsReachable), + cfg->getBumpVectorContext()); + } + + /// Add a reachable successor to a block, with the alternate variant that is + /// unreachable. + void addSuccessor(CFGBlock *B, CFGBlock *ReachableBlock, CFGBlock *AltBlock) { + B->addSuccessor(CFGBlock::AdjacentBlock(ReachableBlock, AltBlock), + cfg->getBumpVectorContext()); } /// Try and evaluate an expression to an integer constant. @@ -3495,13 +3503,37 @@ bool CFGImplicitDtor::isNoReturn(ASTContext &astContext) const { } //===----------------------------------------------------------------------===// -// Filtered walking of the CFG. +// CFGBlock operations. //===----------------------------------------------------------------------===// +CFGBlock::AdjacentBlock::AdjacentBlock(CFGBlock *B, bool IsReachable) + : ReachableBlock(IsReachable ? B : 0), + UnreachableBlock(!IsReachable ? B : 0, + B && IsReachable ? AB_Normal : AB_Unreachable) {} + +CFGBlock::AdjacentBlock::AdjacentBlock(CFGBlock *B, CFGBlock *AlternateBlock) + : ReachableBlock(B), + UnreachableBlock(B == AlternateBlock ? 0 : AlternateBlock, + B == AlternateBlock ? AB_Alternate : AB_Normal) {} + +void CFGBlock::addSuccessor(AdjacentBlock Succ, + BumpVectorContext &C) { + if (CFGBlock *B = Succ.getReachableBlock()) + B->Preds.push_back(CFGBlock::AdjacentBlock(this, Succ.isReachable()), C); + + if (CFGBlock *UnreachableB = Succ.getPossiblyUnreachableBlock()) + UnreachableB->Preds.push_back(CFGBlock::AdjacentBlock(this, false), C); + + Succs.push_back(Succ, C); +} + bool CFGBlock::FilterEdge(const CFGBlock::FilterOptions &F, const CFGBlock *From, const CFGBlock *To) { - if (To && F.IgnoreDefaultsWithCoveredEnums) { + if (F.IgnoreNullPredecessors && !From) + return true; + + if (To && From && F.IgnoreDefaultsWithCoveredEnums) { // If the 'To' has no label or is labeled but the label isn't a // CaseStmt then filter this edge. if (const SwitchStmt *S = @@ -3963,7 +3995,16 @@ static void print_block(raw_ostream &OS, const CFG* cfg, if (i % 10 == 8) OS << "\n "; - OS << " B" << (*I)->getBlockID(); + CFGBlock *B = *I; + bool Reachable = true; + if (!B) { + Reachable = false; + B = I->getPossiblyUnreachableBlock(); + } + + OS << " B" << B->getBlockID(); + if (!Reachable) + OS << "(Unreachable)"; } if (ShowColors) |

