[PATCH] D64656: Ensure placeholder instruction for cleanup is created

Øystein Dale via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 12 12:07:38 PDT 2019


oydale created this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

A placeholder instruction for use in generation of cleanup code for an
initializer list would not be emitted if the base class contained a
non-trivial destructor and the class contains no fields of its own. This
would be the case when using CTAD to deduce the template arguments for a
struct with an overloaded call operator, e.g.

template <class... Ts> struct ctad : Ts... {};
template <class... Ts> ctad(Ts...)->ctad<Ts...>;

and this class was initialized with a list of lambdas capturing by copy,
e.g.

  ctad c {[s](short){}, [s](long){}};

In a release build the bug would manifest itself as a crash in the SROA
pass, however, in a debug build the following assert in CGCleanup.cpp
would fail:

  assert(dominatingIP && "no existing variable and no dominating IP!");

By ensuring that a placeholder instruction is emitted even if there's no
fields in the class, neither the assert nor the crash is reproducible.

See https://bugs.llvm.org/show_bug.cgi?id=40771


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D64656

Files:
  clang/lib/CodeGen/CGExprAgg.cpp


Index: clang/lib/CodeGen/CGExprAgg.cpp
===================================================================
--- clang/lib/CodeGen/CGExprAgg.cpp
+++ clang/lib/CodeGen/CGExprAgg.cpp
@@ -1618,6 +1618,14 @@
           GEP->eraseFromParent();
   }
 
+  // Base class has a destructor and there's no fields in the class itself,
+  // create a placeholder here since we did not create one earlier.
+  if (!cleanupDominator && !cleanups.empty())
+    cleanupDominator = CGF.Builder.CreateAlignedLoad(
+        CGF.Int8Ty,
+        llvm::Constant::getNullValue(CGF.Int8PtrTy),
+        CharUnits::One()); // placeholder
+
   // Deactivate all the partial cleanups in reverse order, which
   // generally means popping them.
   for (unsigned i = cleanups.size(); i != 0; --i)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D64656.209555.patch
Type: text/x-patch
Size: 765 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190712/432851f0/attachment.bin>


More information about the cfe-commits mailing list