forked from OSchip/llvm-project
[analyzer] Improve modelling of nullptr_t in the analyzer. Fix PR25414.
Differential Revision: http://reviews.llvm.org/D15007 llvm-svn: 254718
This commit is contained in:
parent
87cd9c63df
commit
e86cb2e822
|
@ -95,6 +95,9 @@ DefinedOrUnknownSVal
|
|||
SValBuilder::getRegionValueSymbolVal(const TypedValueRegion* region) {
|
||||
QualType T = region->getValueType();
|
||||
|
||||
if (T->isNullPtrType())
|
||||
return makeZeroVal(T);
|
||||
|
||||
if (!SymbolManager::canSymbolicate(T))
|
||||
return UnknownVal();
|
||||
|
||||
|
@ -112,6 +115,9 @@ DefinedOrUnknownSVal SValBuilder::conjureSymbolVal(const void *SymbolTag,
|
|||
unsigned Count) {
|
||||
QualType T = Ex->getType();
|
||||
|
||||
if (T->isNullPtrType())
|
||||
return makeZeroVal(T);
|
||||
|
||||
// Compute the type of the result. If the expression is not an R-value, the
|
||||
// result should be a location.
|
||||
QualType ExType = Ex->getType();
|
||||
|
@ -126,6 +132,9 @@ DefinedOrUnknownSVal SValBuilder::conjureSymbolVal(const void *symbolTag,
|
|||
const LocationContext *LCtx,
|
||||
QualType type,
|
||||
unsigned count) {
|
||||
if (type->isNullPtrType())
|
||||
return makeZeroVal(type);
|
||||
|
||||
if (!SymbolManager::canSymbolicate(type))
|
||||
return UnknownVal();
|
||||
|
||||
|
@ -142,6 +151,9 @@ DefinedOrUnknownSVal SValBuilder::conjureSymbolVal(const Stmt *stmt,
|
|||
const LocationContext *LCtx,
|
||||
QualType type,
|
||||
unsigned visitCount) {
|
||||
if (type->isNullPtrType())
|
||||
return makeZeroVal(type);
|
||||
|
||||
if (!SymbolManager::canSymbolicate(type))
|
||||
return UnknownVal();
|
||||
|
||||
|
@ -160,6 +172,8 @@ SValBuilder::getConjuredHeapSymbolVal(const Expr *E,
|
|||
QualType T = E->getType();
|
||||
assert(Loc::isLocType(T));
|
||||
assert(SymbolManager::canSymbolicate(T));
|
||||
if (T->isNullPtrType())
|
||||
return makeZeroVal(T);
|
||||
|
||||
SymbolRef sym = SymMgr.conjureSymbol(E, LCtx, T, VisitCount);
|
||||
return loc::MemRegionVal(MemMgr.getSymbolicHeapRegion(sym));
|
||||
|
@ -185,6 +199,9 @@ SValBuilder::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol,
|
|||
const TypedValueRegion *region) {
|
||||
QualType T = region->getValueType();
|
||||
|
||||
if (T->isNullPtrType())
|
||||
return makeZeroVal(T);
|
||||
|
||||
if (!SymbolManager::canSymbolicate(T))
|
||||
return UnknownVal();
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
// RUN: %clang_cc1 -std=c++11 -Wno-conversion-null -analyze -analyzer-checker=core -analyzer-store region -verify %s
|
||||
// RUN: %clang_cc1 -std=c++11 -Wno-conversion-null -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store region -verify %s
|
||||
|
||||
void clang_analyzer_eval(int);
|
||||
|
||||
// test to see if nullptr is detected as a null pointer
|
||||
void foo1(void) {
|
||||
|
@ -87,3 +89,40 @@ void testMaterializeTemporaryExprWithNullPtr() {
|
|||
// Create MaterializeTemporaryExpr with a nullptr inside.
|
||||
const nullptr_t &r = nullptr;
|
||||
}
|
||||
|
||||
int getSymbol();
|
||||
|
||||
struct X {
|
||||
virtual void f() {}
|
||||
};
|
||||
|
||||
void invokeF(X* x) {
|
||||
x->f(); // expected-warning{{Called C++ object pointer is null}}
|
||||
}
|
||||
|
||||
struct Type {
|
||||
decltype(nullptr) x;
|
||||
};
|
||||
|
||||
void shouldNotCrash() {
|
||||
decltype(nullptr) p;
|
||||
if (getSymbol())
|
||||
invokeF(p); // expected-warning{{Function call argument is an uninit}}
|
||||
if (getSymbol())
|
||||
invokeF(nullptr);
|
||||
if (getSymbol()) {
|
||||
X *x = Type().x;
|
||||
x->f(); // expected-warning{{Called C++ object pointer is null}}
|
||||
}
|
||||
}
|
||||
|
||||
void f(decltype(nullptr) p) {
|
||||
int *q = nullptr;
|
||||
clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
|
||||
clang_analyzer_eval(q == 0); // expected-warning{{TRUE}}
|
||||
}
|
||||
|
||||
decltype(nullptr) returnsNullPtrType();
|
||||
void fromReturnType() {
|
||||
((X *)returnsNullPtrType())->f(); // expected-warning{{Called C++ object pointer is null}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue