Implement proper support for generating code for compound literals in
C++, which means: - binding the temporary as needed in Sema, so that we generate the appropriate call to the destructor, and - emitting the compound literal into the appropriate location for the aggregate, rather than trying to emit it as a temporary and memcpy() it. Fixes PR10138 / <rdar://problem/9615901>. llvm-svn: 133235
This commit is contained in:
parent
3982029f60
commit
9b71f0cfac
|
@ -91,9 +91,7 @@ public:
|
|||
void VisitMemberExpr(MemberExpr *ME) { EmitAggLoadOfLValue(ME); }
|
||||
void VisitUnaryDeref(UnaryOperator *E) { EmitAggLoadOfLValue(E); }
|
||||
void VisitStringLiteral(StringLiteral *E) { EmitAggLoadOfLValue(E); }
|
||||
void VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
|
||||
EmitAggLoadOfLValue(E);
|
||||
}
|
||||
void VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
|
||||
void VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
|
||||
EmitAggLoadOfLValue(E);
|
||||
}
|
||||
|
@ -247,6 +245,13 @@ void AggExprEmitter::VisitOpaqueValueExpr(OpaqueValueExpr *e) {
|
|||
EmitFinalDestCopy(e, CGF.getOpaqueLValueMapping(e));
|
||||
}
|
||||
|
||||
void
|
||||
AggExprEmitter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
|
||||
AggValueSlot Slot = EnsureSlot(E->getType());
|
||||
CGF.EmitAggExpr(E->getInitializer(), Slot);
|
||||
}
|
||||
|
||||
|
||||
void AggExprEmitter::VisitCastExpr(CastExpr *E) {
|
||||
switch (E->getCastKind()) {
|
||||
case CK_Dynamic: {
|
||||
|
|
|
@ -5309,8 +5309,9 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
|
|||
// In C, compound literals are l-values for some reason.
|
||||
ExprValueKind VK = getLangOptions().CPlusPlus ? VK_RValue : VK_LValue;
|
||||
|
||||
return Owned(new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType,
|
||||
VK, literalExpr, isFileScope));
|
||||
return MaybeBindToTemporary(
|
||||
new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType,
|
||||
VK, literalExpr, isFileScope));
|
||||
}
|
||||
|
||||
ExprResult
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
|
||||
|
||||
struct X {
|
||||
X();
|
||||
X(const X&);
|
||||
X(const char*);
|
||||
~X();
|
||||
};
|
||||
|
||||
struct Y {
|
||||
int i;
|
||||
X x;
|
||||
};
|
||||
|
||||
// CHECK: define i32 @_Z1fv()
|
||||
int f() {
|
||||
// CHECK: [[LVALUE:%[a-z0-9.]+]] = alloca
|
||||
// CHECK-NEXT: [[I:%[a-z0-9]+]] = getelementptr inbounds {{.*}}* [[LVALUE]], i32 0, i32 0
|
||||
// CHECK-NEXT: store i32 17, i32* [[I]]
|
||||
// CHECK-NEXT: [[X:%[a-z0-9]+]] = getelementptr inbounds {{.*}} [[LVALUE]], i32 0, i32 1
|
||||
// CHECK-NEXT: call void @_ZN1XC1EPKc({{.*}}[[X]]
|
||||
// CHECK-NEXT: [[I:%[a-z0-9]+]] = getelementptr inbounds {{.*}} [[LVALUE]], i32 0, i32 0
|
||||
// CHECK-NEXT: [[RESULT:%[a-z0-9]+]] = load i32*
|
||||
// CHECK-NEXT: call void @_ZN1YD1Ev
|
||||
// CHECK-NEXT: ret i32 [[RESULT]]
|
||||
return ((Y){17, "seventeen"}).i;
|
||||
}
|
Loading…
Reference in New Issue