Skip to content

Commit 4f69eb4

Browse files
committed
[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
1 parent df76f1e commit 4f69eb4

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

lib/StaticAnalyzer/Core/ExprEngineCXX.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,8 @@ void ExprEngine::VisitCXXDestructor(QualType ObjectType,
172172
// FIXME: We need to run the same destructor on every element of the array.
173173
// This workaround will just run the first destructor (which will still
174174
// invalidate the entire array).
175-
if (const ArrayType *AT = getContext().getAsArrayType(ObjectType)) {
175+
// This is a loop because of multidimensional arrays.
176+
while (const ArrayType *AT = getContext().getAsArrayType(ObjectType)) {
176177
ObjectType = AT->getElementType();
177178
Dest = State->getLValue(ObjectType, getSValBuilder().makeZeroArrayIndex(),
178179
loc::MemRegionVal(Dest)).getAsRegion();

test/Analysis/dtor.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,3 +301,30 @@ namespace ExplicitDestructorCall {
301301
obj->VirtualDtor::~VirtualDtor();
302302
}
303303
}
304+
305+
306+
namespace MultidimensionalArrays {
307+
void testArrayInvalidation() {
308+
int i = 42;
309+
int j = 42;
310+
311+
{
312+
IntWrapper arr[2][2];
313+
314+
// There should be no undefined value warnings here.
315+
// Eventually these should be TRUE as well, but right now
316+
// we can't handle array constructors.
317+
clang_analyzer_eval(arr[0][0].x == 0); // expected-warning{{UNKNOWN}}
318+
clang_analyzer_eval(arr[1][1].x == 0); // expected-warning{{UNKNOWN}}
319+
320+
arr[0][0].x = &i;
321+
arr[1][1].x = &j;
322+
clang_analyzer_eval(*arr[0][0].x == 42); // expected-warning{{TRUE}}
323+
clang_analyzer_eval(*arr[1][1].x == 42); // expected-warning{{TRUE}}
324+
}
325+
326+
// The destructors should have invalidated i and j.
327+
clang_analyzer_eval(i == 42); // expected-warning{{UNKNOWN}}
328+
clang_analyzer_eval(j == 42); // expected-warning{{UNKNOWN}}
329+
}
330+
}

0 commit comments

Comments
 (0)