diff options
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/expr.c | 5 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr85496.C | 18 |
4 files changed, 32 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ecad014e0a5..b93fe69cf3e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2018-04-23 Eric Botcazou <ebotcazou@adacore.com> + + PR middle-end/85496 + * expr.c (store_field): In the bitfield case, if the value comes from + a function call and is returned in registers by means of a PARALLEL, + do not change the mode of the temporary unless BLKmode and VOIDmode. + 2019-02-15 Eric Botcazou <ebotcazou@adacore.com> * asan.c (asan_emit_stack_protection): Use full-sized mask to align diff --git a/gcc/expr.c b/gcc/expr.c index 6342c0a88ee..b3645fb1c15 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -6693,8 +6693,9 @@ store_field (rtx target, HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos, if (GET_CODE (temp) == PARALLEL) { HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp)); - machine_mode temp_mode - = smallest_mode_for_size (size * BITS_PER_UNIT, MODE_INT); + machine_mode temp_mode = GET_MODE (temp); + if (temp_mode == BLKmode || temp_mode == VOIDmode) + temp_mode = smallest_mode_for_size (size * BITS_PER_UNIT, MODE_INT); rtx temp_target = gen_reg_rtx (temp_mode); emit_group_store (temp_target, temp, TREE_TYPE (exp), size); temp = temp_target; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7dc8ba30323..52de66b28e6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2018-04-23 Eric Botcazou <ebotcazou@adacore.com> + + * g++.dg/torture/pr85496.C: New test. + 2018-12-05 Jakub Jelinek <jakub@redhat.com> PR sanitizer/88333 diff --git a/gcc/testsuite/g++.dg/torture/pr85496.C b/gcc/testsuite/g++.dg/torture/pr85496.C new file mode 100644 index 00000000000..3f504a37791 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr85496.C @@ -0,0 +1,18 @@ +// PR middle-end/85496 +// Reported by Marek Polacek <mpolacek@gcc.gnu.org> + +template <typename> class complex; +template <typename _Tp> complex<_Tp> operator*(complex<_Tp>, complex<_Tp>); +template <> struct complex<float> { _Complex float _M_value; }; +class A { + complex<float> _f0, _f1; + +public: + complex<float> &m_fn1() { return _f1; } +}; +complex<float> a; +void cos() { + A b; + complex<float> c; + b.m_fn1() = c * a; +} |