From 7929bf22fb161be27db8a1d1969cd29078ca2459 Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Sun, 24 Jul 2016 08:15:58 +0000 Subject: [PATCH] [analyzer] Pring LocationContext in ExplodedGraph dumps. Remove some FIXMEs in the surrounding code, which have been addressed long time ago by introducing checker-specific tags. Differential Revision: https://reviews.llvm.org/D22622 llvm-svn: 276557 --- clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 92 +++++++++++++--------------- 1 file changed, 41 insertions(+), 51 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index cda9d2f..a3c5fc4 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -2521,26 +2521,10 @@ struct DOTGraphTraits : // FIXME: Since we do not cache error nodes in ExprEngine now, this does not // work. static std::string getNodeAttributes(const ExplodedNode *N, void*) { - -#if 0 - // FIXME: Replace with a general scheme to tell if the node is - // an error node. - if (GraphPrintCheckerState->isImplicitNullDeref(N) || - GraphPrintCheckerState->isExplicitNullDeref(N) || - GraphPrintCheckerState->isUndefDeref(N) || - GraphPrintCheckerState->isUndefStore(N) || - GraphPrintCheckerState->isUndefControlFlow(N) || - GraphPrintCheckerState->isUndefResult(N) || - GraphPrintCheckerState->isBadCall(N) || - GraphPrintCheckerState->isUndefArg(N)) - return "color=\"red\",style=\"filled\""; - - if (GraphPrintCheckerState->isNoReturnCall(N)) - return "color=\"blue\",style=\"filled\""; -#endif return ""; } + // De-duplicate some source location pretty-printing. static void printLocation(raw_ostream &Out, SourceLocation SLoc) { if (SLoc.isFileID()) { Out << "\\lline=" @@ -2550,6 +2534,12 @@ struct DOTGraphTraits : << "\\l"; } } + static void printLocation2(raw_ostream &Out, SourceLocation SLoc) { + if (SLoc.isFileID() && GraphPrintSourceManager->isInMainFile(SLoc)) + Out << "line " << GraphPrintSourceManager->getExpansionLineNumber(SLoc); + else + SLoc.print(Out, *GraphPrintSourceManager); + } static std::string getNodeLabel(const ExplodedNode *N, void*){ @@ -2563,12 +2553,6 @@ struct DOTGraphTraits : case ProgramPoint::BlockEntranceKind: { Out << "Block Entrance: B" << Loc.castAs().getBlock()->getBlockID(); - if (const NamedDecl *ND = - dyn_cast(Loc.getLocationContext()->getDecl())) { - Out << " ("; - ND->printName(Out); - Out << ")"; - } break; } @@ -2693,13 +2677,6 @@ struct DOTGraphTraits : Out << "\\l"; } -#if 0 - // FIXME: Replace with a general scheme to determine - // the name of the check. - if (GraphPrintCheckerState->isUndefControlFlow(N)) { - Out << "\\|Control-flow based on\\lUndefined value.\\l"; - } -#endif break; } @@ -2721,27 +2698,6 @@ struct DOTGraphTraits : else if (Loc.getAs()) Out << "\\lPostLValue\\l"; -#if 0 - // FIXME: Replace with a general scheme to determine - // the name of the check. - if (GraphPrintCheckerState->isImplicitNullDeref(N)) - Out << "\\|Implicit-Null Dereference.\\l"; - else if (GraphPrintCheckerState->isExplicitNullDeref(N)) - Out << "\\|Explicit-Null Dereference.\\l"; - else if (GraphPrintCheckerState->isUndefDeref(N)) - Out << "\\|Dereference of undefialied value.\\l"; - else if (GraphPrintCheckerState->isUndefStore(N)) - Out << "\\|Store to Undefined Loc."; - else if (GraphPrintCheckerState->isUndefResult(N)) - Out << "\\|Result of operation is undefined."; - else if (GraphPrintCheckerState->isNoReturnCall(N)) - Out << "\\|Call to function marked \"noreturn\"."; - else if (GraphPrintCheckerState->isBadCall(N)) - Out << "\\|Call to NULL/Undefined."; - else if (GraphPrintCheckerState->isUndefArg(N)) - Out << "\\|Argument in call is undefined"; -#endif - break; } } @@ -2749,6 +2705,40 @@ struct DOTGraphTraits : ProgramStateRef state = N->getState(); Out << "\\|StateID: " << (const void*) state.get() << " NodeID: " << (const void*) N << "\\|"; + + // Analysis stack backtrace. + Out << "Location context stack (from current to outer):\\l"; + const LocationContext *LC = Loc.getLocationContext(); + unsigned Idx = 0; + for (; LC; LC = LC->getParent(), ++Idx) { + Out << Idx << ". (" << (const void *)LC << ") "; + switch (LC->getKind()) { + case LocationContext::StackFrame: + if (const NamedDecl *D = dyn_cast(LC->getDecl())) + Out << "Calling " << D->getQualifiedNameAsString(); + else + Out << "Calling anonymous code"; + if (const Stmt *S = cast(LC)->getCallSite()) { + Out << " at "; + printLocation2(Out, S->getLocStart()); + } + break; + case LocationContext::Block: + Out << "Invoking block"; + if (const Decl *D = cast(LC)->getBlockDecl()) { + Out << " defined at "; + printLocation2(Out, D->getLocStart()); + } + break; + case LocationContext::Scope: + Out << "Entering scope"; + // FIXME: Add more info once ScopeContext is activated. + break; + } + Out << "\\l"; + } + Out << "\\l"; + state->printDOT(Out); Out << "\\l"; -- 2.7.4