diff options
author | Jakub Jelinek <jakub@redhat.com> | 2004-04-01 17:50:11 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2004-04-01 17:50:11 +0200 |
commit | 0b612185938e178cce2cb547424e27e7d8deeac7 (patch) | |
tree | 1615e48fce0014662e719f1204572e9e274a295f /gcc/fold-const.c | |
parent | a150de295117d1e8f76a01180541eff7d0eb380c (diff) | |
download | gcc-0b612185938e178cce2cb547424e27e7d8deeac7.zip gcc-0b612185938e178cce2cb547424e27e7d8deeac7.tar.gz gcc-0b612185938e178cce2cb547424e27e7d8deeac7.tar.bz2 |
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
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 30 |
1 files changed, 8 insertions, 22 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 51e986a..772e64e 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -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)); |