Author: rsmith Date: Wed May 10 19:17:17 2017 New Revision: 302750 URL: http://llvm.org/viewvc/llvm-project?rev=302750&view=rev Log: PR22877: When constructing an array via a constructor with a default argument in list-initialization, run cleanups for the default argument after each iteration of the initialization loop.
We previously only ran the destructor for any temporary once, at the end of the complete loop, rather than once per iteration! Added: cfe/trunk/test/CodeGenCXX/array-default-argument.cpp Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=302750&r1=302749&r2=302750&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Wed May 10 19:17:17 2017 @@ -512,12 +512,20 @@ void AggExprEmitter::EmitArrayInit(Addre currentElement->addIncoming(element, entryBB); // Emit the actual filler expression. - LValue elementLV = - CGF.MakeAddrLValue(Address(currentElement, elementAlign), elementType); - if (filler) - EmitInitializationToLValue(filler, elementLV); - else - EmitNullInitializationToLValue(elementLV); + { + // C++1z [class.temporary]p5: + // when a default constructor is called to initialize an element of + // an array with no corresponding initializer [...] the destruction of + // every temporary created in a default argument is sequenced before + // the construction of the next array element, if any + CodeGenFunction::RunCleanupsScope CleanupsScope(CGF); + LValue elementLV = + CGF.MakeAddrLValue(Address(currentElement, elementAlign), elementType); + if (filler) + EmitInitializationToLValue(filler, elementLV); + else + EmitNullInitializationToLValue(elementLV); + } // Move on to the next element. llvm::Value *nextElement = Added: cfe/trunk/test/CodeGenCXX/array-default-argument.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/array-default-argument.cpp?rev=302750&view=auto ============================================================================== --- cfe/trunk/test/CodeGenCXX/array-default-argument.cpp (added) +++ cfe/trunk/test/CodeGenCXX/array-default-argument.cpp Wed May 10 19:17:17 2017 @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s -triple %itanium_abi_triple | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -o - %s -triple %itanium_abi_triple -fexceptions -fcxx-exceptions | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-EH + +struct A { + A(); + ~A(); +}; + +struct B { + B(A = A()); + ~B(); +}; + +void f(); +// CHECK-LABEL: define void @_Z1gv() +void g() { + // CHECK: br label %[[LOOP:.*]] + + // [[LOOP]]: + // CHECK: {{call|invoke}} void @_ZN1AC1Ev([[TEMPORARY:.*]]) + // CHECK-EH: unwind label %[[PARTIAL_ARRAY_LPAD:.*]] + // CHECK: {{call|invoke}} void @_ZN1BC1E1A({{.*}}, [[TEMPORARY]]) + // CHECK-EH: unwind label %[[A_AND_PARTIAL_ARRAY_LPAD:.*]] + // CHECK: {{call|invoke}} void @_ZN1AD1Ev([[TEMPORARY]]) + // CHECK-EH: unwind label %[[PARTIAL_ARRAY_LPAD]] + // CHECK: getelementptr {{.*}}, i{{[0-9]*}} 1 + // CHECK: icmp eq + // CHECK: br i1 {{.*}} label %[[LOOP]] + B b[5]; + + // CHECK: {{call|invoke}} void @_Z1fv() + f(); + + // CHECK-NOT: @_ZN1AD1Ev( + // CHECK: {{call|invoke}} void @_ZN1BD1Ev( +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits