зеркало из https://github.com/microsoft/clang-1.git
Reset the lifetime-managed flag between emission of the agg conditional
branches. Fixes PR8623. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@119408 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
34c26300b3
Коммит
74fb0edb44
|
@ -394,8 +394,8 @@ void AggExprEmitter::VisitConditionalOperator(const ConditionalOperator *E) {
|
||||||
CGF.BeginConditionalBranch();
|
CGF.BeginConditionalBranch();
|
||||||
CGF.EmitBlock(LHSBlock);
|
CGF.EmitBlock(LHSBlock);
|
||||||
|
|
||||||
// Handle the GNU extension for missing LHS.
|
// Save whether the destination's lifetime is externally managed.
|
||||||
assert(E->getLHS() && "Must have LHS for aggregate value");
|
bool DestLifetimeManaged = Dest.isLifetimeExternallyManaged();
|
||||||
|
|
||||||
Visit(E->getLHS());
|
Visit(E->getLHS());
|
||||||
CGF.EndConditionalBranch();
|
CGF.EndConditionalBranch();
|
||||||
|
@ -404,6 +404,12 @@ void AggExprEmitter::VisitConditionalOperator(const ConditionalOperator *E) {
|
||||||
CGF.BeginConditionalBranch();
|
CGF.BeginConditionalBranch();
|
||||||
CGF.EmitBlock(RHSBlock);
|
CGF.EmitBlock(RHSBlock);
|
||||||
|
|
||||||
|
// If the result of an agg expression is unused, then the emission
|
||||||
|
// of the LHS might need to create a destination slot. That's fine
|
||||||
|
// with us, and we can safely emit the RHS into the same slot, but
|
||||||
|
// we shouldn't claim that its lifetime is externally managed.
|
||||||
|
Dest.setLifetimeExternallyManaged(DestLifetimeManaged);
|
||||||
|
|
||||||
Visit(E->getRHS());
|
Visit(E->getRHS());
|
||||||
CGF.EndConditionalBranch();
|
CGF.EndConditionalBranch();
|
||||||
CGF.EmitBranch(ContBlock);
|
CGF.EmitBranch(ContBlock);
|
||||||
|
|
|
@ -379,8 +379,8 @@ public:
|
||||||
bool isLifetimeExternallyManaged() const {
|
bool isLifetimeExternallyManaged() const {
|
||||||
return LifetimeFlag;
|
return LifetimeFlag;
|
||||||
}
|
}
|
||||||
void setLifetimeExternallyManaged() {
|
void setLifetimeExternallyManaged(bool Managed = true) {
|
||||||
LifetimeFlag = true;
|
LifetimeFlag = Managed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isVolatile() const {
|
bool isVolatile() const {
|
||||||
|
|
|
@ -493,3 +493,35 @@ namespace Elision {
|
||||||
A(*x).foo();
|
A(*x).foo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace PR8623 {
|
||||||
|
struct A { A(int); ~A(); };
|
||||||
|
|
||||||
|
// CHECK: define void @_ZN6PR86233fooEb(
|
||||||
|
void foo(bool b) {
|
||||||
|
// CHECK: [[TMP:%.*]] = alloca [[A:%.*]], align 1
|
||||||
|
// CHECK-NEXT: [[LCONS:%.*]] = alloca i1
|
||||||
|
// CHECK-NEXT: [[RCONS:%.*]] = alloca i1
|
||||||
|
// CHECK-NEXT: store i1 false, i1* [[RCONS]]
|
||||||
|
// CHECK-NEXT: store i1 false, i1* [[LCONS]]
|
||||||
|
// CHECK: br i1
|
||||||
|
// CHECK: call void @_ZN6PR86231AC1Ei([[A]]* [[TMP]], i32 2)
|
||||||
|
// CHECK-NEXT: store i1 true, i1* [[LCONS]]
|
||||||
|
// CHECK-NEXT: br label
|
||||||
|
// CHECK: call void @_ZN6PR86231AC1Ei([[A]]* [[TMP]], i32 3)
|
||||||
|
// CHECK-NEXT: store i1 true, i1* [[RCONS]]
|
||||||
|
// CHECK-NEXT: br label
|
||||||
|
// CHECK: load i1* [[RCONS]]
|
||||||
|
// CHECK-NEXT: br i1
|
||||||
|
// CHECK: call void @_ZN6PR86231AD1Ev([[A]]* [[TMP]])
|
||||||
|
// CHECK-NEXT: store i1 false, i1* [[RCONS]]
|
||||||
|
// CHECK-NEXT: br label
|
||||||
|
// CHECK: load i1* [[LCONS]]
|
||||||
|
// CHECK-NEXT: br i1
|
||||||
|
// CHECK: call void @_ZN6PR86231AD1Ev([[A]]* [[TMP]])
|
||||||
|
// CHECK-NEXT: store i1 false, i1* [[LCONS]]
|
||||||
|
// CHECK-NEXT: br label
|
||||||
|
// CHECK: ret void
|
||||||
|
b ? A(2) : A(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче