re PR c++/14755 (miscompilation in bitfielded signed integers)
PR c++/14755 * fold-const.c (fold) <EQ_EXPR>: Properly compute newconst in "bitfld++ == const" to "++bitfld == const + incr" transformations. * gcc.c-torture/execute/20040331-1.c: New test. * gcc.dg/20040331-1.c: New test. From-SVN: r80294
This commit is contained in:
parent
a150de2951
commit
0b61218593
@ -1,3 +1,9 @@
|
||||
2004-04-01 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/14755
|
||||
* fold-const.c (fold) <EQ_EXPR>: Properly compute newconst in
|
||||
"bitfld++ == const" to "++bitfld == const + incr" transformations.
|
||||
|
||||
2004-04-01 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
|
||||
|
||||
* expr.c (get_inner_reference): Use DECL_UNSIGNED, not TREE_UNSIGNED.
|
||||
|
@ -7338,12 +7338,11 @@ fold (tree expr)
|
||||
/* If VAROP is a reference to a bitfield, we must mask
|
||||
the constant by the width of the field. */
|
||||
if (TREE_CODE (TREE_OPERAND (varop, 0)) == COMPONENT_REF
|
||||
&& DECL_BIT_FIELD(TREE_OPERAND (TREE_OPERAND (varop, 0), 1)))
|
||||
&& DECL_BIT_FIELD (TREE_OPERAND (TREE_OPERAND (varop, 0), 1)))
|
||||
{
|
||||
tree fielddecl = TREE_OPERAND (TREE_OPERAND (varop, 0), 1);
|
||||
int size = TREE_INT_CST_LOW (DECL_SIZE (fielddecl));
|
||||
tree folded_compare;
|
||||
tree mask = 0;
|
||||
tree folded_compare, shift;
|
||||
|
||||
/* First check whether the comparison would come out
|
||||
always the same. If we don't do that we would
|
||||
@ -7355,25 +7354,12 @@ fold (tree expr)
|
||||
|| integer_onep (folded_compare))
|
||||
return omit_one_operand (type, folded_compare, varop);
|
||||
|
||||
if (size < HOST_BITS_PER_WIDE_INT)
|
||||
{
|
||||
unsigned HOST_WIDE_INT lo = ((unsigned HOST_WIDE_INT) 1
|
||||
<< size) - 1;
|
||||
mask = build_int_2 (lo, 0);
|
||||
}
|
||||
else if (size < 2 * HOST_BITS_PER_WIDE_INT)
|
||||
{
|
||||
HOST_WIDE_INT hi = ((HOST_WIDE_INT) 1
|
||||
<< (size - HOST_BITS_PER_WIDE_INT)) - 1;
|
||||
mask = build_int_2 (~0, hi);
|
||||
}
|
||||
|
||||
if (mask)
|
||||
{
|
||||
mask = fold_convert (TREE_TYPE (varop), mask);
|
||||
newconst = fold (build2 (BIT_AND_EXPR, TREE_TYPE (varop),
|
||||
newconst, mask));
|
||||
}
|
||||
shift = build_int_2 (TYPE_PRECISION (TREE_TYPE (varop)) - size,
|
||||
0);
|
||||
newconst = fold (build2 (LSHIFT_EXPR, TREE_TYPE (varop),
|
||||
newconst, shift));
|
||||
newconst = fold (build2 (RSHIFT_EXPR, TREE_TYPE (varop),
|
||||
newconst, shift));
|
||||
}
|
||||
|
||||
return fold (build2 (code, type, varop, newconst));
|
||||
|
@ -1,3 +1,9 @@
|
||||
2004-04-01 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/14755
|
||||
* gcc.c-torture/execute/20040331-1.c: New test.
|
||||
* gcc.dg/20040331-1.c: New test.
|
||||
|
||||
2004-04-01 Paul Brook <paul@codesourcery.com>
|
||||
|
||||
* gcc.dg/arm-mmx-1.c: Add -mabi=iwmmxt to dg-options.
|
||||
|
12
gcc/testsuite/gcc.c-torture/execute/20040331-1.c
Normal file
12
gcc/testsuite/gcc.c-torture/execute/20040331-1.c
Normal file
@ -0,0 +1,12 @@
|
||||
/* PR c++/14755 */
|
||||
extern void abort (void);
|
||||
extern void exit (int);
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
struct { int count: 31; } s = { 0 };
|
||||
while (s.count--)
|
||||
abort ();
|
||||
exit (0);
|
||||
}
|
14
gcc/testsuite/gcc.dg/20040331-1.c
Normal file
14
gcc/testsuite/gcc.dg/20040331-1.c
Normal file
@ -0,0 +1,14 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-O2 -fwrapv" } */
|
||||
|
||||
extern void abort (void);
|
||||
extern void exit (int);
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
struct { int count: 2; } s = { -2 };
|
||||
while (s.count-- != -2)
|
||||
abort ();
|
||||
exit (0);
|
||||
}
|
Loading…
Reference in New Issue
Block a user