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