From: Jakub Jelinek Date: Wed, 1 Mar 2017 09:02:12 +0000 (+0100) Subject: re PR c++/79681 (ICE with constexpr and bitfield) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=42132674e5c9e7978a7d7d9283682f89639e236e;p=gcc.git re PR c++/79681 (ICE with constexpr and bitfield) PR c++/79681 * fold-const.c (make_bit_field_ref): If orig_inner is COMPONENT_REF, attempt to use its first operand as BIT_FIELD_REF base. * g++.dg/cpp1y/constexpr-79681-1.C: New test. * g++.dg/cpp1y/constexpr-79681-2.C: New test. From-SVN: r245804 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 253eab3456a..4873ae8eb9d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2017-03-01 Jakub Jelinek + + PR c++/79681 + * fold-const.c (make_bit_field_ref): If orig_inner is COMPONENT_REF, + attempt to use its first operand as BIT_FIELD_REF base. + 2017-03-01 Richard Biener PR middle-end/79721 diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 3d638360687..e64fa64232e 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -3862,6 +3862,31 @@ make_bit_field_ref (location_t loc, tree inner, tree orig_inner, tree type, { tree result, bftype; + /* Attempt not to lose the access path if possible. */ + if (TREE_CODE (orig_inner) == COMPONENT_REF) + { + tree ninner = TREE_OPERAND (orig_inner, 0); + machine_mode nmode; + HOST_WIDE_INT nbitsize, nbitpos; + tree noffset; + int nunsignedp, nreversep, nvolatilep = 0; + tree base = get_inner_reference (ninner, &nbitsize, &nbitpos, + &noffset, &nmode, &nunsignedp, + &nreversep, &nvolatilep); + if (base == inner + && noffset == NULL_TREE + && nbitsize >= bitsize + && nbitpos <= bitpos + && bitpos + bitsize <= nbitpos + nbitsize + && !reversep + && !nreversep + && !nvolatilep) + { + inner = ninner; + bitpos -= nbitpos; + } + } + alias_set_type iset = get_alias_set (orig_inner); if (iset == 0 && get_alias_set (inner) != iset) inner = fold_build2 (MEM_REF, TREE_TYPE (inner), diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7aac384da2f..5d7e177f271 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -5,6 +5,10 @@ 2017-03-01 Jakub Jelinek + PR c++/79681 + * g++.dg/cpp1y/constexpr-79681-1.C: New test. + * g++.dg/cpp1y/constexpr-79681-2.C: New test. + PR c++/79746 * g++.dg/warn/Wunused-parm-9.C: New test. diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-79681-1.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-79681-1.C new file mode 100644 index 00000000000..000afd80e04 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-79681-1.C @@ -0,0 +1,17 @@ +// PR c++/79681 +// { dg-do compile { target c++14 } } +// { dg-options "-O2" } + +struct A +{ + int i : 4; +}; + +constexpr bool +foo () +{ + A x[] = { 1 }; + return x[0].i; +} + +static_assert (foo(), ""); diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-79681-2.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-79681-2.C new file mode 100644 index 00000000000..edca161f8d5 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-79681-2.C @@ -0,0 +1,39 @@ +// PR c++/79681 +// { dg-do compile { target c++14 } } +// { dg-options "-O2" } + +struct A +{ + char i : 4; + char k : 1; + char l : 3; +}; +struct B +{ + char j : 4; +}; +struct C +{ + long long u; + A a[1]; + B b[1]; +}; + +constexpr bool +foo () +{ + C c = { 0, { { 5, 0, 2 } }, { { 6 } } }; + C d = { 0, { { 6, 0, 1 } }, { { 5 } } }; + return c.a[0].i == d.a[0].i && c.b[0].j == d.b[0].j; +} + +constexpr bool +bar () +{ + C c = { 0, { { 5, 0, 2 } }, { { 6 } } }; + C d = { 0, { { 6, 0, 1 } }, { { 5 } } }; + return c.a[0].i == d.a[0].i && c.a[0].l == d.a[0].l; +} + +static_assert (foo () == false, ""); +static_assert (bar () == false, "");