diff options
author | Arthur Eubanks <aeubanks@google.com> | 2021-03-03 09:55:02 -0800 |
---|---|---|
committer | Tom Stellard <tstellar@redhat.com> | 2021-06-23 00:11:05 -0400 |
commit | 6c57bab74f6ffc8f40c5a805dedb5deb76c80458 (patch) | |
tree | d01b5bdf7150d19b6e28cec5c7301b4ea86214a5 | |
parent | fa21c5d4cf8cf00347e89bc3c50fbaf6a5c185dd (diff) |
[clang] Don't assert in EmitAggregateCopy on trivial_abi types
Fixes PR42961.
Reviewed By: rnk
Differential Revision: https://reviews.llvm.org/D97872
(cherry picked from commit c8227f06b3356cdc9cc757d8888dfb59a6d8ad89)
-rw-r--r-- | clang/lib/CodeGen/CGExprAgg.cpp | 2 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/trivial_abi.cpp | 18 |
2 files changed, 19 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index 60ea1b2af037..f3ab91559d30 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -2056,7 +2056,7 @@ void CodeGenFunction::EmitAggregateCopy(LValue Dest, LValue Src, QualType Ty, Record->hasTrivialCopyAssignment() || Record->hasTrivialMoveConstructor() || Record->hasTrivialMoveAssignment() || - Record->isUnion()) && + Record->hasAttr<TrivialABIAttr>() || 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 index ac41f5cac086..a4222c100311 100644 --- a/clang/test/CodeGenCXX/trivial_abi.cpp +++ b/clang/test/CodeGenCXX/trivial_abi.cpp @@ -262,3 +262,21 @@ void calleeExceptionLarge(Large, Large); 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(); }; |