This revision was not accepted when it landed; it landed in state "Needs Review". This revision was automatically updated to reflect the committed changes. Closed by commit rL331014: [analyzer] Fix operator delete[] array-type-sub-expression handling. (authored by dergachev, committed by ). Herald added a subscriber: llvm-commits.
Changed prior to commit: https://reviews.llvm.org/D46146?vs=144212&id=144262#toc Repository: rL LLVM https://reviews.llvm.org/D46146 Files: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp cfe/trunk/test/Analysis/new.cpp Index: cfe/trunk/test/Analysis/new.cpp =================================================================== --- cfe/trunk/test/Analysis/new.cpp +++ cfe/trunk/test/Analysis/new.cpp @@ -274,6 +274,24 @@ clang_analyzer_eval(true); // expected-warning{{TRUE}} } +void test_array_delete() { + class C { + public: + ~C() {} + }; + + auto c1 = new C[2][3]; + delete[] c1; // no-crash // no-warning + + C c2[4]; + // FIXME: Should warn. + delete[] &c2; // no-crash + + C c3[7][6]; + // FIXME: Should warn. + delete[] &c3; // no-crash +} + void testDeleteNull() { NoReturnDtor *foo = 0; delete foo; // should not call destructor, checked below Index: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1086,12 +1086,14 @@ // This workaround will just run the first destructor (which will still // invalidate the entire array). CallOpts.IsArrayCtorOrDtor = true; + // Yes, it may even be a multi-dimensional array. + while (const auto *AT = getContext().getAsArrayType(DTy)) + DTy = AT->getElementType(); if (ArgR) ArgR = getStoreManager().GetElementZeroRegion(cast<SubRegion>(ArgR), DTy); } - VisitCXXDestructor(DE->getDestroyedType(), ArgR, DE, /*IsBase=*/false, - Pred, Dst, CallOpts); + VisitCXXDestructor(DTy, ArgR, DE, /*IsBase=*/false, Pred, Dst, CallOpts); } void ExprEngine::ProcessBaseDtor(const CFGBaseDtor D,
Index: cfe/trunk/test/Analysis/new.cpp =================================================================== --- cfe/trunk/test/Analysis/new.cpp +++ cfe/trunk/test/Analysis/new.cpp @@ -274,6 +274,24 @@ clang_analyzer_eval(true); // expected-warning{{TRUE}} } +void test_array_delete() { + class C { + public: + ~C() {} + }; + + auto c1 = new C[2][3]; + delete[] c1; // no-crash // no-warning + + C c2[4]; + // FIXME: Should warn. + delete[] &c2; // no-crash + + C c3[7][6]; + // FIXME: Should warn. + delete[] &c3; // no-crash +} + void testDeleteNull() { NoReturnDtor *foo = 0; delete foo; // should not call destructor, checked below Index: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1086,12 +1086,14 @@ // This workaround will just run the first destructor (which will still // invalidate the entire array). CallOpts.IsArrayCtorOrDtor = true; + // Yes, it may even be a multi-dimensional array. + while (const auto *AT = getContext().getAsArrayType(DTy)) + DTy = AT->getElementType(); if (ArgR) ArgR = getStoreManager().GetElementZeroRegion(cast<SubRegion>(ArgR), DTy); } - VisitCXXDestructor(DE->getDestroyedType(), ArgR, DE, /*IsBase=*/false, - Pred, Dst, CallOpts); + VisitCXXDestructor(DTy, ArgR, DE, /*IsBase=*/false, Pred, Dst, CallOpts); } void ExprEngine::ProcessBaseDtor(const CFGBaseDtor D,
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits