]> granicus.if.org Git - clang/commitdiff
[analyzer] Don't crash running destructors for multidimensional arrays.
authorJordan Rose <jordan_rose@apple.com>
Wed, 12 Dec 2012 19:13:44 +0000 (19:13 +0000)
committerJordan Rose <jordan_rose@apple.com>
Wed, 12 Dec 2012 19:13:44 +0000 (19:13 +0000)
We don't handle array destructors correctly yet, but we now apply the same
hack (explicitly destroy the first element, implicitly invalidate the rest)
for multidimensional arrays that we already use for linear arrays.

<rdar://problem/12858542>

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

lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
test/Analysis/dtor.cpp

index b3a4a8a8fe4a694320dee91f16b3948ed73a6aa0..1f0c523ac662b5e5a19f0e73af681a434fed17d7 100644 (file)
@@ -172,7 +172,8 @@ void ExprEngine::VisitCXXDestructor(QualType ObjectType,
   // FIXME: We need to run the same destructor on every element of the array.
   // This workaround will just run the first destructor (which will still
   // invalidate the entire array).
-  if (const ArrayType *AT = getContext().getAsArrayType(ObjectType)) {
+  // This is a loop because of multidimensional arrays.
+  while (const ArrayType *AT = getContext().getAsArrayType(ObjectType)) {
     ObjectType = AT->getElementType();
     Dest = State->getLValue(ObjectType, getSValBuilder().makeZeroArrayIndex(),
                             loc::MemRegionVal(Dest)).getAsRegion();
index f46194599d4ebb32bb512064c19ed499dbd106be..40407ea5b63a496157a904782c4d9e6acca82341 100644 (file)
@@ -301,3 +301,30 @@ namespace ExplicitDestructorCall {
     obj->VirtualDtor::~VirtualDtor();
   }
 }
+
+
+namespace MultidimensionalArrays {
+  void testArrayInvalidation() {
+    int i = 42;
+    int j = 42;
+
+    {
+      IntWrapper arr[2][2];
+
+      // There should be no undefined value warnings here.
+      // Eventually these should be TRUE as well, but right now
+      // we can't handle array constructors.
+      clang_analyzer_eval(arr[0][0].x == 0); // expected-warning{{UNKNOWN}}
+      clang_analyzer_eval(arr[1][1].x == 0); // expected-warning{{UNKNOWN}}
+
+      arr[0][0].x = &i;
+      arr[1][1].x = &j;
+      clang_analyzer_eval(*arr[0][0].x == 42); // expected-warning{{TRUE}}
+      clang_analyzer_eval(*arr[1][1].x == 42); // expected-warning{{TRUE}}
+    }
+
+    // The destructors should have invalidated i and j.
+    clang_analyzer_eval(i == 42); // expected-warning{{UNKNOWN}}
+    clang_analyzer_eval(j == 42); // expected-warning{{UNKNOWN}}
+  }
+}