diff options
author | Ted Kremenek <kremenek@apple.com> | 2012-02-07 00:24:33 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2012-02-07 00:24:33 +0000 |
commit | 0cf3d471546251b12bdceff360f66c079c40526c (patch) | |
tree | 93f4c72f5d847ff9cc382cd249f3bb2e85563292 /lib/StaticAnalyzer/Core/BugReporterVisitors.cpp | |
parent | 0a29422eb722c0ffbb98b98d8636042b19069f1a (diff) |
Add basic BugReporter support for CallEnter/CallExit. WIP.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@149939 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/BugReporterVisitors.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/BugReporterVisitors.cpp | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index 230e7c97eb..68ec6b0a93 100644 --- a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -726,3 +726,54 @@ ConditionBRVisitor::VisitTrueTest(const Expr *Cond, PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LC); return new PathDiagnosticEventPiece(Loc, Out.str()); } + +static PathDiagnosticLocation getLastStmtLoc(const ExplodedNode *N, + const SourceManager &SM) { + while (N) { + ProgramPoint PP = N->getLocation(); + if (const StmtPoint *SP = dyn_cast<StmtPoint>(&PP)) + return PathDiagnosticLocation(SP->getStmt(), SM, PP.getLocationContext()); + if (N->pred_empty()) + break; + N = *N->pred_begin(); + } + return PathDiagnosticLocation(); +} + +PathDiagnosticPiece * +CallEnterExitBRVisitor::VisitNode(const ExplodedNode *N, + const ExplodedNode *PrevN, + BugReporterContext &BRC, + BugReport &BR) { + ProgramPoint PP = N->getLocation(); + SmallString<256> buf; + llvm::raw_svector_ostream Out(buf); + PathDiagnosticLocation pos; + + if (const CallEnter *CEnter = dyn_cast<CallEnter>(&PP)) { + const Decl *callee = CEnter->getCalleeContext()->getDecl(); + pos = PathDiagnosticLocation(CEnter->getCallExpr(), BRC.getSourceManager(), + PP.getLocationContext()); + if (isa<BlockDecl>(callee)) + Out << "Entering call to block"; + else if (const NamedDecl *ND = dyn_cast<NamedDecl>(callee)) + Out << "Entering call to '" << ND->getNameAsString() << "'"; + } + else if (const CallExit *CExit = dyn_cast<CallExit>(&PP)) { + const Decl *caller = CExit->getLocationContext()->getParent()->getDecl(); + pos = getLastStmtLoc(PrevN, BRC.getSourceManager()); + if (const NamedDecl *ND = dyn_cast<NamedDecl>(caller)) + Out << "Returning to " << ND->getNameAsString(); + else + Out << "Returning to caller"; + } + + if (!pos.isValid()) + return 0; + + StringRef msg = Out.str(); + if (msg.empty()) + return 0; + + return new PathDiagnosticEventPiece(pos, msg); +} |