summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/StaticAnalyzer/Core/SValBuilder.cpp17
-rw-r--r--clang/test/Analysis/nullptr.cpp41
2 files changed, 57 insertions, 1 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
index 98fac33c22a..cdae04068e1 100644
--- a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
+++ b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
@@ -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();
diff --git a/clang/test/Analysis/nullptr.cpp b/clang/test/Analysis/nullptr.cpp
index 56151dc6b65..17320f3b9a8 100644
--- a/clang/test/Analysis/nullptr.cpp
+++ b/clang/test/Analysis/nullptr.cpp
@@ -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}}
+}
OpenPOWER on IntegriCloud