summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-11-15 02:07:23 +0000
committerJordan Rose <jordan_rose@apple.com>2012-11-15 02:07:23 +0000
commit2d98b97e1077889f16ef1be5b3c0d801a1f7345e (patch)
treee9806ea6e46ca46b2b231c0b60804aa3881f8aff /clang/lib/StaticAnalyzer
parente0b23b5198baa1499edaf0209c164e81007c4dfe (diff)
downloadbcm5719-llvm-2d98b97e1077889f16ef1be5b3c0d801a1f7345e.tar.gz
bcm5719-llvm-2d98b97e1077889f16ef1be5b3c0d801a1f7345e.zip
[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> llvm-svn: 168019
Diffstat (limited to 'clang/lib/StaticAnalyzer')
-rw-r--r--clang/lib/StaticAnalyzer/Core/BugReporter.cpp26
-rw-r--r--clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp4
2 files changed, 20 insertions, 10 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp
index c898d65a5f9..c6689f8536d 100644
--- a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/clang/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;
diff --git a/clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
index 0f48d1e1c79..2ebadcaa238 100644
--- a/clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
+++ b/clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
@@ -790,11 +790,14 @@ PathDiagnosticCallPiece::getCallEnterEvent() const {
StringRef msg = Out.str();
if (msg.empty())
return 0;
+ assert(callEnter.asLocation().isValid());
return new PathDiagnosticEventPiece(callEnter, msg);
}
IntrusiveRefCntPtr<PathDiagnosticEventPiece>
PathDiagnosticCallPiece::getCallEnterWithinCallerEvent() const {
+ if (!callEnterWithin.asLocation().isValid())
+ return 0;
SmallString<256> buf;
llvm::raw_svector_ostream Out(buf);
if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(Caller))
@@ -819,6 +822,7 @@ PathDiagnosticCallPiece::getCallExitEvent() const {
Out << "Returning from '" << *ND << "'";
else
Out << "Returning to caller";
+ assert(callReturn.asLocation().isValid());
return new PathDiagnosticEventPiece(callReturn, Out.str());
}
OpenPOWER on IntegriCloud