Index: lib/CodeGen/CGExpr.cpp =================================================================== --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -192,8 +192,12 @@ RValue CodeGenFunction::EmitAnyExprToTemp(const Expr *E) { AggValueSlot AggSlot = AggValueSlot::ignored(); - if (hasAggregateEvaluationKind(E->getType())) + if (hasAggregateEvaluationKind(E->getType())) { + if (const auto *OVE = dyn_cast(E)) + return getOpaqueLValueMapping(OVE).asAggregateRValue(); AggSlot = CreateAggTemp(E->getType(), "agg.tmp"); + } + return EmitAnyExpr(E, AggSlot); } Index: test/CodeGenObjCXX/property-dot-copy-elision.mm =================================================================== --- /dev/null +++ test/CodeGenObjCXX/property-dot-copy-elision.mm @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -std=c++1z -fobjc-arc -o - %s | FileCheck %s + +struct S0 { + id f; +}; + +struct S1 { + S1(); + S1(S0); + id f; +}; + +@interface C +@property S1 f; +@end +@implementation C +@end + +// CHECK-LABEL: define void @_Z5test0P1C( +// CHECK: %{{.*}} = alloca % +// CHECK: %[[TEMP_LVALUE:.*]] = alloca %[[STRUCT_S0:.*]], align +// CHECK: %[[AGG_TMP:.*]] = alloca %[[STRUCT_S1:.*]], align +// CHECK: call void @_ZN2S0C1Ev(%[[STRUCT_S0]]* %[[TEMP_LVALUE]]) +// CHECK: call void @_ZN2S1C1E2S0(%[[STRUCT_S1]]* %[[AGG_TMP]], %[[STRUCT_S0]]* %[[TEMP_LVALUE]]) +// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %[[STRUCT_S1]]*)*)(i8* %{{.*}}, i8* %{{.*}}, %[[STRUCT_S1]]* %[[AGG_TMP]]) + +void test0(C *c) { + c.f = S0(); +} + +// CHECK: define void @_Z5test1P1C( +// CHECK: %{{.*}} = alloca % +// CHECK: %[[TEMP_LVALUE:.*]] = alloca %[[STRUCT_S1:.*]], align +// CHECK: call void @_ZN2S1C1Ev(%[[STRUCT_S1]]* %[[TEMP_LVALUE]]) +// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %[[STRUCT_S1]]*)*)(i8* %{{.*}}, i8* %{{.*}}, %[[STRUCT_S1]]* %[[TEMP_LVALUE]]) + +void test1(C *c) { + c.f = S1(); +} Index: test/CodeGenObjCXX/property-objects.mm =================================================================== --- test/CodeGenObjCXX/property-objects.mm +++ test/CodeGenObjCXX/property-objects.mm @@ -125,8 +125,6 @@ // CHECK-NEXT: [[T1:%.*]] = sext i32 [[T0]] to i64 // CHECK-NEXT: store i64 [[T1]], i64* [[X]], align 8 // CHECK-NOT: call -// CHECK: call void @llvm.memcpy -// CHECK-NOT: call // CHECK: call void bitcast {{.*}} @objc_msgSend // CHECK-NOT: call // CHECK: ret void @@ -147,8 +145,6 @@ // CHECK-NOT: call // CHECK: store i64 [[T0]], // CHECK-NOT: call -// CHECK: call void @llvm.memcpy -// CHECK-NOT: call // CHECK: call void bitcast {{.*}} @objc_msgSend // CHECK-NOT: call // CHECK: ret void @@ -168,8 +164,6 @@ // CHECK-NOT: call // CHECK: store i64 [[T0]], // CHECK-NOT: call -// CHECK: call void @llvm.memcpy -// CHECK-NOT: call // CHECK: call void bitcast {{.*}} @objc_msgSend // CHECK-NOT: call // CHECK: ret void @@ -216,8 +210,6 @@ // CHECK-NOT: call // CHECK: store i32 [[T0]], // CHECK-NOT: call -// CHECK: call void @llvm.memcpy -// CHECK-NOT: call // CHECK: call void bitcast {{.*}} @objc_msgSend // CHECK-NOT: call // CHECK: ret void