aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.cc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2025-01-29 15:09:35 +0100
committerRichard Biener <rguenth@gcc.gnu.org>2025-01-30 10:03:02 +0100
commit6b56e645a7b481693fe6982f8f09ba2e07768bf8 (patch)
tree811f58cd52a0e1808aa67cfa9864e56d15162d45 /gcc/expr.cc
parentd1c7837d2d6e5a2997228681166ed8c814891881 (diff)
downloadgcc-6b56e645a7b481693fe6982f8f09ba2e07768bf8.zip
gcc-6b56e645a7b481693fe6982f8f09ba2e07768bf8.tar.gz
gcc-6b56e645a7b481693fe6982f8f09ba2e07768bf8.tar.bz2
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.
Diffstat (limited to 'gcc/expr.cc')
-rw-r--r--gcc/expr.cc8
1 files changed, 8 insertions, 0 deletions
diff --git a/gcc/expr.cc b/gcc/expr.cc
index 7f3149b..10467f8 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;