From: Jakub Jelinek Date: Thu, 1 Apr 2004 16:27:06 +0000 (+0200) Subject: re PR c++/14755 (miscompilation in bitfielded signed integers) X-Git-Tag: releases/gcc-3.3.4~109 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3569be2724944da778338afee2e06f943fb49751;p=thirdparty%2Fgcc.git re PR c++/14755 (miscompilation in bitfielded signed integers) PR c++/14755 * fold-const.c (fold) : Properly compute newconst in "bitfld++ == const" to "++bitfld == const + incr" transformations. * gcc.c-torture/execute/20040331-1.c: New test. From-SVN: r80301 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6d7b7bbebaf5..08cb57f20adf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2004-04-01 Jakub Jelinek + + PR c++/14755 + * fold-const.c (fold) : Properly compute newconst in + "bitfld++ == const" to "++bitfld == const + incr" transformations. + 2004-04-01 Jakub Jelinek PR c/14069 diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 19384e436654..9be3ddfa6abf 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -6049,12 +6049,11 @@ fold (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 @@ -6066,25 +6065,12 @@ fold (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 = convert (TREE_TYPE (varop), mask); - newconst = fold (build (BIT_AND_EXPR, TREE_TYPE (varop), - newconst, mask)); - } + shift = build_int_2 (TYPE_PRECISION (TREE_TYPE (varop)) - size, + 0); + newconst = fold (build (LSHIFT_EXPR, TREE_TYPE (varop), + newconst, shift)); + newconst = fold (build (RSHIFT_EXPR, TREE_TYPE (varop), + newconst, shift)); } return fold (build (code, type, varop, newconst)); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f3d3cd84eb42..794c523b2fe4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,4 +1,9 @@ -2004-03-27 Jakub Jelinek +2004-04-01 Jakub Jelinek + + PR c++/14755 + * gcc.c-torture/execute/20040331-1.c: New test. + +2004-04-01 Jakub Jelinek PR c/14069 * gcc.dg/20040322-1.c: New test.