Author: Richard Smith Date: 2021-02-03T23:38:02-08:00 New Revision: cde8d2fddbff55cae520d90f47f6faf124d3f953
URL: https://github.com/llvm/llvm-project/commit/cde8d2fddbff55cae520d90f47f6faf124d3f953 DIFF: https://github.com/llvm/llvm-project/commit/cde8d2fddbff55cae520d90f47f6faf124d3f953.diff LOG: Fix miscompile when performing template instantiation of non-dependent doubly-nested implicit CXXConstructExprs. Ensure that we transform the parameter initializer using TransformInitializer rather than TransformExpr so that we properly strip down and rebuild the initialization, including any necessary CXXBindTemporaryExprs. Otherwise we can end up forgetting to destroy temporary objects used to construct a constructor parameter. Added: clang/test/CodeGenCXX/instantiate-init.cpp Modified: clang/lib/Sema/TreeTransform.h Removed: ################################################################################ diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 1bff267cffc8..1da28a3bb94c 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -12241,7 +12241,8 @@ TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) { (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(1)))) && (!getDerived().DropCallArgument(E->getArg(0))) && !E->isListInitialization())) - return getDerived().TransformExpr(E->getArg(0)); + return getDerived().TransformInitializer(E->getArg(0), + /*DirectInit*/ false); TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName()); diff --git a/clang/test/CodeGenCXX/instantiate-init.cpp b/clang/test/CodeGenCXX/instantiate-init.cpp new file mode 100644 index 000000000000..dd8a1a13bdf0 --- /dev/null +++ b/clang/test/CodeGenCXX/instantiate-init.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -std=c++14 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -std=c++17 %s -emit-llvm -o - | FileCheck %s + +namespace std { + template<typename T> class initializer_list { + const T *data; + __SIZE_TYPE__ size; + + public: + initializer_list(); + }; +} + +namespace ParenBraceInitList { + struct Vector { + Vector(std::initializer_list<int>); + ~Vector(); + }; + + struct Base { Base(Vector) {} }; + + // CHECK: define {{.*}}18ParenBraceInitList1fILi0EE + template<int> void f() { + // CHECK: call {{.*}}18ParenBraceInitList6VectorC1 + // CHECK: call {{.*}}18ParenBraceInitList6VectorD1 + Base({0}); + } + template void f<0>(); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits