mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-07 16:42:34 +00:00
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! Re-commit of r302750, reverted in r302776. llvm-svn: 302817
This commit is contained in:
parent
dbd6219f81
commit
722363727d
@ -512,12 +512,20 @@ void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType,
|
||||
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 =
|
||||
|
36
clang/test/CodeGenCXX/array-default-argument.cpp
Normal file
36
clang/test/CodeGenCXX/array-default-argument.cpp
Normal file
@ -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}} {{.*}} @_ZN1AC1Ev([[TEMPORARY:.*]])
|
||||
// CHECK-EH: unwind label %[[PARTIAL_ARRAY_LPAD:.*]]
|
||||
// CHECK: {{call|invoke}} {{.*}} @_ZN1BC1E1A({{.*}}, [[TEMPORARY]])
|
||||
// CHECK-EH: unwind label %[[A_AND_PARTIAL_ARRAY_LPAD:.*]]
|
||||
// CHECK: {{call|invoke}} {{.*}} @_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}} {{.*}} @_ZN1BD1Ev(
|
||||
}
|
Loading…
Reference in New Issue
Block a user