return false;
}
-#if 1
-
namespace {
class VISIBILITY_HIDDEN EdgeBuilder {
std::vector<PathDiagnosticLocation> CLocs;
}
}
-
-#else
-
-static void GenExtAddEdge(PathDiagnostic& PD,
- PathDiagnosticBuilder &PDB,
- PathDiagnosticLocation NewLoc,
- PathDiagnosticLocation &PrevLoc,
- bool allowBlockJump = false) {
-
- if (const Stmt *S = NewLoc.asStmt()) {
- if (IsControlFlowExpr(S))
- return;
- }
-
-
- if (!PrevLoc.isValid()) {
- PrevLoc = NewLoc;
- return;
- }
-
- if (NewLoc == PrevLoc)
- return;
-
- // Are we jumping between statements within the same compound statement?
- if (!allowBlockJump)
- if (const Stmt *PS = PrevLoc.asStmt())
- if (const Stmt *NS = NewLoc.asStmt()) {
- const Stmt *parentPS = PDB.getParent(PS);
- if (parentPS && isa<CompoundStmt>(parentPS) &&
- parentPS == PDB.getParent(NS))
- return;
- }
-
- // Add an extra edge when jumping between contexts.
- while (1) {
- if (const Stmt *PS = PrevLoc.asStmt())
- if (const Stmt *NS = NewLoc.asStmt()) {
- PathDiagnosticLocation X = PDB.getEnclosingStmtLocation(PS);
- // FIXME: We need a version of getParent that ignores '()' and casts.
- const Stmt *parentX = PDB.getParent(X.asStmt());
-
- const PathDiagnosticLocation &Y = PDB.getEnclosingStmtLocation(NS);
- // FIXME: We need a version of getParent that ignores '()' and casts.
- const Stmt *parentY = PDB.getParent(Y.asStmt());
-
- if (parentX && IsControlFlowExpr(parentX)) {
- if (parentX == parentY)
- break;
- else {
- if (const Stmt *grandparentX = PDB.getParent(parentX)) {
- const PathDiagnosticLocation &W =
- PDB.getEnclosingStmtLocation(grandparentX);
-
- if (W != Y) X = W;
- }
- }
- }
-
- if (X != Y && PrevLoc.asLocation() != X.asLocation()) {
- PD.push_front(new PathDiagnosticControlFlowPiece(X, PrevLoc));
- PrevLoc = X;
- }
- }
- break;
- }
-
- PD.push_front(new PathDiagnosticControlFlowPiece(NewLoc, PrevLoc));
- PrevLoc = NewLoc;
-}
-
-static bool IsNestedDeclStmt(const Stmt *S, ParentMap &PM) {
- const DeclStmt *DS = dyn_cast<DeclStmt>(S);
-
- if (!DS)
- return false;
-
- const Stmt *Parent = PM.getParent(DS);
- if (!Parent)
- return false;
-
- if (const ForStmt *FS = dyn_cast<ForStmt>(Parent))
- return FS->getInit() == DS;
-
- // FIXME: In the future IfStmt/WhileStmt may contain DeclStmts in their
- // condition.
-
- return false;
-}
-
-static void GenerateExtensivePathDiagnostic(PathDiagnostic& PD,
- PathDiagnosticBuilder &PDB,
- const ExplodedNode<GRState> *N) {
-
- SourceManager& SMgr = PDB.getSourceManager();
- const ExplodedNode<GRState>* NextNode = N->pred_empty()
- ? NULL : *(N->pred_begin());
-
- PathDiagnosticLocation PrevLoc;
-
- while (NextNode) {
- N = NextNode;
- NextNode = GetPredecessorNode(N);
- ProgramPoint P = N->getLocation();
-
- // Block edges.
- if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
- const CFGBlock &Blk = *BE->getSrc();
-
- // Add a special edge for the entrance into the function/method.
- if (&Blk == &PDB.getCFG().getEntry()) {
- FullSourceLoc L = FullSourceLoc(PDB.getCodeDecl().getLocation(), SMgr);
- GenExtAddEdge(PD, PDB, L.getSpellingLoc(), PrevLoc);
- continue;
- }
-
- if (const Stmt *Term = Blk.getTerminator()) {
- const Stmt *Cond = Blk.getTerminatorCondition();
- if (!Cond || !IsControlFlowExpr(Cond)) {
- // For terminators that are control-flow expressions like '&&', '?',
- // have the condition be the anchor point for the control-flow edge
- // instead of the terminator.
- const Stmt *X = isa<Expr>(Term) ? (Cond ? Cond : Term) : Term;
- GenExtAddEdge(PD, PDB, PathDiagnosticLocation(X, SMgr), PrevLoc,true);
- continue;
- }
- }
-
- // Only handle blocks with more than 1 statement here, as the blocks
- // with one statement are handled at BlockEntrances.
- if (Blk.size() > 1) {
- const Stmt *S = *Blk.rbegin();
-
- // We don't add control-flow edges for DeclStmt's that appear in
- // the condition of if/while/for or are control-flow merge expressions.
- if (!IsControlFlowExpr(S) && !IsNestedDeclStmt(S, PDB.getParentMap())) {
- GenExtAddEdge(PD, PDB, PathDiagnosticLocation(S, SMgr), PrevLoc);
- }
- }
-
- continue;
- }
-
- if (const BlockEntrance *BE = dyn_cast<BlockEntrance>(&P)) {
- if (const Stmt* S = BE->getFirstStmt()) {
- if (!IsControlFlowExpr(S) && !IsNestedDeclStmt(S, PDB.getParentMap())) {
- if (PrevLoc.isValid()) {
- // Are we jumping within the same enclosing statement?
- if (PDB.getEnclosingStmtLocation(S) ==
- PDB.getEnclosingStmtLocation(PrevLoc))
- continue;
- }
-
- GenExtAddEdge(PD, PDB, PDB.getEnclosingStmtLocation(S), PrevLoc);
- }
- }
-
- continue;
- }
-
- PathDiagnosticPiece* p =
- PDB.getReport().VisitNode(N, NextNode, PDB.getGraph(),
- PDB.getBugReporter(), PDB.getNodeMapClosure());
-
- if (p) {
- GenExtAddEdge(PD, PDB, p->getLocation(), PrevLoc, true);
- PD.push_front(p);
- }
- }
-}
-#endif
-
//===----------------------------------------------------------------------===//
// Methods for BugType and subclasses.
//===----------------------------------------------------------------------===//