diff options
author | Jordan Rose <jordan_rose@apple.com> | 2012-11-15 02:07:23 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2012-11-15 02:07:23 +0000 |
commit | 368f3b070e8cb657a65bfa443d60256676d269e7 (patch) | |
tree | b2e99b170560985c2cbd6be5df2a7eea01adf713 /lib/StaticAnalyzer/Core/BugReporter.cpp | |
parent | 350aea7b794e4824f61d92f96140fbdcc0393588 (diff) |
[analyzer] Make sure calls in synthesized functions have valid path locations.
We do this by using the "most recent" good location: if a synthesized
function 'A' calls another function 'B', the path notes for the call to 'B'
will be placed at the same location as the path note for calling 'A'.
Similarly, the call to 'A' will have a note saying "Entered call from...",
and now we just don't emit that (since the user doesn't have a body to look
at anyway).
Previously, we were doing this for the "Calling..." notes, but not for the
"Entered call from..." or "Returning to caller". This caused a crash when
the path entered and then exiting a call within a synthesized body.
<rdar://problem/12657843>
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@168019 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/BugReporter.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/BugReporter.cpp | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp index c898d65a5f..c6689f8536 100644 --- a/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -193,7 +193,7 @@ static void removeRedundantMsgs(PathPieces &path) { /// that aren't needed. Return true if afterwards the path contains /// "interesting stuff" which means it should be pruned from the parent path. bool BugReporter::RemoveUneededCalls(PathPieces &pieces, BugReport *R, - PathDiagnosticCallPiece *CallWithLoc) { + PathDiagnosticLocation *LastCallLocation) { bool containsSomethingInteresting = false; const unsigned N = pieces.size(); @@ -217,18 +217,24 @@ bool BugReporter::RemoveUneededCalls(PathPieces &pieces, BugReport *R, containsSomethingInteresting = true; break; } + + if (LastCallLocation) { + if (!call->callEnter.asLocation().isValid()) + call->callEnter = *LastCallLocation; + if (!call->callReturn.asLocation().isValid()) + call->callReturn = *LastCallLocation; + } + // Recursively clean out the subclass. Keep this call around if // it contains any informative diagnostics. - PathDiagnosticCallPiece *NewCallWithLoc = - call->getLocation().asLocation().isValid() - ? call : CallWithLoc; - - if (!RemoveUneededCalls(call->path, R, NewCallWithLoc)) - continue; + if (call->callEnterWithin.asLocation().isValid()) + LastCallLocation = &call->callEnterWithin; + else + LastCallLocation = &call->callEnter; - if (NewCallWithLoc == CallWithLoc && CallWithLoc) { - call->callEnter = CallWithLoc->callEnter; - } + assert(LastCallLocation && "Outermost call has an invalid location"); + if (!RemoveUneededCalls(call->path, R, LastCallLocation)) + continue; containsSomethingInteresting = true; break; |