blob: b9827df0cf71ce0f8c7b07977f9946165bc1ed77 [file] [edit]
// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
struct S {
int n;
};
struct T {
S s;
};
// &r->s is the address of a field of a symbolic region, so it is symbol-based.
// A swapped null check (`nullptr == p`) must build the same constraint as the
// usual `p == nullptr`; otherwise the analyzer contradicts itself and reports a
// null dereference that cannot happen.
int gh206798_swapped(T *r) {
S *p = &r->s;
if (!p) {
}
if (nullptr == p)
return 0;
return p->n; // no-warning: p is known non-null after the check
}
int gh206798_normal(T *r) {
S *p = &r->s;
if (!p) {
}
if (p == nullptr)
return 0;
return p->n; // no-warning: p is known non-null after the check
}
// A genuine null dereference must still be flagged in either order.
int stillReportsRealBug_swapped(S *p) {
if (nullptr == p)
return p->n; // expected-warning{{Access to field 'n' results in a dereference of a null pointer (loaded from variable 'p')}}
return 0;
}
int stillReportsRealBug_normal(S *p) {
if (p == nullptr)
return p->n; // expected-warning{{Access to field 'n' results in a dereference of a null pointer (loaded from variable 'p')}}
return 0;
}