middle-end/115641 - invalid address construction

fold_truth_andor_1 via make_bit_field_ref builds an address of
a CALL_EXPR which isn't valid GENERIC and later causes an ICE.
The following simply avoids the folding for f ().a != 1 || f ().b != 2
as it is a premature optimization anyway.  The alternative would
have been to build a TARGET_EXPR around the call.  To get this far
f () has to be const as otherwise the two calls are not semantically
equivalent for the optimization.

	PR middle-end/115641
	* fold-const.cc (decode_field_reference): If the inner
	reference isn't something we can take the address of, fail.

	* gcc.dg/torture/pr115641.c: New testcase.
This commit is contained in:
Richard Biener 2024-07-18 13:35:33 +02:00 committed by Richard Biener
parent ebac11afbc
commit 3670c70c56
2 changed files with 32 additions and 0 deletions

View file

@ -5003,6 +5003,9 @@ decode_field_reference (location_t loc, tree *exp_, HOST_WIDE_INT *pbitsize,
|| *pbitsize < 0
|| offset != 0
|| TREE_CODE (inner) == PLACEHOLDER_EXPR
/* We eventually want to build a larger reference and need to take
the address of this. */
|| (!REFERENCE_CLASS_P (inner) && !DECL_P (inner))
/* Reject out-of-bound accesses (PR79731). */
|| (! AGGREGATE_TYPE_P (TREE_TYPE (inner))
&& compare_tree_int (TYPE_SIZE (TREE_TYPE (inner)),

View file

@ -0,0 +1,29 @@
/* { dg-do run } */
typedef struct {
char hours, day, month;
short year;
} T;
T g (void)
{
T now;
now.hours = 1;
now.day = 2;
now.month = 3;
now.year = 4;
return now;
}
__attribute__((const)) T f (void)
{
T virk = g ();
return virk;
}
int main ()
{
if (f ().hours != 1 || f ().day != 2 || f ().month != 3 || f ().year != 4)
__builtin_abort ();
return 0;
}