Fix output_constructor_bitfield handling of wide bitfields (PR89037)
The testcase was failing because we were trying to access TREE_INT_CST_ELT (x, 1) of a 128-bit integer that was small enough to need only a single element. 2019-01-25 Richard Sandiford <richard.sandiford@arm.com> gcc/ PR middle-end/89037 * varasm.c (output_constructor_bitfield): Use wi::extract_uhwi instead of accessing TREE_INT_CST_ELT directly. gcc/testsuite/ PR middle-end/89037 * gcc.dg/pr89037.c: New test. From-SVN: r268272
This commit is contained in:
parent
62fa42ce81
commit
3c35efc322
4 changed files with 44 additions and 13 deletions
|
@ -1,3 +1,9 @@
|
|||
2019-01-25 Richard Sandiford <richard.sandiford@arm.com>
|
||||
|
||||
PR middle-end/89037
|
||||
* varasm.c (output_constructor_bitfield): Use wi::extract_uhwi
|
||||
instead of accessing TREE_INT_CST_ELT directly.
|
||||
|
||||
2019-01-25 Christophe Lyon <christophe.lyon@linaro.org>
|
||||
|
||||
* doc/sourcebuild.texi (Environment attributes): Add fenv and
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2019-01-25 Richard Sandiford <richard.sandiford@arm.com>
|
||||
|
||||
PR middle-end/89037
|
||||
* gcc.dg/pr89037.c: New test.
|
||||
|
||||
2019-01-25 Christophe Lyon <christophe.lyon@linaro.org>
|
||||
|
||||
* lib/target-supports.exp (check_effective_target_fenv): New.
|
||||
|
|
24
gcc/testsuite/gcc.dg/pr89037.c
Normal file
24
gcc/testsuite/gcc.dg/pr89037.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
/* { dg-do run { target int128 } } */
|
||||
/* { dg-options "" } */
|
||||
|
||||
struct s
|
||||
{
|
||||
__int128 y : 66;
|
||||
};
|
||||
typedef struct s T;
|
||||
T a[] = { 1, 10000, 0x12345, 0xff000001, 1ULL << 63, (__int128) 1 << 64,
|
||||
((__int128) 1 << 64) | 1 };
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
if (a[0].y != 1
|
||||
|| a[1].y != 10000
|
||||
|| a[2].y != 0x12345
|
||||
|| a[3].y != 0xff000001
|
||||
|| a[4].y != (1ULL << 63)
|
||||
|| a[5].y != ((__int128) 1 << 64)
|
||||
|| a[6].y != (((__int128) 1 << 64) | 1))
|
||||
__builtin_abort ();
|
||||
return 0;
|
||||
}
|
22
gcc/varasm.c
22
gcc/varasm.c
|
@ -5349,7 +5349,7 @@ output_constructor_bitfield (oc_local_state *local, unsigned int bit_offset)
|
|||
{
|
||||
int this_time;
|
||||
int shift;
|
||||
HOST_WIDE_INT value;
|
||||
unsigned HOST_WIDE_INT value;
|
||||
HOST_WIDE_INT next_byte = next_offset / BITS_PER_UNIT;
|
||||
HOST_WIDE_INT next_bit = next_offset % BITS_PER_UNIT;
|
||||
|
||||
|
@ -5381,15 +5381,13 @@ output_constructor_bitfield (oc_local_state *local, unsigned int bit_offset)
|
|||
this_time = end - shift + 1;
|
||||
}
|
||||
|
||||
/* Now get the bits from the appropriate constant word. */
|
||||
value = TREE_INT_CST_ELT (local->val, shift / HOST_BITS_PER_WIDE_INT);
|
||||
shift = shift & (HOST_BITS_PER_WIDE_INT - 1);
|
||||
/* Now get the bits we want to insert. */
|
||||
value = wi::extract_uhwi (wi::to_widest (local->val),
|
||||
shift, this_time);
|
||||
|
||||
/* Get the result. This works only when:
|
||||
1 <= this_time <= HOST_BITS_PER_WIDE_INT. */
|
||||
local->byte |= (((value >> shift)
|
||||
& (((HOST_WIDE_INT) 2 << (this_time - 1)) - 1))
|
||||
<< (BITS_PER_UNIT - this_time - next_bit));
|
||||
local->byte |= value << (BITS_PER_UNIT - this_time - next_bit);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5406,15 +5404,13 @@ output_constructor_bitfield (oc_local_state *local, unsigned int bit_offset)
|
|||
this_time
|
||||
= HOST_BITS_PER_WIDE_INT - (shift & (HOST_BITS_PER_WIDE_INT - 1));
|
||||
|
||||
/* Now get the bits from the appropriate constant word. */
|
||||
value = TREE_INT_CST_ELT (local->val, shift / HOST_BITS_PER_WIDE_INT);
|
||||
shift = shift & (HOST_BITS_PER_WIDE_INT - 1);
|
||||
/* Now get the bits we want to insert. */
|
||||
value = wi::extract_uhwi (wi::to_widest (local->val),
|
||||
shift, this_time);
|
||||
|
||||
/* Get the result. This works only when:
|
||||
1 <= this_time <= HOST_BITS_PER_WIDE_INT. */
|
||||
local->byte |= (((value >> shift)
|
||||
& (((HOST_WIDE_INT) 2 << (this_time - 1)) - 1))
|
||||
<< next_bit);
|
||||
local->byte |= value << next_bit;
|
||||
}
|
||||
|
||||
next_offset += this_time;
|
||||
|
|
Loading…
Add table
Reference in a new issue