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.
This commit is contained in:
Richard Biener 2021-02-26 08:45:36 +01:00
parent 0f161cc849
commit c173346aac
2 changed files with 38 additions and 1 deletions

View File

@ -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)

View File

@ -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)};
}