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>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133235
91177308-0d34-0410-b5e6-
96231b3b80d8
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);
}
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: {
// 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
--- /dev/null
+// 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;
+}