aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Checker/PathSensitive/GRState.h11
-rw-r--r--lib/Checker/GRExprEngine.cpp20
-rw-r--r--lib/Checker/GRState.cpp6
-rw-r--r--lib/Checker/IdempotentOperationChecker.cpp4
-rw-r--r--test/Analysis/dead-stores.c2
-rw-r--r--test/Analysis/misc-ps-region-store.m10
-rw-r--r--test/Analysis/plist-output-alternate.m756
-rw-r--r--test/Analysis/plist-output.m1
8 files changed, 782 insertions, 28 deletions
diff --git a/include/clang/Checker/PathSensitive/GRState.h b/include/clang/Checker/PathSensitive/GRState.h
index d72d63ab3c..ac382898d8 100644
--- a/include/clang/Checker/PathSensitive/GRState.h
+++ b/include/clang/Checker/PathSensitive/GRState.h
@@ -270,12 +270,9 @@ public:
SVal getSValAsScalarOrLoc(const Stmt *Ex) const;
SVal getSVal(Loc LV, QualType T = QualType()) const;
-
- /// Returns a "simplified" SVal bound to the location 'LV' in the state's
- /// store. A simplified SVal will include optimizations such as
- /// if the SVal is a symbol whose value is perfectly constrained then that
- /// constant value is returned instead.
- SVal getSimplifiedSVal(Loc LV, QualType T= QualType()) const;
+
+ /// Returns the "raw" SVal bound to LV before any value simplfication.
+ SVal getRawSVal(Loc LV, QualType T= QualType()) const;
SVal getSVal(const MemRegion* R) const;
@@ -674,7 +671,7 @@ inline SVal GRState::getSValAsScalarOrLoc(const Stmt *S) const {
return UnknownVal();
}
-inline SVal GRState::getSVal(Loc LV, QualType T) const {
+inline SVal GRState::getRawSVal(Loc LV, QualType T) const {
return getStateManager().StoreMgr->Retrieve(St, LV, T);
}
diff --git a/lib/Checker/GRExprEngine.cpp b/lib/Checker/GRExprEngine.cpp
index c11785a711..733aebb44d 100644
--- a/lib/Checker/GRExprEngine.cpp
+++ b/lib/Checker/GRExprEngine.cpp
@@ -1876,7 +1876,7 @@ void GRExprEngine::EvalBind(ExplodedNodeSet& Dst, const Stmt* StoreE,
// is non-NULL. Checkers typically care about
GRStmtNodeBuilderRef BuilderRef(Dst, *Builder, *this, *I, newState, StoreE,
- newState != state);
+ true);
getTF().EvalBind(BuilderRef, location, Val);
}
@@ -1970,16 +1970,18 @@ void GRExprEngine::EvalLoadCommon(ExplodedNodeSet& Dst, const Expr *Ex,
// Proceed with the load.
for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI) {
state = GetState(*NI);
+
if (location.isUnknown()) {
// This is important. We must nuke the old binding.
MakeNode(Dst, Ex, *NI, state->BindExpr(Ex, UnknownVal()),
ProgramPoint::PostLoadKind, tag);
}
else {
- SVal V = state->getSVal(cast<Loc>(location), LoadTy.isNull() ?
- Ex->getType() : LoadTy);
- MakeNode(Dst, Ex, *NI, state->BindExpr(Ex, V), ProgramPoint::PostLoadKind,
- tag);
+ if (LoadTy.isNull())
+ LoadTy = Ex->getType();
+ SVal V = state->getSVal(cast<Loc>(location), LoadTy);
+ MakeNode(Dst, Ex, *NI, state->bindExprAndLocation(Ex, location, V),
+ ProgramPoint::PostLoadKind, tag);
}
}
}
@@ -3384,13 +3386,7 @@ void GRExprEngine::VisitBinaryOperator(const BinaryOperator* B,
SVal Result = EvalBinOp(state, Op, LeftV, RightV, B->getType());
if (Result.isUnknown()) {
- if (OldSt != state) {
- // Generate a new node if we have already created a new state.
- MakeNode(Tmp3, B, *I2, state);
- }
- else
- Tmp3.Add(*I2);
-
+ MakeNode(Tmp3, B, *I2, state);
continue;
}
diff --git a/lib/Checker/GRState.cpp b/lib/Checker/GRState.cpp
index d38ae21fce..dbbcb39aa0 100644
--- a/lib/Checker/GRState.cpp
+++ b/lib/Checker/GRState.cpp
@@ -169,9 +169,9 @@ SVal GRState::getSValAsScalarOrLoc(const MemRegion *R) const {
return UnknownVal();
}
-SVal GRState::getSimplifiedSVal(Loc location, QualType T) const {
- SVal V = getSVal(cast<Loc>(location), T);
-
+SVal GRState::getSVal(Loc location, QualType T) const {
+ SVal V = getRawSVal(cast<Loc>(location), T);
+
// If 'V' is a symbolic value that is *perfectly* constrained to
// be a constant value, use that value instead to lessen the burden
// on later analysis stages (so we have less symbolic values to reason
diff --git a/lib/Checker/IdempotentOperationChecker.cpp b/lib/Checker/IdempotentOperationChecker.cpp
index 3d454bed9a..3dcbea491e 100644
--- a/lib/Checker/IdempotentOperationChecker.cpp
+++ b/lib/Checker/IdempotentOperationChecker.cpp
@@ -200,7 +200,7 @@ void IdempotentOperationChecker::PreVisitBinaryOperator(
A = Impossible;
return;
}
- LHSVal = state->getSVal(cast<Loc>(LHSVal));
+ LHSVal = state->getSVal(cast<Loc>(LHSVal), LHS->getType());
}
@@ -355,6 +355,8 @@ void IdempotentOperationChecker::PostVisitBinaryOperator(
const BinaryOperator *B) {
// Add the ExplodedNode we just visited
BinaryOperatorData &Data = hash[B];
+ assert(isa<BinaryOperator>(cast<StmtPoint>(C.getPredecessor()
+ ->getLocation()).getStmt()));
Data.explodedNodes.Add(C.getPredecessor());
}
diff --git a/test/Analysis/dead-stores.c b/test/Analysis/dead-stores.c
index da131a2982..c150fa088d 100644
--- a/test/Analysis/dead-stores.c
+++ b/test/Analysis/dead-stores.c
@@ -150,7 +150,7 @@ void f15(unsigned x, unsigned y) {
int f16(int x) {
x = x * 2;
- x = sizeof(int [x = (x || x + 1) * 2]) // expected-warning{{Although the value stored to 'x' is used}} expected-warning{{The left operand to '*' is always 1}}
+ x = sizeof(int [x = (x || x + 1) * 2]) // expected-warning{{Although the value stored to 'x' is used}} expected-warning{{The left operand to '*' is always 1}} expected-warning{{The left operand to '+' is always 0}}
? 5 : 8;
return x;
}
diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m
index a4e0d0bfa6..27aaff09e2 100644
--- a/test/Analysis/misc-ps-region-store.m
+++ b/test/Analysis/misc-ps-region-store.m
@@ -1103,16 +1103,18 @@ void pr8015_C() {
}
}
-// FIXME: This is a false positive due to not reasoning about symbolic
-// array indices correctly. Discussion in PR 8015.
+// Tests that we correctly handle that 'number' is perfectly constrained
+// after 'if (nunber == 0)', allowing us to resolve that
+// numbers[number] == numbers[0].
void pr8015_D_FIXME() {
int number = pr8015_A();
const char *numbers[] = { "zero" };
if (number == 0) {
- if (numbers[number] == numbers[0])
+ if (numbers[number] == numbers[0]) // expected-warning{{Both operands to '==' always have the same value}}
return;
+ // Unreachable.
int *p = 0;
- *p = 0xDEADBEEF; // expected-warning{{Dereference of null pointer}}
+ *p = 0xDEADBEEF; // no-warnng
}
}
diff --git a/test/Analysis/plist-output-alternate.m b/test/Analysis/plist-output-alternate.m
new file mode 100644
index 0000000000..ad9f89fcd1
--- /dev/null
+++ b/test/Analysis/plist-output-alternate.m
@@ -0,0 +1,756 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-output=plist -o - %s | FileCheck %s
+
+void test_null_init(void) {
+ int *p = 0;
+ *p = 0xDEADBEEF;
+}
+
+void test_null_assign(void) {
+ int *p;
+ p = 0;
+ *p = 0xDEADBEEF;
+}
+
+void test_null_assign_transitive(void) {
+ int *p;
+ p = 0;
+ int *q = p;
+ *q = 0xDEADBEEF;
+}
+
+void test_null_cond(int *p) {
+ if (!p) {
+ *p = 0xDEADBEEF;
+ }
+}
+
+void test_null_cond_transitive(int *q) {
+ if (!q) {
+ int *p = q;
+ *p = 0xDEADBEEF;
+ }
+}
+
+void test_null_field(void) {
+ struct s { int *p; } x;
+ x.p = 0;
+ *(x.p) = 0xDEADBEEF;
+}
+
+// CHECK: <?xml version="1.0" encoding="UTF-8"?>
+// CHECK: <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+// CHECK: <plist version="1.0">
+// CHECK: <dict>
+// CHECK: <key>files</key>
+// CHECK: <array>
+// CHECK: </array>
+// CHECK: <key>diagnostics</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>path</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>event</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>4</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <key>ranges</key>
+// CHECK: <array>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>4</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>4</integer>
+// CHECK: <key>col</key><integer>8</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </array>
+// CHECK: <key>extended_message</key>
+// CHECK: <string>Variable &apos;p&apos; initialized to a null pointer value</string>
+// CHECK: <key>message</key>
+// CHECK: <string>Variable &apos;p&apos; initialized to a null pointer value</string>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>control</string>
+// CHECK: <key>edges</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>start</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>4</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>4</integer>
+// CHECK: <key>col</key><integer>8</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>end</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>5</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>5</integer>
+// CHECK: <key>col</key><integer>4</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>event</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>5</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <key>ranges</key>
+// CHECK: <array>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>5</integer>
+// CHECK: <key>col</key><integer>4</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>5</integer>
+// CHECK: <key>col</key><integer>4</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </array>
+// CHECK: <key>extended_message</key>
+// CHECK: <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK: <key>message</key>
+// CHECK: <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>description</key><string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK: <key>category</key><string>Logic error</string>
+// CHECK: <key>type</key><string>Dereference of null pointer</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>5</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>path</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>control</string>
+// CHECK: <key>edges</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>start</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>9</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>9</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>end</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>10</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>10</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>event</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>10</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <key>ranges</key>
+// CHECK: <array>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>10</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>10</integer>
+// CHECK: <key>col</key><integer>7</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </array>
+// CHECK: <key>extended_message</key>
+// CHECK: <string>Null pointer value stored to &apos;p&apos;</string>
+// CHECK: <key>message</key>
+// CHECK: <string>Null pointer value stored to &apos;p&apos;</string>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>control</string>
+// CHECK: <key>edges</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>start</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>10</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>10</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>end</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>11</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>11</integer>
+// CHECK: <key>col</key><integer>4</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>event</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>11</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <key>ranges</key>
+// CHECK: <array>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>11</integer>
+// CHECK: <key>col</key><integer>4</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>11</integer>
+// CHECK: <key>col</key><integer>4</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </array>
+// CHECK: <key>extended_message</key>
+// CHECK: <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK: <key>message</key>
+// CHECK: <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>description</key><string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK: <key>category</key><string>Logic error</string>
+// CHECK: <key>type</key><string>Dereference of null pointer</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>11</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>path</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>control</string>
+// CHECK: <key>edges</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>start</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>15</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>15</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>end</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>17</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>17</integer>
+// CHECK: <key>col</key><integer>8</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>event</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>17</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <key>ranges</key>
+// CHECK: <array>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>17</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>17</integer>
+// CHECK: <key>col</key><integer>8</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </array>
+// CHECK: <key>extended_message</key>
+// CHECK: <string>Variable &apos;q&apos; initialized to a null pointer value</string>
+// CHECK: <key>message</key>
+// CHECK: <string>Variable &apos;q&apos; initialized to a null pointer value</string>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>control</string>
+// CHECK: <key>edges</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>start</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>17</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>17</integer>
+// CHECK: <key>col</key><integer>8</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>end</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>18</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>18</integer>
+// CHECK: <key>col</key><integer>4</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>event</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>18</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <key>ranges</key>
+// CHECK: <array>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>18</integer>
+// CHECK: <key>col</key><integer>4</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>18</integer>
+// CHECK: <key>col</key><integer>4</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </array>
+// CHECK: <key>extended_message</key>
+// CHECK: <string>Dereference of null pointer (loaded from variable &apos;q&apos;)</string>
+// CHECK: <key>message</key>
+// CHECK: <string>Dereference of null pointer (loaded from variable &apos;q&apos;)</string>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>description</key><string>Dereference of null pointer (loaded from variable &apos;q&apos;)</string>
+// CHECK: <key>category</key><string>Logic error</string>
+// CHECK: <key>type</key><string>Dereference of null pointer</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>18</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>path</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>control</string>
+// CHECK: <key>edges</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>start</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>22</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>22</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>end</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>23</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>23</integer>
+// CHECK: <key>col</key><integer>6</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>event</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>23</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <key>ranges</key>
+// CHECK: <array>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>23</integer>
+// CHECK: <key>col</key><integer>6</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>23</integer>
+// CHECK: <key>col</key><integer>6</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </array>
+// CHECK: <key>extended_message</key>
+// CHECK: <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK: <key>message</key>
+// CHECK: <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>description</key><string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK: <key>category</key><string>Logic error</string>
+// CHECK: <key>type</key><string>Dereference of null pointer</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>23</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>path</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>control</string>
+// CHECK: <key>edges</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>start</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>28</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>28</integer>
+// CHECK: <key>col</key><integer>3</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>end</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>29</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>29</integer>
+// CHECK: <key>col</key><integer>10</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>event</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>29</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <key>ranges</key>
+// CHECK: <array>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>29</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>29</integer>
+// CHECK: <key>col</key><integer>10</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </array>
+// CHECK: <key>extended_message</key>
+// CHECK: <string>Variable &apos;p&apos; initialized to a null pointer value</string>
+// CHECK: <key>message</key>
+// CHECK: <string>Variable &apos;p&apos; initialized to a null pointer value</string>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>control</string>
+// CHECK: <key>edges</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>start</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>29</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>29</integer>
+// CHECK: <key>col</key><integer>10</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>end</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>30</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>30</integer>
+// CHECK: <key>col</key><integer>6</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>event</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>30</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <key>ranges</key>
+// CHECK: <array>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>30</integer>
+// CHECK: <key>col</key><integer>6</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>30</integer>
+// CHECK: <key>co