r254718 - [analyzer] Improve modelling of nullptr_t in the analyzer. Fix PR25414.

Gabor Horvath via cfe-commits cfe-commits at lists.llvm.org
Fri Dec 4 07:02:30 PST 2015


Author: xazax
Date: Fri Dec  4 09:02:30 2015
New Revision: 254718

URL: http://llvm.org/viewvc/llvm-project?rev=254718&view=rev
Log:
[analyzer] Improve modelling of nullptr_t in the analyzer. Fix PR25414.

Differential Revision: http://reviews.llvm.org/D15007

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp
    cfe/trunk/test/Analysis/nullptr.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp?rev=254718&r1=254717&r2=254718&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp Fri Dec  4 09:02:30 2015
@@ -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::conjur
                                                    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::conjur
                                                    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::conjur
                                                    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(co
   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::getDerivedRegionValueSymbol
                                              const TypedValueRegion *region) {
   QualType T = region->getValueType();
 
+  if (T->isNullPtrType())
+    return makeZeroVal(T);
+
   if (!SymbolManager::canSymbolicate(T))
     return UnknownVal();
 

Modified: cfe/trunk/test/Analysis/nullptr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/nullptr.cpp?rev=254718&r1=254717&r2=254718&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/nullptr.cpp (original)
+++ cfe/trunk/test/Analysis/nullptr.cpp Fri Dec  4 09:02:30 2015
@@ -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 testMaterializeTemporaryExprWithNul
   // 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}}
+}




More information about the cfe-commits mailing list