gimple-fold: Fix up fold_array_ctor_reference RAW_DATA_CST handling [PR118207]

The following testcases ICE because fold_array_ctor_reference in the
RAW_DATA_CST handling just return build_int_cst without actually checking
that if type is non-NULL, TREE_TYPE (val) is uselessly convertible to it.

By falling through the code after it without *suboff += we get everything
we need, the two if conditionals will never be true (we've already
checked that size == BITS_PER_UNIT and so can't be 0, and val will be
INTEGER_CST), but it will do the important fold_ctor_reference call
which will deal with type incompatibilities.

2024-12-28  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/118207
	* gimple-fold.cc (fold_array_ctor_reference): For RAW_DATA_CST,
	just set val to build_int_cst and fall through to the normal
	element handling code instead of returning build_int_cst right away.

	* gcc.dg/pr118207.c: New test.
This commit is contained in:
Jakub Jelinek 2024-12-28 15:42:56 +01:00 committed by Jakub Jelinek
parent a326ecf541
commit 65c8fd7b01
3 changed files with 43 additions and 2 deletions

View file

@ -9707,9 +9707,8 @@ fold_array_ctor_reference (tree type, tree ctor,
constructor_elt *elt = CONSTRUCTOR_ELT (ctor, ctor_idx);
if (elt->index == NULL_TREE || TREE_CODE (elt->index) != INTEGER_CST)
return NULL_TREE;
*suboff += access_index.to_uhwi () * BITS_PER_UNIT;
unsigned o = (access_index - wi::to_offset (elt->index)).to_uhwi ();
return build_int_cst (TREE_TYPE (val), RAW_DATA_UCHAR_ELT (val, o));
val = build_int_cst (TREE_TYPE (val), RAW_DATA_UCHAR_ELT (val, o));
}
if (!size && TREE_CODE (val) != CONSTRUCTOR)
{

View file

@ -0,0 +1,17 @@
/* PR tree-optimization/118207 */
/* { dg-do compile } */
/* { dg-options "-O2" } */
struct A { unsigned char a; };
struct B { struct A b; };
static const unsigned char c[] = {
#embed __FILE__
};
struct B d;
void
foo ()
{
const struct B *t = (const struct B *) &c;
d.b = t->b;
}

View file

@ -0,0 +1,25 @@
/* PR tree-optimization/118207 */
/* { dg-do compile } */
/* { dg-options "-O2" } */
struct A { unsigned char a; };
struct B { struct A b; };
static const unsigned char c[160] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
struct B d;
void
foo ()
{
const struct B *t = (const struct B *) &c;
d.b = t->b;
}