[cfe-commits] r162246 - in /cfe/trunk: lib/StaticAnalyzer/Core/BasicConstraintManager.cpp lib/StaticAnalyzer/Core/RangeConstraintManager.cpp test/Analysis/reference.cpp

Jordan Rose jordan_rose at apple.com
Mon Aug 20 17:27:33 PDT 2012


Author: jrose
Date: Mon Aug 20 19:27:33 2012
New Revision: 162246

URL: http://llvm.org/viewvc/llvm-project?rev=162246&view=rev
Log:
[analyzer] Assume that reference symbols are non-null.

By doing this in the constraint managers, we can ensure that ANY reference
whose value we don't know gets the effect, even if it's not a top-level
parameter.

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/BasicConstraintManager.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
    cfe/trunk/test/Analysis/reference.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/BasicConstraintManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BasicConstraintManager.cpp?rev=162246&r1=162245&r2=162246&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/BasicConstraintManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BasicConstraintManager.cpp Mon Aug 20 19:27:33 2012
@@ -363,6 +363,10 @@
 bool BasicConstraintManager::isNotEqual(ProgramStateRef state,
                                         SymbolRef sym,
                                         const llvm::APSInt& V) const {
+  // Special case: references are known to be non-zero.
+  if (sym->getType(getBasicVals().getContext())->isReferenceType())
+    if (V == 0)
+      return true;
 
   // Retrieve the NE-set associated with the given symbol.
   const ConstNotEqTy::data_type* T = state->get<ConstNotEq>(sym);

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp?rev=162246&r1=162245&r2=162246&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp Mon Aug 20 19:27:33 2012
@@ -380,7 +380,17 @@
   // given symbol type.
   BasicValueFactory &BV = getBasicVals();
   QualType T = sym->getType(BV.getContext());
-  return RangeSet(F, BV.getMinValue(T), BV.getMaxValue(T));
+
+  RangeSet Result(F, BV.getMinValue(T), BV.getMaxValue(T));
+
+  // Special case: references are known to be non-zero.
+  if (T->isReferenceType()) {
+    APSIntType IntType = BV.getAPSIntType(T);
+    Result = Result.Intersect(BV, F, ++IntType.getZeroValue(),
+                                     --IntType.getZeroValue());
+  }
+
+  return Result;
 }
 
 //===------------------------------------------------------------------------===

Modified: cfe/trunk/test/Analysis/reference.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/reference.cpp?rev=162246&r1=162245&r2=162246&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/reference.cpp (original)
+++ cfe/trunk/test/Analysis/reference.cpp Mon Aug 20 19:27:33 2012
@@ -1,3 +1,4 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core,debug.ExprInspection -analyzer-store=region -analyzer-constraints=basic -verify -Wno-null-dereference %s
 // RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core,debug.ExprInspection -analyzer-store=region -analyzer-constraints=range -verify -Wno-null-dereference %s
 
 void clang_analyzer_eval(bool);
@@ -110,6 +111,16 @@
   y = 5; // expected-warning{{Dereference of null pointer}}
 }
 
+void testReferenceAddress(int &x) {
+  clang_analyzer_eval(&x != 0); // expected-warning{{TRUE}}
+  clang_analyzer_eval(&ref() != 0); // expected-warning{{TRUE}}
+
+  struct S { int &x; };
+
+  extern S *getS();
+  clang_analyzer_eval(&getS()->x != 0); // expected-warning{{TRUE}}
+}
+
 
 // ------------------------------------
 // False negatives
@@ -127,5 +138,11 @@
     B *x = 0;
     return *x; // should warn here!
   }
+}
+
+void testReferenceFieldAddress() {
+  struct S { int &x; };
 
+  extern S getS();
+  clang_analyzer_eval(&getS().x != 0); // expected-warning{{UNKNOWN}}
 }





More information about the cfe-commits mailing list