2008-08-26 Jakub Jelinek <jakub@redhat.com> PR middle-end/36449 * fold-const.c (make_bit_field_ref): Change bitpos and bitsize arguments to HOST_WIDE_INT. (fold_truthop): Change first_bit and end_bit to HOST_WIDE_INT. * g++.dg/opt/pr36449.C: New test. --- gcc/fold-const.c.jj 2007-11-24 21:47:36.000000000 +0100 +++ gcc/fold-const.c 2008-08-26 10:56:55.000000000 +0200 @@ -104,7 +104,7 @@ static int twoval_comparison_p (tree, tr static tree eval_subst (tree, tree, tree, tree, tree); static tree pedantic_omit_one_operand (tree, tree, tree); static tree distribute_bit_expr (enum tree_code, tree, tree, tree); -static tree make_bit_field_ref (tree, tree, int, int, int); +static tree make_bit_field_ref (tree, tree, HOST_WIDE_INT, HOST_WIDE_INT, int); static tree optimize_bit_field_compare (enum tree_code, tree, tree, tree); static tree decode_field_reference (tree, HOST_WIDE_INT *, HOST_WIDE_INT *, enum machine_mode *, int *, int *, @@ -3191,8 +3191,8 @@ distribute_real_division (enum tree_code starting at BITPOS. The field is unsigned if UNSIGNEDP is nonzero. */ static tree -make_bit_field_ref (tree inner, tree type, int bitsize, int bitpos, - int unsignedp) +make_bit_field_ref (tree inner, tree type, HOST_WIDE_INT bitsize, + HOST_WIDE_INT bitpos, int unsignedp) { tree result; @@ -4735,7 +4735,7 @@ fold_truthop (enum tree_code code, tree tree ll_and_mask, lr_and_mask, rl_and_mask, rr_and_mask; tree l_const, r_const; tree lntype, rntype, result; - int first_bit, end_bit; + HOST_WIDE_INT first_bit, end_bit; int volatilep; /* Start by getting the comparison codes. Fail if anything is volatile. --- gcc/testsuite/g++.dg/opt/pr36449.C.jj 2008-08-26 11:03:24.000000000 +0200 +++ gcc/testsuite/g++.dg/opt/pr36449.C 2008-08-26 11:00:53.000000000 +0200 @@ -0,0 +1,70 @@ +// PR middle-end/36449 +// { dg-do run } +// { dg-options "-O3" } + +extern "C" void exit (int); +extern "C" void abort (); + +struct R +{ + short a; + short b; +}; + +struct S +{ + R e; + long f; + long g; +}; + +struct T +{ + short c; + short d; +}; + +struct U +{ + long h[0x1ffffff + 1]; + T i; +}; + +U *j; + +void __attribute__((noinline)) +bar () +{ + exit (0); +} + +void __attribute__((noinline)) +foo () +{ + S s; + + s.e.a = 36; + s.e.b = 38; + if (s.e.a == j->i.c && s.e.b == j->i.d) + bar (); +} + +int +main () +{ + try + { + j = new U; + } + catch (...) + { + return 0; + } + j->i.c = 36; + j->i.d = 38; + j->h[0] = 1; + j->h[1] = 2; + j->h[2] = 3; + foo (); + abort (); +}