]> granicus.if.org Git - clang/commitdiff
[analyzer] Use the expression’s type instead of region’s type in ArrayToPointer decay...
authorAnna Zaks <ganna@apple.com>
Tue, 28 May 2013 23:24:01 +0000 (23:24 +0000)
committerAnna Zaks <ganna@apple.com>
Tue, 28 May 2013 23:24:01 +0000 (23:24 +0000)
This gives slightly better precision, specifically, in cases where a non-typed region represents the array
or when the type is a non-array type, which can happen when an array is a result of a reinterpret_cast.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@182810 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
lib/StaticAnalyzer/Core/RegionStore.cpp
lib/StaticAnalyzer/Core/SValBuilder.cpp
test/Analysis/reference.cpp

index 42ef1db45591c5f01dfa695a86cef4165cc0400c..ed1ab8c4cb45440380c48bd36077afec2c35b752 100644 (file)
@@ -516,8 +516,8 @@ public:
 
 public:
 
-  SVal ArrayToPointer(Loc Array) {
-    return StoreMgr->ArrayToPointer(Array);
+  SVal ArrayToPointer(Loc Array, QualType ElementTy) {
+    return StoreMgr->ArrayToPointer(Array, ElementTy);
   }
 
   // Methods that manipulate the GDM.
index 230ce1ea5cf17b9f474a663c198713ce5694ec31..5b167084e253e8cf5df6599e3580a9e6f833e126 100644 (file)
@@ -111,7 +111,7 @@ public:
 
   /// ArrayToPointer - Used by ExprEngine::VistCast to handle implicit
   ///  conversions between arrays and pointers.
-  virtual SVal ArrayToPointer(Loc Array) = 0;
+  virtual SVal ArrayToPointer(Loc Array, QualType ElementTy) = 0;
 
   /// Evaluates a chain of derived-to-base casts through the path specified in
   /// \p Cast.
index 729fc009fe804199fb44945a05b599c19a2ebec1..00a6f7119042043ce3eeb9b0cd1919aac5e13900 100644 (file)
@@ -377,7 +377,7 @@ public:
   ///  version of that lvalue (i.e., a pointer to the first element of
   ///  the array).  This is called by ExprEngine when evaluating
   ///  casts from arrays to pointers.
-  SVal ArrayToPointer(Loc Array);
+  SVal ArrayToPointer(Loc Array, QualType ElementTy);
 
   StoreRef getInitialStore(const LocationContext *InitLoc) {
     return StoreRef(RBFactory.getEmptyMap().getRootWithoutRetain(), *this);
@@ -1250,26 +1250,13 @@ RegionStoreManager::getSizeInElements(ProgramStateRef state,
 ///  version of that lvalue (i.e., a pointer to the first element of
 ///  the array).  This is called by ExprEngine when evaluating casts
 ///  from arrays to pointers.
-SVal RegionStoreManager::ArrayToPointer(Loc Array) {
+SVal RegionStoreManager::ArrayToPointer(Loc Array, QualType T) {
   if (!Array.getAs<loc::MemRegionVal>())
     return UnknownVal();
 
   const MemRegion* R = Array.castAs<loc::MemRegionVal>().getRegion();
-  const TypedValueRegion* ArrayR = dyn_cast<TypedValueRegion>(R);
-
-  if (!ArrayR)
-    return UnknownVal();
-
-  // Strip off typedefs from the ArrayRegion's ValueType.
-  QualType T = ArrayR->getValueType().getDesugaredType(Ctx);
-  const ArrayType *AT = dyn_cast<ArrayType>(T);
-  if (!AT)
-    return UnknownVal();
-
-  T = AT->getElementType();
-
   NonLoc ZeroIdx = svalBuilder.makeZeroArrayIndex();
-  return loc::MemRegionVal(MRMgr.getElementRegion(T, ZeroIdx, ArrayR, Ctx));
+  return loc::MemRegionVal(MRMgr.getElementRegion(T, ZeroIdx, R, Ctx));
 }
 
 //===----------------------------------------------------------------------===//
index 9d77a3ef58fb6f2a32790578bc9428eb82955e54..ecfceaa0f3cf403a0eb26e50021cdafd7be47a4a 100644 (file)
@@ -435,9 +435,11 @@ SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) {
   }
 
   // Check for casts from array type to another type.
-  if (originalTy->isArrayType()) {
+  if (const ArrayType *arrayT =
+                      dyn_cast<ArrayType>(originalTy.getCanonicalType())) {
     // We will always decay to a pointer.
-    val = StateMgr.ArrayToPointer(val.castAs<Loc>());
+    QualType elemTy = arrayT->getElementType();
+    val = StateMgr.ArrayToPointer(val.castAs<Loc>(), elemTy);
 
     // Are we casting from an array to a pointer?  If so just pass on
     // the decayed value.
index 1dabe7bc1a3d7402c42f3d59f3a9fcf60e9ffb1d..bd5eaaa309099f1b0fcdb259e90b742ef218d9d8 100644 (file)
@@ -75,6 +75,13 @@ namespace PR13440 {
     int (&x)[1];
 
     int *m() { return x; }
+
+    void testArrayToPointerDecayWithNonTypedValueRegion() {
+      int *p = x;
+      int *q = x;
+      clang_analyzer_eval(p[0] == q[0]); // expected-warning{{TRUE}}
+    }
+
   };
 
   void test() {