aboutsummaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2017-03-01 10:02:12 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2017-03-01 10:02:12 +0100
commit42132674e5c9e7978a7d7d9283682f89639e236e (patch)
tree90bace33bc8bb839de2a9bf73929c8d73b391cde /gcc/fold-const.c
parent0100ae430272feaa208b02c32e52d530cd9c8644 (diff)
downloadgcc-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.c25
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),