https://gcc.gnu.org/g:b444c3061a14d12d164d82345a1836f5fbd21939
commit r12-11023-gb444c3061a14d12d164d82345a1836f5fbd21939 Author: Richard Biener <rguent...@suse.de> Date: Thu Jul 18 13:35:33 2024 +0200 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. (cherry picked from commit 3670c70c561656a19f6bff36dd229f18120af127) Diff: --- gcc/fold-const.cc | 3 +++ gcc/testsuite/gcc.dg/torture/pr115641.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index 391f11095408..4e88aa4ef521 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -4767,6 +4767,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)), diff --git a/gcc/testsuite/gcc.dg/torture/pr115641.c b/gcc/testsuite/gcc.dg/torture/pr115641.c new file mode 100644 index 000000000000..65fb09ca64fc --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr115641.c @@ -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; +}