diff options
-rw-r--r-- | include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h | 7 | ||||
-rw-r--r-- | include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h | 17 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/BugReporter.cpp | 76 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/BugReporterVisitors.cpp | 26 | ||||
-rw-r--r-- | test/Analysis/conditional-operator-path-notes.c | 361 | ||||
-rw-r--r-- | test/Analysis/diagnostics/deref-track-symbolic-region.cpp | 3 | ||||
-rw-r--r-- | test/Analysis/inline-plist.c | 294 | ||||
-rw-r--r-- | test/Analysis/inlining/path-notes.c | 568 | ||||
-rw-r--r-- | test/Analysis/method-call-path-notes.cpp | 86 | ||||
-rw-r--r-- | test/Analysis/null-deref-path-notes.m | 134 | ||||
-rw-r--r-- | test/Analysis/plist-output-alternate.m | 58 | ||||
-rw-r--r-- | test/Analysis/plist-output.m | 58 | ||||
-rw-r--r-- | test/Analysis/retain-release-path-notes.m | 8833 |
13 files changed, 5117 insertions, 5404 deletions
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h index fe64f93d0d..b4592c0fc9 100644 --- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h +++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h @@ -141,6 +141,10 @@ public: void Profile(llvm::FoldingSetNodeID &ID) const; + /// Return the tag associated with this visitor. This tag will be used + /// to make all PathDiagnosticPieces created by this visitor. + static const char *getTag(); + PathDiagnosticPiece *VisitNode(const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC, @@ -170,6 +174,9 @@ public: ID.AddPointer(&x); } + /// Return the tag associated with this visitor. This tag will be used + /// to make all PathDiagnosticPieces created by this visitor. + static const char *getTag(); virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N, const ExplodedNode *Prev, diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h index bb87f808b0..6dc26e6703 100644 --- a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h +++ b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h @@ -320,6 +320,13 @@ private: const std::string str; const Kind kind; const DisplayHint Hint; + + /// A constant string that can be used to tag the PathDiagnosticPiece, + /// typically with the identification of the creator. The actual pointer + /// value is meant to be an identifier; the string itself is useful for + /// debugging. + StringRef Tag; + std::vector<SourceRange> ranges; PathDiagnosticPiece() LLVM_DELETED_FUNCTION; @@ -336,6 +343,16 @@ public: llvm::StringRef getString() const { return str; } + /// Tag this PathDiagnosticPiece with the given C-string. + void setTag(const char *tag) { Tag = tag; } + + /// Return the opaque tag (if any) on the PathDiagnosticPiece. + const void *getTag() const { return Tag.data(); } + + /// Return the string representation of the tag. This is useful + /// for debugging. + StringRef getTagStr() const { return Tag; } + /// getDisplayHint - Return a hint indicating where the diagnostic should /// be displayed by the PathDiagnosticConsumer. DisplayHint getDisplayHint() const { return Hint; } diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp index 6b94ac81a3..ed91988258 100644 --- a/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -118,6 +118,68 @@ GetCurrentOrNextStmt(const ExplodedNode *N) { // Diagnostic cleanup. //===----------------------------------------------------------------------===// +static PathDiagnosticEventPiece * +eventsDescribeSameCondition(PathDiagnosticEventPiece *X, + PathDiagnosticEventPiece *Y) { + // Prefer diagnostics that come from ConditionBRVisitor over + // those that came from TrackConstraintBRVisitor. + const void *tagPreferred = ConditionBRVisitor::getTag(); + const void *tagLesser = TrackConstraintBRVisitor::getTag(); + + if (X->getLocation() != Y->getLocation()) + return 0; + + if (X->getTag() == tagPreferred && Y->getTag() == tagLesser) + return X; + + if (Y->getTag() == tagPreferred && X->getTag() == tagLesser) + return Y; + + return 0; +} + +static void RemoveRedundantMsgs(PathPieces &path) { + unsigned N = path.size(); + if (N < 2) + return; + for (unsigned i = 0; i < N; ++i) { + IntrusiveRefCntPtr<PathDiagnosticPiece> piece(path.front()); + path.pop_front(); + + switch (piece->getKind()) { + case clang::ento::PathDiagnosticPiece::Call: + RemoveRedundantMsgs(cast<PathDiagnosticCallPiece>(piece)->path); + break; + case clang::ento::PathDiagnosticPiece::Macro: + RemoveRedundantMsgs(cast<PathDiagnosticMacroPiece>(piece)->subPieces); + break; + case clang::ento::PathDiagnosticPiece::ControlFlow: + break; + case clang::ento::PathDiagnosticPiece::Event: { + if (i == N-1) + break; + + if (PathDiagnosticEventPiece *nextEvent = + dyn_cast<PathDiagnosticEventPiece>(path.front().getPtr())) { + PathDiagnosticEventPiece *event = + cast<PathDiagnosticEventPiece>(piece); + // Check to see if we should keep one of the two pieces. If we + // come up with a preference, record which piece to keep, and consume + // another piece from the path. + if (PathDiagnosticEventPiece *pieceToKeep = + eventsDescribeSameCondition(event, nextEvent)) { + piece = pieceToKeep; + path.pop_front(); + ++i; + } + } + break; + } + } + path.push_back(piece); + } +} + /// Recursively scan through a path and prune out calls and macros pieces /// that aren't needed. Return true if afterwards the path contains /// "interesting stuff" which means it should be pruned from the parent path. @@ -2016,10 +2078,16 @@ bool GRBugReporter::generatePathDiagnostic(PathDiagnostic& PD, } while(finalReportConfigToken != originalReportConfigToken); // Finally, prune the diagnostic path of uninteresting stuff. - if (!PD.path.empty() && R->shouldPrunePath()) { - bool hasSomethingInteresting = RemoveUneededCalls(PD.getMutablePieces(), R); - assert(hasSomethingInteresting); - (void) hasSomethingInteresting; + if (!PD.path.empty()) { + // Remove messages that are basically the same. + RemoveRedundantMsgs(PD.getMutablePieces()); + + if (R->shouldPrunePath()) { + bool hasSomethingInteresting = RemoveUneededCalls(PD.getMutablePieces(), + R); + assert(hasSomethingInteresting); + (void) hasSomethingInteresting; + } } return true; diff --git a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index 00d7d3becf..213a52a9b9 100644 --- a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -467,6 +467,12 @@ void TrackConstraintBRVisitor::Profile(llvm::FoldingSetNodeID &ID) const { ID.Add(Constraint); } +/// Return the tag associated with this visitor. This tag will be used +/// to make all PathDiagnosticPieces created by this visitor. +const char *TrackConstraintBRVisitor::getTag() { + return "TrackConstraintBRVisitor"; +} + PathDiagnosticPiece * TrackConstraintBRVisitor::VisitNode(const ExplodedNode *N, const ExplodedNode *PrevN, @@ -506,7 +512,10 @@ TrackConstraintBRVisitor::VisitNode(const ExplodedNode *N, PathDiagnosticLocation::create(P, BRC.getSourceManager()); if (!L.isValid()) return NULL; - return new PathDiagnosticEventPiece(L, os.str()); + + PathDiagnosticEventPiece *X = new PathDiagnosticEventPiece(L, os.str()); + X->setTag(getTag()); + return X; } return NULL; @@ -689,14 +698,23 @@ void FindLastStoreBRVisitor::registerStatementVarDecls(BugReport &BR, //===----------------------------------------------------------------------===// // Visitor that tries to report interesting diagnostics from conditions. //===----------------------------------------------------------------------===// + +/// Return the tag associated with this visitor. This tag will be used +/// to make all PathDiagnosticPieces created by this visitor. +const char *ConditionBRVisitor::getTag() { + return "ConditionBRVisitor"; +} + PathDiagnosticPiece *ConditionBRVisitor::VisitNode(const ExplodedNode *N, const ExplodedNode *Prev, BugReporterContext &BRC, BugReport &BR) { PathDiagnosticPiece *piece = VisitNodeImpl(N, Prev, BRC, BR); - if (PathDiagnosticEventPiece *ev = - dyn_cast_or_null<PathDiagnosticEventPiece>(piece)) - ev->setPrunable(true, /* override */ false); + if (piece) { + piece->setTag(getTag()); + if (PathDiagnosticEventPiece *ev=dyn_cast<PathDiagnosticEventPiece>(piece)) + ev->setPrunable(true, /* override */ false); + } return piece; } diff --git a/test/Analysis/conditional-operator-path-notes.c b/test/Analysis/conditional-operator-path-notes.c index 5877b8f26b..de313a7f5f 100644 --- a/test/Analysis/conditional-operator-path-notes.c +++ b/test/Analysis/conditional-operator-path-notes.c @@ -1,5 +1,6 @@ // RUN: %clang --analyze %s -Xanalyzer -analyzer-output=text -Xclang -verify -// RUN: %clang --analyze %s -o - | FileCheck %s +// RUN: %clang --analyze %s -o %t +// RUN: FileCheck --input-file=%t %s void testCondOp(int *p) { int *x = p ? p : p; @@ -13,9 +14,7 @@ void testCondOp(int *p) { void testCondProblem(int *p) { if (p) return; // expected-note@-1 {{Assuming 'p' is null}} - // expected-note@-2 {{Assuming pointer value is null}} - // FIXME: The above path note is not necessary. <rdar://problem/12252783> - // expected-note@-4 {{Taking false branch}} + // expected-note@-2 {{Taking false branch}} int x = *p ? 0 : 1; // expected-warning{{Dereference of null pointer (loaded from variable 'p')}} // expected-note@-1 {{Dereference of null pointer (loaded from variable 'p')}} @@ -25,20 +24,16 @@ void testCondProblem(int *p) { void testLHSProblem(int *p) { int x = !p ? *p : 1; // expected-warning{{Dereference of null pointer (loaded from variable 'p')}} // expected-note@-1 {{Assuming 'p' is null}} - // expected-note@-2 {{Assuming pointer value is null}} - // FIXME: The above path note is not necessary. <rdar://problem/12252783> - // expected-note@-4 {{'?' condition is true}} - // expected-note@-5 {{Dereference of null pointer (loaded from variable 'p')}} + // expected-note@-2 {{'?' condition is true}} + // expected-note@-3 {{Dereference of null pointer (loaded from variable 'p')}} (void)x; } void testRHSProblem(int *p) { int x = p ? 1 : *p; // expected-warning{{Dereference of null pointer (loaded from variable 'p')}} // expected-note@-1 {{Assuming 'p' is null}} - // expected-note@-2 {{Assuming pointer value is null}} - // FIXME: The above path note is not necessary. <rdar://problem/12252783> - // expected-note@-4 {{'?' condition is false}} - // expected-note@-5 {{Dereference of null pointer (loaded from variable 'p')}} + // expected-note@-2 {{'?' condition is false}} + // expected-note@-3 {{Dereference of null pointer (loaded from variable 'p')}} (void)x; } @@ -53,9 +48,7 @@ void testBinaryCondOp(int *p) { void testBinaryLHSProblem(int *p) { if (p) return; // expected-note@-1 {{Assuming 'p' is null}} - // expected-note@-2 {{Assuming pointer value is null}} - // FIXME: The above path note is not necessary. <rdar://problem/12252783> - // expected-note@-4 {{Taking false branch}} + // expected-note@-2 {{Taking false branch}} int x = *p ?: 1; // expected-warning{{Dereference of null pointer (loaded from variable 'p')}} // expected-note@-1 {{Dereference of null pointer (loaded from variable 'p')}} @@ -75,12 +68,12 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>line</key><integer>6</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>line</key><integer>6</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -88,12 +81,12 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>line</key><integer>6</integer> // CHECK-NEXT: <key>col</key><integer>12</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>line</key><integer>6</integer> // CHECK-NEXT: <key>col</key><integer>12</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -105,7 +98,7 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>line</key><integer>6</integer> // CHECK-NEXT: <key>col</key><integer>12</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -113,12 +106,12 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>line</key><integer>6</integer> // CHECK-NEXT: <key>col</key><integer>12</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>line</key><integer>6</integer> // CHECK-NEXT: <key>col</key><integer>12</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -138,12 +131,12 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>line</key><integer>6</integer> // CHECK-NEXT: <key>col</key><integer>12</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>line</key><integer>6</integer> // CHECK-NEXT: <key>col</key><integer>12</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -151,12 +144,12 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>line</key><integer>6</integer> // CHECK-NEXT: <key>col</key><integer>20</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>line</key><integer>6</integer> // CHECK-NEXT: <key>col</key><integer>20</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -172,12 +165,12 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>line</key><integer>6</integer> // CHECK-NEXT: <key>col</key><integer>20</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>line</key><integer>6</integer> // CHECK-NEXT: <key>col</key><integer>20</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -185,12 +178,12 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>line</key><integer>6</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>line</key><integer>6</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -202,7 +195,7 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>line</key><integer>6</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -210,12 +203,12 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>line</key><integer>6</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>line</key><integer>6</integer> // CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -235,12 +228,12 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>line</key><integer>6</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>5</integer> +// CHECK-NEXT: <key>line</key><integer>6</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -248,12 +241,12 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>9</integer> +// CHECK-NEXT: <key>line</key><integer>10</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>9</integer> +// CHECK-NEXT: <key>line</key><integer>10</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -265,7 +258,7 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>9</integer> +// CHECK-NEXT: <key>line</key><integer>10</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -273,12 +266,12 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>9</integer> +// CHECK-NEXT: <key>line</key><integer>10</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>9</integer> +// CHECK-NEXT: <key>line</key><integer>10</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -299,7 +292,7 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <key>issue_hash</key><integer>5</integer> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>9</integer> +// CHECK-NEXT: <key>line</key><integer>10</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -315,12 +308,12 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>14</integer> +// CHECK-NEXT: <key>line</key><integer>15</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>14</integer> +// CHECK-NEXT: <key>line</key><integer>15</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -328,12 +321,12 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>14</integer> +// CHECK-NEXT: <key>line</key><integer>15</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>14</integer> +// CHECK-NEXT: <key>line</key><integer>15</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -345,7 +338,7 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>14</integer> +// CHECK-NEXT: <key>line</key><integer>15</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -353,12 +346,12 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>14</integer> +// CHECK-NEXT: <key>line</key><integer>15</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>14</integer> +// CHECK-NEXT: <key>line</key><integer>15</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -371,35 +364,6 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <string>Assuming 'p' is null</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>event</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>14</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <key>ranges</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>14</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>14</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </array> -// CHECK-NEXT: <key>depth</key><integer>0</integer> -// CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Assuming pointer value is null</string> -// CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Assuming pointer value is null</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> // CHECK-NEXT: <key>edges</key> // CHECK-NEXT: <array> @@ -407,12 +371,12 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>14</integer> +// CHECK-NEXT: <key>line</key><integer>15</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>14</integer> +// CHECK-NEXT: <key>line</key><integer>15</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -420,12 +384,12 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>20</integer> +// CHECK-NEXT: <key>line</key><integer>19</integer> // CHECK-NEXT: <key>col</key><integer>11</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>20</integer> +// CHECK-NEXT: <key>line</key><integer>19</integer> // CHECK-NEXT: <key>col</key><integer>11</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -437,7 +401,7 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>20</integer> +// CHECK-NEXT: <key>line</key><integer>19</integer> // CHECK-NEXT: <key>col</key><integer>11</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -445,12 +409,12 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>20</integer> +// CHECK-NEXT: <key>line</key><integer>19</integer> // CHECK-NEXT: <key>col</key><integer>12</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>20</integer> +// CHECK-NEXT: <key>line</key><integer>19</integer> // CHECK-NEXT: <key>col</key><integer>12</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -468,10 +432,10 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <key>type</key><string>Dereference of null pointer</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> // CHECK-NEXT: <key>issue_context</key><string>testCondProblem</string> -// CHECK-NEXT: <key>issue_hash</key><integer>7</integer> +// CHECK-NEXT: <key>issue_hash</key><integer>5</integer> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>20</integer> +// CHECK-NEXT: <key>line</key><integer>19</integer> // CHECK-NEXT: <key>col</key><integer>11</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -487,12 +451,12 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>26</integer> +// CHECK-NEXT: <key>line</key><integer>25</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>26</integer> +// CHECK-NEXT: <key>line</key><integer>25</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -500,12 +464,12 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>26</integer> +// CHECK-NEXT: <key>line</key><integer>25</integer> // CHECK-NEXT: <key>col</key><integer>11</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>26</integer> +// CHECK-NEXT: <key>line</key><integer>25</integer> // CHECK-NEXT: <key>col</key><integer>11</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -517,7 +481,7 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>26</integer> +// CHECK-NEXT: <key>line</key><integer>25</integer> // CHECK-NEXT: <key>col</key><integer>11</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -525,12 +489,12 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>26</integer> +// CHECK-NEXT: <key>line</key><integer>25</integer> // CHECK-NEXT: <key>col</key><integer>11</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>26</integer> +// CHECK-NEXT: <key>line</key><integer>25</integer> // CHECK-NEXT: <key>col</key><integer>12</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -543,35 +507,6 @@ void testBinaryLHSProblem(int *p) { // CHECK-NEXT: <string>Assuming 'p' is null</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>event</string> -// CHECK-NEXT: <key>location</key> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>li |