summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtem Dergachev <artem.dergachev@gmail.com>2018-04-27 02:16:03 +0000
committerArtem Dergachev <artem.dergachev@gmail.com>2018-04-27 02:16:03 +0000
commit4fbd97e183f193def02f39972ab97be327e541ff (patch)
tree4741a41db3bfaf40ec2b181092d64435ca74ef64
parentc08b693e309baa80f0a3dd7794af130c3393c777 (diff)
downloadbcm5719-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.cpp6
-rw-r--r--clang/test/Analysis/new.cpp18
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
OpenPOWER on IntegriCloud