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

Jordan Rose jordan_rose at apple.com
Tue Aug 21 13:52:19 PDT 2012


Author: jrose
Date: Tue Aug 21 15:52:19 2012
New Revision: 162313

URL: http://llvm.org/viewvc/llvm-project?rev=162313&view=rev
Log:
[analyzer] Push "references are non-null" knowledge up to the common parent.

This reduces duplication across the Basic and Range constraint managers, and
keeps their internals free of dealing with the semantics of C++. It's still
a little unfortunate that the constraint manager is dealing with this at all,
but this is pretty much the only place to put it so that it will apply to all
symbolic values, even when embedded in larger expressions.

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/BasicConstraintManager.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/SimpleConstraintManager.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=162313&r1=162312&r2=162313&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/BasicConstraintManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BasicConstraintManager.cpp Tue Aug 21 15:52:19 2012
@@ -363,11 +363,6 @@
 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=162313&r1=162312&r2=162313&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp Tue Aug 21 15:52:19 2012
@@ -380,17 +380,7 @@
   // given symbol type.
   BasicValueFactory &BV = getBasicVals();
   QualType T = sym->getType(BV.getContext());
-
-  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;
+  return RangeSet(F, BV.getMinValue(T), BV.getMaxValue(T));
 }
 
 //===------------------------------------------------------------------------===

Modified: cfe/trunk/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp?rev=162313&r1=162312&r2=162313&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp Tue Aug 21 15:52:19 2012
@@ -84,14 +84,9 @@
     const SubRegion *SubR = dyn_cast<SubRegion>(R);
 
     while (SubR) {
-      // FIXME: now we only find the first symbolic region.
-      if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(SubR)) {
-        const llvm::APSInt &zero = getBasicVals().getZeroWithPtrWidth();
-        if (Assumption)
-          return assumeSymNE(state, SymR->getSymbol(), zero, zero);
-        else
-          return assumeSymEQ(state, SymR->getSymbol(), zero, zero);
-      }
+      if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(SubR))
+        return assumeAuxForSymbol(state, SymR->getSymbol(), Assumption);
+
       SubR = dyn_cast<SubRegion>(SubR->getSuperRegion());
     }
 
@@ -138,10 +133,13 @@
   BasicValueFactory &BVF = getBasicVals();
   QualType T = Sym->getType(BVF.getContext());
 
-  // None of the constraint solvers currently support non-integer types.
-  if (!T->isIntegerType())
+  // Don't do anything if this isn't a type we can constrain.
+  if (!(T->isIntegralOrEnumerationType() || Loc::isLocType(T)))
     return State;
 
+  if (T->isReferenceType())
+    return Assumption ? State : NULL;
+
   const llvm::APSInt &zero = BVF.getValue(0, T);
   if (Assumption)
     return assumeSymNE(State, Sym, zero, zero);
@@ -161,8 +159,6 @@
     return assumeAuxForSymbol(state, sym, Assumption);
   }
 
-  BasicValueFactory &BasicVals = getBasicVals();
-
   switch (Cond.getSubKind()) {
   default:
     llvm_unreachable("'Assume' not implemented for this NonLoc");
@@ -185,12 +181,9 @@
 
       BinaryOperator::Opcode op = SE->getOpcode();
       // Implicitly compare non-comparison expressions to 0.
-      if (!BinaryOperator::isComparisonOp(op)) {
-        QualType T = SE->getType(BasicVals.getContext());
-        const llvm::APSInt &zero = BasicVals.getValue(0, T);
-        op = (Assumption ? BO_NE : BO_EQ);
-        return assumeSymRel(state, SE, op, zero);
-      }
+      if (!BinaryOperator::isComparisonOp(op))
+        return assumeAuxForSymbol(state, SE, Assumption);
+
       // From here on out, op is the real comparison we'll be testing.
       if (!Assumption)
         op = NegateComparison(op);
@@ -238,8 +231,25 @@
   BasicValueFactory &BVF = getBasicVals();
   ASTContext &Ctx = BVF.getContext();
 
+  // Special case for references, which cannot be null.
+  QualType Ty = LHS->getType(Ctx);
+  if (Ty->isReferenceType() && Int == 0) {
+    switch (op) {
+    case BO_EQ:
+    case BO_LE:
+    case BO_LT:
+      return NULL;
+    case BO_NE:
+    case BO_GT:
+    case BO_GE:
+      return state;
+    default:
+      llvm_unreachable("We should only be handling comparisons here.");
+    }
+  }
+
   // Get the type used for calculating wraparound.
-  APSIntType WraparoundType = BVF.getAPSIntType(LHS->getType(Ctx));
+  APSIntType WraparoundType = BVF.getAPSIntType(Ty);
 
   // We only handle simple comparisons of the form "$sym == constant"
   // or "($sym+constant1) == constant2".

Modified: cfe/trunk/test/Analysis/reference.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/reference.cpp?rev=162313&r1=162312&r2=162313&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/reference.cpp (original)
+++ cfe/trunk/test/Analysis/reference.cpp Tue Aug 21 15:52:19 2012
@@ -119,6 +119,9 @@
 
   extern S *getS();
   clang_analyzer_eval(&getS()->x != 0); // expected-warning{{TRUE}}
+
+  // This actually takes a different path, because it's not a BinaryOperator.
+  clang_analyzer_eval(&getS()->x); // expected-warning{{TRUE}}
 }
 
 





More information about the cfe-commits mailing list