summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Eubanks <aeubanks@google.com>2021-03-03 09:55:02 -0800
committerTom Stellard <tstellar@redhat.com>2021-06-23 00:11:05 -0400
commit6c57bab74f6ffc8f40c5a805dedb5deb76c80458 (patch)
treed01b5bdf7150d19b6e28cec5c7301b4ea86214a5
parentfa21c5d4cf8cf00347e89bc3c50fbaf6a5c185dd (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.cpp2
-rw-r--r--clang/test/CodeGenCXX/trivial_abi.cpp18
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(); };