diff --git a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp index b3a4a8a8fe4a694320dee91f16b3948ed73a6aa0..1f0c523ac662b5e5a19f0e73af681a434fed17d7 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 f46194599d4ebb32bb512064c19ed499dbd106be..40407ea5b63a496157a904782c4d9e6acca82341 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}} + } +}