aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2021-02-26 08:45:36 +0100
committerRichard Biener <rguenther@suse.de>2021-02-26 12:34:27 +0100
commitc173346aac4a66ad3747f380f2f0c97d2dbf8973 (patch)
treed16ea8891b077209bea6a72523af2f259f0499fd /gcc
parent0f161cc8494cf7283a16fa9ebbcf8fd121bab68d (diff)
downloadgcc-c173346aac4a66ad3747f380f2f0c97d2dbf8973.zip
gcc-c173346aac4a66ad3747f380f2f0c97d2dbf8973.tar.gz
gcc-c173346aac4a66ad3747f380f2f0c97d2dbf8973.tar.bz2
middle-end/99281 - avoid bitfield stores into addressable types
This avoids doing bitfield stores into the return object of calls when using return-slot optimization and the type is addressable. Instead we have to pass down the original target RTX to the call expansion which otherwise tries to create a new temporary. 2021-02-26 Richard Biener <rguenther@suse.de> PR middle-end/99281 * expr.c (store_field): For calls with return-slot optimization and addressable return type expand the store directly. * g++.dg/pr99218.C: New testcase.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/expr.c8
-rw-r--r--gcc/testsuite/g++.dg/pr99218.C31
2 files changed, 38 insertions, 1 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 86dc1b6..92035c7 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -7214,7 +7214,13 @@ store_field (rtx target, poly_int64 bitsize, poly_int64 bitpos,
|| !multiple_p (bitpos, BITS_PER_UNIT)
|| !poly_int_tree_p (DECL_SIZE (TREE_OPERAND (exp, 1)),
&decl_bitsize)
- || maybe_ne (decl_bitsize, bitsize)))
+ || maybe_ne (decl_bitsize, bitsize))
+ /* A call with an addressable return type and return-slot
+ optimization must not need bitfield operations but we must
+ pass down the original target. */
+ && (TREE_CODE (exp) != CALL_EXPR
+ || !TREE_ADDRESSABLE (TREE_TYPE (exp))
+ || !CALL_EXPR_RETURN_SLOT_OPT (exp)))
/* If we are expanding a MEM_REF of a non-BLKmode non-addressable
decl we must use bitfield operations. */
|| (known_size_p (bitsize)
diff --git a/gcc/testsuite/g++.dg/pr99218.C b/gcc/testsuite/g++.dg/pr99218.C
new file mode 100644
index 0000000..477a6a2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr99218.C
@@ -0,0 +1,31 @@
+// { dg-do compile }
+// { dg-require-effective-target c++17 }
+
+struct Data
+{
+ Data() {}
+ ~Data() {}
+
+ long long i;
+};
+
+struct X
+{
+ Data a;
+ int b;
+};
+
+template<class T>
+X get(T const&)
+{
+ return X{};
+}
+
+template<class... Ts>
+struct pack_type : Ts...
+{};
+
+int main()
+{
+ pack_type<X>{get(1)};
+}