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:

llvm-svn: 83358
diff --git a/clang/lib/Analysis/RegionStore.cpp b/clang/lib/Analysis/RegionStore.cpp
index 7a433dd..46e1d12 100644
--- a/clang/lib/Analysis/RegionStore.cpp
+++ b/clang/lib/Analysis/RegionStore.cpp
@@ -826,7 +826,10 @@
 
     // Not yet handled.
     case MemRegion::VarRegionKind:
-    case MemRegion::StringRegionKind:
+    case MemRegion::StringRegionKind: {
+      
+    }
+    // Fall-through.
     case MemRegion::CompoundLiteralRegionKind:
     case MemRegion::FieldRegionKind:
     case MemRegion::ObjCObjectRegionKind:
@@ -851,17 +854,27 @@
 
   SVal Idx = ER->getIndex();
   nonloc::ConcreteInt* Base = dyn_cast<nonloc::ConcreteInt>(&Idx);
-  nonloc::ConcreteInt* Offset = dyn_cast<nonloc::ConcreteInt>(&R);
 
-  // Only support concrete integer indexes for now.
-  if (Base && Offset) {
-    // FIXME: Should use SValuator here.
-    SVal NewIdx = Base->evalBinOp(ValMgr, Op,
+  // For now, only support:
+  //  (a) concrete integer indices that can easily be resolved
+  //  (b) 0 + symbolic index
+  if (Base) {
+    if (nonloc::ConcreteInt *Offset = dyn_cast<nonloc::ConcreteInt>(&R)) {
+      // FIXME: Should use SValuator here.
+      SVal NewIdx =
+        Base->evalBinOp(ValMgr, Op,
                 cast<nonloc::ConcreteInt>(ValMgr.convertToArrayIndex(*Offset)));
-    const MemRegion* NewER =
-      MRMgr.getElementRegion(ER->getElementType(), NewIdx, ER->getSuperRegion(),
-                             getContext());
-    return ValMgr.makeLoc(NewER);
+      const MemRegion* NewER =
+        MRMgr.getElementRegion(ER->getElementType(), NewIdx,
+                               ER->getSuperRegion(), getContext());
+      return ValMgr.makeLoc(NewER);
+    }    
+    if (0 == Base->getValue()) {
+      const MemRegion* NewER =
+        MRMgr.getElementRegion(ER->getElementType(), R,
+                               ER->getSuperRegion(), getContext());
+      return ValMgr.makeLoc(NewER);      
+    }    
   }
 
   return UnknownVal();