- Allow making ElementRegions with complex offsets (expressions or symbols) for the purpose of bounds-checking.
- Rewrite GRState::AssumeInBound to actually do that checking, and to use the normal constraint path.
- Remove ConstraintManager::AssumeInBound.
- Teach RegionStore and FlatStore to ignore those regions for now.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111116 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Checker/Store.cpp b/lib/Checker/Store.cpp
index e0e2c3a..7c80eed 100644
--- a/lib/Checker/Store.cpp
+++ b/lib/Checker/Store.cpp
@@ -284,10 +284,6 @@
   if (Base.isUnknownOrUndef() || isa<loc::ConcreteInt>(Base))
     return Base;
 
-  // Only handle integer offsets... for now.
-  if (!isa<nonloc::ConcreteInt>(Offset))
-    return UnknownVal();
-
   const MemRegion* BaseRegion = cast<loc::MemRegionVal>(Base).getRegion();
 
   // Pointer of any type can be cast and used as array base.
@@ -316,6 +312,19 @@
     return UnknownVal();
 
   const llvm::APSInt& BaseIdxI = cast<nonloc::ConcreteInt>(BaseIdx).getValue();
+
+  // Only allow non-integer offsets if the base region has no offset itself.
+  // FIXME: This is a somewhat arbitrary restriction. We should be using
+  // SValuator here to add the two offsets without checking their types.
+  if (!isa<nonloc::ConcreteInt>(Offset)) {
+    if (isa<ElementRegion>(BaseRegion->StripCasts()))
+      return UnknownVal();
+
+    return loc::MemRegionVal(MRMgr.getElementRegion(elementType, Offset,
+                                                    ElemR->getSuperRegion(),
+                                                    Ctx));
+  }
+
   const llvm::APSInt& OffI = cast<nonloc::ConcreteInt>(Offset).getValue();
   assert(BaseIdxI.isSigned());