diff options
author | Artem Dergachev <artem.dergachev@gmail.com> | 2018-04-27 02:16:03 +0000 |
---|---|---|
committer | Artem Dergachev <artem.dergachev@gmail.com> | 2018-04-27 02:16:03 +0000 |
commit | 4fbd97e183f193def02f39972ab97be327e541ff (patch) | |
tree | 4741a41db3bfaf40ec2b181092d64435ca74ef64 | |
parent | c08b693e309baa80f0a3dd7794af130c3393c777 (diff) | |
download | bcm5719-llvm-4fbd97e183f193def02f39972ab97be327e541ff.tar.gz bcm5719-llvm-4fbd97e183f193def02f39972ab97be327e541ff.zip |
[analyzer] Fix operator delete[] array-type-sub-expression handling.
Avoid crash when the sub-expression of operator delete[] is of array type.
This is not the same as simply using a delete[] syntax.
We're still not properly calling destructors in this case in the analyzer.
Differential Revision: https://reviews.llvm.org/D46146
llvm-svn: 331014
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 6 | ||||
-rw-r--r-- | clang/test/Analysis/new.cpp | 18 |
2 files changed, 22 insertions, 2 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 1e0bfcea2d7..d0ebb223e94 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1086,12 +1086,14 @@ void ExprEngine::ProcessDeleteDtor(const CFGDeleteDtor Dtor, // 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, diff --git a/clang/test/Analysis/new.cpp b/clang/test/Analysis/new.cpp index 4ae93c612f3..31f763266c3 100644 --- a/clang/test/Analysis/new.cpp +++ b/clang/test/Analysis/new.cpp @@ -274,6 +274,24 @@ void test_var_delete() { 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 |