Fix: <rdar://problem/7275774> Static analyzer warns about NULL pointer when
                              adding assert

This fix required a few changes:

SimpleSValuator:
- Eagerly replace a symbolic value with its constant value in EvalBinOpNN
  when it is constrained to a constant.  This allows us to better constant fold
  values along a path.
- Handle trivial case of '<', '>' comparison of pointers when the two pointers
  are exactly the same.

RegionStoreManager:





git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83358 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/SimpleSValuator.cpp b/lib/Analysis/SimpleSValuator.cpp
index 52a5919..2869fab 100644
--- a/lib/Analysis/SimpleSValuator.cpp
+++ b/lib/Analysis/SimpleSValuator.cpp
@@ -29,8 +29,8 @@
 
   virtual SVal EvalMinus(NonLoc val);
   virtual SVal EvalComplement(NonLoc val);
-  virtual SVal EvalBinOpNN(BinaryOperator::Opcode op, NonLoc lhs, NonLoc rhs,
-                           QualType resultTy);
+  virtual SVal EvalBinOpNN(const GRState *state, BinaryOperator::Opcode op,
+                           NonLoc lhs, NonLoc rhs, QualType resultTy);
   virtual SVal EvalBinOpLL(BinaryOperator::Opcode op, Loc lhs, Loc rhs,
                            QualType resultTy);
   virtual SVal EvalBinOpLN(const GRState *state, BinaryOperator::Opcode op,
@@ -206,7 +206,8 @@
   return ValMgr.makeTruthVal(isEqual ? lhs == rhs : lhs != rhs, resultTy);
 }
 
-SVal SimpleSValuator::EvalBinOpNN(BinaryOperator::Opcode op,
+SVal SimpleSValuator::EvalBinOpNN(const GRState *state,
+                                  BinaryOperator::Opcode op,
                                   NonLoc lhs, NonLoc rhs,
                                   QualType resultTy)  {
   // Handle trivial case where left-side and right-side are the same.
@@ -342,8 +343,18 @@
       }
     }
     case nonloc::SymbolValKind: {
+      nonloc::SymbolVal *slhs = cast<nonloc::SymbolVal>(&lhs);
+      SymbolRef Sym = slhs->getSymbol();
+      
+      // Does the symbol simplify to a constant?
+      if (Sym->getType(ValMgr.getContext())->isIntegerType())
+        if (const llvm::APSInt *Constant = state->getSymVal(Sym)) {
+          lhs = nonloc::ConcreteInt(*Constant);
+          continue;
+        }
+      
       if (isa<nonloc::ConcreteInt>(rhs)) {
-        return ValMgr.makeNonLoc(cast<nonloc::SymbolVal>(lhs).getSymbol(), op,
+        return ValMgr.makeNonLoc(slhs->getSymbol(), op,
                                  cast<nonloc::ConcreteInt>(rhs).getValue(),
                                  resultTy);
       }
@@ -362,6 +373,13 @@
     case BinaryOperator::EQ:
     case BinaryOperator::NE:
       return EvalEquality(ValMgr, lhs, rhs, op == BinaryOperator::EQ, resultTy);
+    case BinaryOperator::LT:
+    case BinaryOperator::GT:
+      // FIXME: Generalize.  For now, just handle the trivial case where
+      //  the two locations are identical.
+      if (lhs == rhs)
+        return ValMgr.makeTruthVal(false, resultTy);
+      return UnknownVal();
   }
 }