diff options
author | Richard Biener <rguenther@suse.de> | 2021-02-26 08:45:36 +0100 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2021-02-26 12:34:27 +0100 |
commit | c173346aac4a66ad3747f380f2f0c97d2dbf8973 (patch) | |
tree | d16ea8891b077209bea6a72523af2f259f0499fd /gcc | |
parent | 0f161cc8494cf7283a16fa9ebbcf8fd121bab68d (diff) | |
download | gcc-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.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/pr99218.C | 31 |
2 files changed, 38 insertions, 1 deletions
@@ -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)}; +} |