diff options
author | Jakub Jelinek <jakub@redhat.com> | 2017-03-01 10:02:12 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2017-03-01 10:02:12 +0100 |
commit | 42132674e5c9e7978a7d7d9283682f89639e236e (patch) | |
tree | 90bace33bc8bb839de2a9bf73929c8d73b391cde /gcc/fold-const.c | |
parent | 0100ae430272feaa208b02c32e52d530cd9c8644 (diff) | |
download | gcc-42132674e5c9e7978a7d7d9283682f89639e236e.zip gcc-42132674e5c9e7978a7d7d9283682f89639e236e.tar.gz gcc-42132674e5c9e7978a7d7d9283682f89639e236e.tar.bz2 |
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
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 3d63836..e64fa64 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), |