diff options
Diffstat (limited to 'lib/StaticAnalyzer/Core/PathDiagnostic.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/PathDiagnostic.cpp | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp index 3306eaa7f8..394e975d4e 100644 --- a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp +++ b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp @@ -253,16 +253,33 @@ static SourceLocation getValidSourceLocation(const Stmt* S, // source code, so find an enclosing statement and use its location. if (!L.isValid()) { - ParentMap *PM = 0; + AnalysisDeclContext *ADC; if (LAC.is<const LocationContext*>()) - PM = &LAC.get<const LocationContext*>()->getParentMap(); + ADC = LAC.get<const LocationContext*>()->getAnalysisDeclContext(); else - PM = &LAC.get<AnalysisDeclContext*>()->getParentMap(); + ADC = LAC.get<AnalysisDeclContext*>(); + + ParentMap &PM = ADC->getParentMap(); + + const Stmt *Parent = S; + do { + Parent = PM.getParent(Parent); + + // In rare cases, we have implicit top-level expressions, + // such as arguments for implicit member initializers. + // In this case, fall back to the start of the body (even if we were + // asked for the statement end location). + if (!Parent) { + const Stmt *Body = ADC->getBody(); + if (Body) + L = Body->getLocStart(); + else + L = ADC->getDecl()->getLocEnd(); + break; + } - while (!L.isValid()) { - S = PM->getParent(S); - L = UseEnd ? S->getLocEnd() : S->getLocStart(); - } + L = UseEnd ? Parent->getLocEnd() : Parent->getLocStart(); + } while (!L.isValid()); } return L; |