Commit 0b612185 by Jakub Jelinek Committed by Jakub Jelinek

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
parent a150de29
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> 2004-04-01 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* expr.c (get_inner_reference): Use DECL_UNSIGNED, not TREE_UNSIGNED. * expr.c (get_inner_reference): Use DECL_UNSIGNED, not TREE_UNSIGNED.
......
...@@ -7338,12 +7338,11 @@ fold (tree expr) ...@@ -7338,12 +7338,11 @@ fold (tree expr)
/* If VAROP is a reference to a bitfield, we must mask /* If VAROP is a reference to a bitfield, we must mask
the constant by the width of the field. */ the constant by the width of the field. */
if (TREE_CODE (TREE_OPERAND (varop, 0)) == COMPONENT_REF 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); tree fielddecl = TREE_OPERAND (TREE_OPERAND (varop, 0), 1);
int size = TREE_INT_CST_LOW (DECL_SIZE (fielddecl)); int size = TREE_INT_CST_LOW (DECL_SIZE (fielddecl));
tree folded_compare; tree folded_compare, shift;
tree mask = 0;
/* First check whether the comparison would come out /* First check whether the comparison would come out
always the same. If we don't do that we would always the same. If we don't do that we would
...@@ -7355,25 +7354,12 @@ fold (tree expr) ...@@ -7355,25 +7354,12 @@ fold (tree expr)
|| integer_onep (folded_compare)) || integer_onep (folded_compare))
return omit_one_operand (type, folded_compare, varop); return omit_one_operand (type, folded_compare, varop);
if (size < HOST_BITS_PER_WIDE_INT) shift = build_int_2 (TYPE_PRECISION (TREE_TYPE (varop)) - size,
{ 0);
unsigned HOST_WIDE_INT lo = ((unsigned HOST_WIDE_INT) 1 newconst = fold (build2 (LSHIFT_EXPR, TREE_TYPE (varop),
<< size) - 1; newconst, shift));
mask = build_int_2 (lo, 0); newconst = fold (build2 (RSHIFT_EXPR, TREE_TYPE (varop),
} newconst, shift));
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));
}
} }
return fold (build2 (code, type, varop, newconst)); return fold (build2 (code, type, varop, newconst));
......
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> 2004-04-01 Paul Brook <paul@codesourcery.com>
* gcc.dg/arm-mmx-1.c: Add -mabi=iwmmxt to dg-options. * gcc.dg/arm-mmx-1.c: Add -mabi=iwmmxt to dg-options.
......
/* 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);
}
/* { 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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment