[analyzer] Gain more precision retrieving the right SVal by specifying the type of the expression.
Thanks to Jordan for suggesting the fix. llvm-svn: 179732
This commit is contained in:
parent
54f4d01bd3
commit
4f59835182
|
@ -997,7 +997,13 @@ bool bugreporter::trackNullOrUndefValue(const ExplodedNode *N,
|
||||||
if (Optional<loc::MemRegionVal> L = V.getAs<loc::MemRegionVal>()) {
|
if (Optional<loc::MemRegionVal> L = V.getAs<loc::MemRegionVal>()) {
|
||||||
// At this point we are dealing with the region's LValue.
|
// At this point we are dealing with the region's LValue.
|
||||||
// However, if the rvalue is a symbolic region, we should track it as well.
|
// However, if the rvalue is a symbolic region, we should track it as well.
|
||||||
SVal RVal = state->getSVal(L->getRegion());
|
// Try to use the correct type when looking up the value.
|
||||||
|
SVal RVal;
|
||||||
|
if (const Expr *E = dyn_cast<Expr>(S))
|
||||||
|
RVal = state->getRawSVal(L.getValue(), E->getType());
|
||||||
|
else
|
||||||
|
RVal = state->getSVal(L->getRegion());
|
||||||
|
|
||||||
const MemRegion *RegionRVal = RVal.getAsRegion();
|
const MemRegion *RegionRVal = RVal.getAsRegion();
|
||||||
report.addVisitor(new UndefOrNullArgVisitor(L->getRegion()));
|
report.addVisitor(new UndefOrNullArgVisitor(L->getRegion()));
|
||||||
|
|
||||||
|
|
|
@ -133,6 +133,13 @@ void test(struct Outer *wrapperPtr) {
|
||||||
// expected-note@-1 {{Dereference of null pointer (loaded from field 'p')}}
|
// expected-note@-1 {{Dereference of null pointer (loaded from field 'p')}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test4(int **p) {
|
||||||
|
if (*p) return; // expected-note {{Taking false branch}}
|
||||||
|
// expected-note@-1 {{Assuming pointer value is null}}
|
||||||
|
**p = 1; // expected-warning {{Dereference of null pointer}}
|
||||||
|
// expected-note@-1 {{Dereference of null pointer}}
|
||||||
|
}
|
||||||
|
|
||||||
// CHECK: <key>diagnostics</key>
|
// CHECK: <key>diagnostics</key>
|
||||||
// CHECK-NEXT: <array>
|
// CHECK-NEXT: <array>
|
||||||
// CHECK-NEXT: <dict>
|
// CHECK-NEXT: <dict>
|
||||||
|
@ -3021,4 +3028,147 @@ void test(struct Outer *wrapperPtr) {
|
||||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||||
// CHECK-NEXT: </dict>
|
// CHECK-NEXT: </dict>
|
||||||
// CHECK-NEXT: </dict>
|
// CHECK-NEXT: </dict>
|
||||||
|
// CHECK-NEXT: <dict>
|
||||||
|
// CHECK-NEXT: <key>path</key>
|
||||||
|
// CHECK-NEXT: <array>
|
||||||
|
// CHECK-NEXT: <dict>
|
||||||
|
// CHECK-NEXT: <key>kind</key><string>control</string>
|
||||||
|
// CHECK-NEXT: <key>edges</key>
|
||||||
|
// CHECK-NEXT: <array>
|
||||||
|
// CHECK-NEXT: <dict>
|
||||||
|
// CHECK-NEXT: <key>start</key>
|
||||||
|
// CHECK-NEXT: <array>
|
||||||
|
// CHECK-NEXT: <dict>
|
||||||
|
// CHECK-NEXT: <key>line</key><integer>137</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>137</integer>
|
||||||
|
// CHECK-NEXT: <key>col</key><integer>4</integer>
|
||||||
|
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||||
|
// CHECK-NEXT: </dict>
|
||||||
|
// CHECK-NEXT: </array>
|
||||||
|
// CHECK-NEXT: <key>end</key>
|
||||||
|
// CHECK-NEXT: <array>
|
||||||
|
// CHECK-NEXT: <dict>
|
||||||
|
// CHECK-NEXT: <key>line</key><integer>137</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>137</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: </dict>
|
||||||
|
// CHECK-NEXT: </array>
|
||||||
|
// 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>137</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>137</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>137</integer>
|
||||||
|
// CHECK-NEXT: <key>col</key><integer>8</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>
|
||||||
|
// CHECK-NEXT: <dict>
|
||||||
|
// CHECK-NEXT: <key>start</key>
|
||||||
|
// CHECK-NEXT: <array>
|
||||||
|
// CHECK-NEXT: <dict>
|
||||||
|
// CHECK-NEXT: <key>line</key><integer>137</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>137</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: <key>end</key>
|
||||||
|
// CHECK-NEXT: <array>
|
||||||
|
// CHECK-NEXT: <dict>
|
||||||
|
// CHECK-NEXT: <key>line</key><integer>139</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>139</integer>
|
||||||
|
// CHECK-NEXT: <key>col</key><integer>3</integer>
|
||||||
|
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||||
|
// CHECK-NEXT: </dict>
|
||||||
|
// CHECK-NEXT: </array>
|
||||||
|
// CHECK-NEXT: </dict>
|
||||||
|
// CHECK-NEXT: </array>
|
||||||
|
// 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>139</integer>
|
||||||
|
// CHECK-NEXT: <key>col</key><integer>3</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>139</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>139</integer>
|
||||||
|
// CHECK-NEXT: <key>col</key><integer>9</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>Dereference of null pointer</string>
|
||||||
|
// CHECK-NEXT: <key>message</key>
|
||||||
|
// CHECK-NEXT: <string>Dereference of null pointer</string>
|
||||||
|
// CHECK-NEXT: </dict>
|
||||||
|
// CHECK-NEXT: </array>
|
||||||
|
// CHECK-NEXT: <key>description</key><string>Dereference of null pointer</string>
|
||||||
|
// CHECK-NEXT: <key>category</key><string>Logic error</string>
|
||||||
|
// 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>test4</string>
|
||||||
|
// CHECK-NEXT: <key>issue_hash</key><string>3</string>
|
||||||
|
// CHECK-NEXT: <key>location</key>
|
||||||
|
// CHECK-NEXT: <dict>
|
||||||
|
// CHECK-NEXT: <key>line</key><integer>139</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: </array>
|
// CHECK-NEXT: </array>
|
||||||
|
|
Loading…
Reference in New Issue