From: Richard Biener Date: Wed, 29 Jan 2025 14:09:35 +0000 (+0100) Subject: middle-end/118692 - ICE with out-of-bound ref expansion X-Git-Tag: basepoints/gcc-16~2269 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6b56e645a7b481693fe6982f8f09ba2e07768bf8;p=thirdparty%2Fgcc.git middle-end/118692 - ICE with out-of-bound ref expansion The following guards the BIT_FIELD_REF expansion fallback for MEM_REFs of entities expanded to register (or constant) further, avoiding large out-of-bound offsets by, when the access does not overlap the base object, expanding the offset as if it were zero. PR middle-end/118692 * expr.cc (expand_expr_real_1): When expanding a MEM_REF as BIT_FIELD_REF avoid large offsets for accesses not overlapping the base object. * gcc.dg/pr118692.c: New testcase. --- diff --git a/gcc/expr.cc b/gcc/expr.cc index 7f3149b85ee..10467f82c0d 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -11806,6 +11806,14 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, set_mem_size (temp, int_size_in_bytes (type)); return temp; } + /* When the access is fully outside of the underlying object + expand the offset as zero. This avoids out-of-bound + BIT_FIELD_REFs and generates smaller code for these cases + with UB. */ + type_size = tree_to_poly_uint64 (TYPE_SIZE_UNIT (type)); + if (!ranges_maybe_overlap_p (offset, type_size, 0, + GET_MODE_SIZE (DECL_MODE (base)))) + offset = 0; exp = build3 (BIT_FIELD_REF, type, base, TYPE_SIZE (type), bitsize_int (offset * BITS_PER_UNIT)); REF_REVERSE_STORAGE_ORDER (exp) = reverse; diff --git a/gcc/testsuite/gcc.dg/pr118692.c b/gcc/testsuite/gcc.dg/pr118692.c new file mode 100644 index 00000000000..45fba560b35 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr118692.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +_Complex double cf; + +void +foo(char c) +{ + cf += *(_Complex double *)__builtin_memcpy(8143523003042804629LL + &c, 0, 0); +}