From: Jordan Rose Date: Fri, 3 Aug 2012 23:08:44 +0000 (+0000) Subject: [analyzer] Provide useful PathDiagnosticLocations for CallEnter/Exit events. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7ad4848d4744b8d60289f3e359250cebdaaf7114;p=clang [analyzer] Provide useful PathDiagnosticLocations for CallEnter/Exit events. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161277 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp index bd898f27d6..c482d6796c 100644 --- a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp +++ b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp @@ -276,6 +276,44 @@ static SourceLocation getValidSourceLocation(const Stmt* S, return L; } +static PathDiagnosticLocation +getLocationForCaller(const StackFrameContext *SFC, + const LocationContext *CallerCtx, + const SourceManager &SM) { + const CFGBlock &Block = *SFC->getCallSiteBlock(); + CFGElement Source = Block[SFC->getIndex()]; + + switch (Source.getKind()) { + case CFGElement::Invalid: + llvm_unreachable("Invalid CFGElement"); + case CFGElement::Statement: + return PathDiagnosticLocation(cast(Source).getStmt(), + SM, CallerCtx); + case CFGElement::Initializer: { + const CFGInitializer &Init = cast(Source); + return PathDiagnosticLocation(Init.getInitializer()->getInit(), + SM, CallerCtx); + } + case CFGElement::AutomaticObjectDtor: { + const CFGAutomaticObjDtor &Dtor = cast(Source); + return PathDiagnosticLocation::createEnd(Dtor.getTriggerStmt(), + SM, CallerCtx); + } + case CFGElement::BaseDtor: + case CFGElement::MemberDtor: { + const AnalysisDeclContext *CallerInfo = CallerCtx->getAnalysisDeclContext(); + if (const Stmt *CallerBody = CallerInfo->getBody()) + return PathDiagnosticLocation::createEnd(CallerBody, SM, CallerCtx); + return PathDiagnosticLocation::create(CallerInfo->getDecl(), SM); + } + case CFGElement::TemporaryDtor: + llvm_unreachable("not yet implemented!"); + } + + llvm_unreachable("Unknown CFGElement kind"); +} + + PathDiagnosticLocation PathDiagnosticLocation::createBegin(const Decl *D, const SourceManager &SM) { @@ -360,6 +398,19 @@ PathDiagnosticLocation else if (const PostStmt *PS = dyn_cast(&P)) { S = PS->getStmt(); } + else if (const PostImplicitCall *PIE = dyn_cast(&P)) { + return PathDiagnosticLocation(PIE->getLocation(), SMng); + } + else if (const CallEnter *CE = dyn_cast(&P)) { + return getLocationForCaller(CE->getCalleeContext(), + CE->getLocationContext(), + SMng); + } + else if (const CallExitEnd *CEE = dyn_cast(&P)) { + return getLocationForCaller(CEE->getCalleeContext(), + CEE->getLocationContext(), + SMng); + } return PathDiagnosticLocation(S, SMng, P.getLocationContext()); } @@ -516,43 +567,6 @@ PathDiagnosticLocation PathDiagnostic::getLocation() const { // Manipulation of PathDiagnosticCallPieces. //===----------------------------------------------------------------------===// -static PathDiagnosticLocation -getLocationForCaller(const StackFrameContext *SFC, - const LocationContext *CallerCtx, - const SourceManager &SM) { - const CFGBlock &Block = *SFC->getCallSiteBlock(); - CFGElement Source = Block[SFC->getIndex()]; - - switch (Source.getKind()) { - case CFGElement::Invalid: - llvm_unreachable("Invalid CFGElement"); - case CFGElement::Statement: - return PathDiagnosticLocation(cast(Source).getStmt(), - SM, CallerCtx); - case CFGElement::Initializer: { - const CFGInitializer &Init = cast(Source); - return PathDiagnosticLocation(Init.getInitializer()->getInit(), - SM, CallerCtx); - } - case CFGElement::AutomaticObjectDtor: { - const CFGAutomaticObjDtor &Dtor = cast(Source); - return PathDiagnosticLocation::createEnd(Dtor.getTriggerStmt(), - SM, CallerCtx); - } - case CFGElement::BaseDtor: - case CFGElement::MemberDtor: { - const AnalysisDeclContext *CallerInfo = CallerCtx->getAnalysisDeclContext(); - if (const Stmt *CallerBody = CallerInfo->getBody()) - return PathDiagnosticLocation::createEnd(CallerBody, SM, CallerCtx); - return PathDiagnosticLocation::create(CallerInfo->getDecl(), SM); - } - case CFGElement::TemporaryDtor: - llvm_unreachable("not yet implemented!"); - } - - llvm_unreachable("Unknown CFGElement kind"); -} - PathDiagnosticCallPiece * PathDiagnosticCallPiece::construct(const ExplodedNode *N, const CallExitEnd &CE,