[PATCH] D46146: [analyzer] pr37152: Fix operator delete[] array-type-sub-expression handling.

Artem Dergachev via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 26 15:13:23 PDT 2018


NoQ created this revision.
NoQ added reviewers: dcoughlin, xazax.hun, a.sidorin, george.karpenkov, szepet.
Herald added subscribers: cfe-commits, rnkovacs, baloghadamsoftware.

When operator `delete[]` receives a sub-expression of array type, it destroys the array correctly. Even if it's multi-dimensional, simply because in this case it's an array of array-type objects and destroying such array would mean properly destroying each object, where the object itself is an array, so properly destroying it means destroying its objects, etc.

In this case the AST is saying that the destroyed type is an array type - and we weren't prepared for that.

For now there's no actual calling multiple destructors; at least we're trying not to crash.


Repository:
  rC Clang

https://reviews.llvm.org/D46146

Files:
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  test/Analysis/new.cpp


Index: test/Analysis/new.cpp
===================================================================
--- test/Analysis/new.cpp
+++ 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: lib/StaticAnalyzer/Core/ExprEngine.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ 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,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D46146.144212.patch
Type: text/x-patch
Size: 1522 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180426/6daa0ce8/attachment.bin>


More information about the cfe-commits mailing list