aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-12-12 19:13:44 +0000
committerJordan Rose <jordan_rose@apple.com>2012-12-12 19:13:44 +0000
commit4f69eb4daa3c5ce8b88535fc560f2ee102a580f4 (patch)
tree6c3b4396a300701f730c2613e4331ae1e88947c9
parentdf76f1ea801a60a422812b20bd0bfa6ab51cecf8 (diff)
[analyzer] Don't crash running destructors for multidimensional arrays.
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
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineCXX.cpp3
-rw-r--r--test/Analysis/dtor.cpp27
2 files changed, 29 insertions, 1 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
index b3a4a8a8fe..1f0c523ac6 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -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();
diff --git a/test/Analysis/dtor.cpp b/test/Analysis/dtor.cpp
index f46194599d..40407ea5b6 100644
--- a/test/Analysis/dtor.cpp
+++ b/test/Analysis/dtor.cpp
@@ -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}}
+ }
+}