[analyzer] Diagnostics: Supply Caller information even if the bug occurs

in the callee.

llvm-svn: 152734
This commit is contained in:
Anna Zaks 2012-03-14 18:58:28 +00:00
parent a88fdd3cdd
commit d4e9059fe0
4 changed files with 23 additions and 11 deletions

View File

@ -391,11 +391,17 @@ class PathDiagnosticCallPiece : public PathDiagnosticPiece {
: PathDiagnosticPiece(Call), Caller(callerD),
Callee(0), callReturn(callReturnPos) {}
PathDiagnosticCallPiece(PathPieces &oldPath)
: PathDiagnosticPiece(Call), Caller(0), Callee(0), path(oldPath) {}
PathDiagnosticCallPiece(PathPieces &oldPath, const Decl *caller)
: PathDiagnosticPiece(Call), Caller(caller), Callee(0),
NoExit(true), path(oldPath) {}
const Decl *Caller;
const Decl *Callee;
// Flag signifying that this diagnostic has only call enter and no matching
// call exit.
bool NoExit;
public:
PathDiagnosticLocation callEnter;
PathDiagnosticLocation callEnterWithin;
@ -429,7 +435,8 @@ public:
const CallExit &CE,
const SourceManager &SM);
static PathDiagnosticCallPiece *construct(PathPieces &pieces);
static PathDiagnosticCallPiece *construct(PathPieces &pieces,
const Decl *caller);
virtual void Profile(llvm::FoldingSetNodeID &ID) const;

View File

@ -418,8 +418,10 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
assert(!PD.getActivePath().empty());
PathDiagnosticCallPiece *C =
dyn_cast<PathDiagnosticCallPiece>(PD.getActivePath().front());
if (!C)
C = PathDiagnosticCallPiece::construct(PD.getActivePath());
if (!C) {
const Decl *Caller = CE->getLocationContext()->getDecl();
C = PathDiagnosticCallPiece::construct(PD.getActivePath(), Caller);
}
C->setCallee(*CE, SMgr);
continue;
}
@ -1064,8 +1066,10 @@ static void GenerateExtensivePathDiagnostic(PathDiagnostic& PD,
// a new PathDiagnosticCallPiece.
PathDiagnosticCallPiece *C =
dyn_cast<PathDiagnosticCallPiece>(PD.getActivePath().front());
if (!C)
C = PathDiagnosticCallPiece::construct(PD.getActivePath());
if (!C) {
const Decl * Caller = CE->getLocationContext()->getDecl();
C = PathDiagnosticCallPiece::construct(PD.getActivePath(), Caller);
}
C->setCallee(*CE, SM);
EB.addContext(CE->getCallExpr());
break;

View File

@ -515,8 +515,9 @@ PathDiagnosticCallPiece::construct(const ExplodedNode *N,
}
PathDiagnosticCallPiece *
PathDiagnosticCallPiece::construct(PathPieces &path) {
PathDiagnosticCallPiece *C = new PathDiagnosticCallPiece(path);
PathDiagnosticCallPiece::construct(PathPieces &path,
const Decl *caller) {
PathDiagnosticCallPiece *C = new PathDiagnosticCallPiece(path, caller);
path.clear();
path.push_front(C);
return C;
@ -563,7 +564,7 @@ PathDiagnosticCallPiece::getCallEnterWithinCallerEvent() const {
IntrusiveRefCntPtr<PathDiagnosticEventPiece>
PathDiagnosticCallPiece::getCallExitEvent() const {
if (!Caller)
if (NoExit)
return 0;
SmallString<256> buf;
llvm::raw_svector_ostream Out(buf);

View File

@ -281,7 +281,7 @@ void test_has_bug() {
// CHECK: </dict>
// CHECK: <key>depth</key><integer>1</integer>
// CHECK: <key>extended_message</key>
// CHECK: <string>Entered call
// CHECK: <string>Entered call from &apos;test_has_bug&apos;</string>
// CHECK: <key>message</key>
// CHECK: <string>Entered call
// CHECK: </dict>