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)


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)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to