Commit 42132674 by Jakub Jelinek Committed by Jakub Jelinek

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
parent 0100ae43
2017-03-01 Jakub Jelinek <jakub@redhat.com>
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 <rguenther@suse.de>
PR middle-end/79721
......
......@@ -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),
......
......@@ -5,6 +5,10 @@
2017-03-01 Jakub Jelinek <jakub@redhat.com>
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.
......
// 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(), "");
// 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, "");
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment