diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -2056,7 +2056,7 @@ Record->hasTrivialCopyAssignment() || Record->hasTrivialMoveConstructor() || Record->hasTrivialMoveAssignment() || - Record->isUnion()) && + Record->hasAttr() || Record->isUnion()) && "Trying to aggregate-copy a type without a trivial copy/move " "constructor or assignment operator"); // Ignore empty classes in C++. diff --git a/clang/test/CodeGenCXX/trivial_abi.cpp b/clang/test/CodeGenCXX/trivial_abi.cpp --- a/clang/test/CodeGenCXX/trivial_abi.cpp +++ b/clang/test/CodeGenCXX/trivial_abi.cpp @@ -262,3 +262,21 @@ void testExceptionLarge() { calleeExceptionLarge(Large(), Large()); } + +// PR42961 + +// CHECK: define{{.*}} @"_ZN3$_08__invokeEv"() +// CHECK: %[[RETVAL:.*]] = alloca %[[STRUCT_SMALL]], align 8 +// CHECK: %[[COERCE:.*]] = alloca %[[STRUCT_SMALL]], align 8 +// CHECK: %[[CALL:.*]] = call{{.*}} @"_ZNK3$_0clEv" +// CHECK: %[[COERCEDIVE:.*]] = getelementptr{{.*}} %[[COERCE]] +// CHECK: %[[COERCEVALIP:.*]] = inttoptr{{.*}} %[[CALL]] +// CHECK: %[[RETVALP:.*]] = bitcast %[[STRUCT_SMALL]]* %[[RETVAL]] +// CHECK: %[[COERCEP:.*]] = bitcast %[[STRUCT_SMALL]]* %[[COERCE]] +// CHECK: call {{.*}}memcpy{{.*}} %[[RETVALP]]{{.*}} %[[COERCEP]] +// CHECK: %[[COERCEDIVE1:.*]] = getelementptr{{.*}} %[[RETVAL]] +// CHECK: %[[TMP:.*]] = load{{.*}} %[[COERCEDIVE1]] +// CHECK: %[[COERCEVALPI:.*]] = ptrtoint{{.*}} %[[TMP]] +// CHECK: ret{{.*}} %[[COERCEVALPI]] + +Small (*fp)() = []() -> Small { return Small(); };