aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.cc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2025-01-27 11:28:47 +0100
committerRichard Biener <rguenth@gcc.gnu.org>2025-01-27 13:31:35 +0100
commit52366356fe7b638f66c4011b8a61fb6c22b08087 (patch)
tree98a71465a15eb14567a6a33ed78d010ded787e3e /gcc/expr.cc
parent04ba1300407f106a6dd10d346f58a51d87e6d43e (diff)
downloadgcc-52366356fe7b638f66c4011b8a61fb6c22b08087.zip
gcc-52366356fe7b638f66c4011b8a61fb6c22b08087.tar.gz
gcc-52366356fe7b638f66c4011b8a61fb6c22b08087.tar.bz2
middle-end/118643 - ICE with out-of-bound decl access
When RTL expansion of an out-of-bound access of a register falls back to a BIT_FIELD_REF we have to ensure that's valid. The following avoids negative offsets by expanding through a stack temporary. PR middle-end/118643 * expr.cc (expand_expr_real_1): Avoid falling back to BIT_FIELD_REF expansion for negative offset. * gcc.dg/pr118643.c: New testcase.
Diffstat (limited to 'gcc/expr.cc')
-rw-r--r--gcc/expr.cc7
1 files changed, 4 insertions, 3 deletions
diff --git a/gcc/expr.cc b/gcc/expr.cc
index a310b2d..a06411e 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -11796,13 +11796,14 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
&& known_eq (GET_MODE_BITSIZE (DECL_MODE (base)), type_size))
return expand_expr (build1 (VIEW_CONVERT_EXPR, type, base),
target, tmode, modifier);
- if (TYPE_MODE (type) == BLKmode)
+ if (TYPE_MODE (type) == BLKmode || maybe_lt (offset, 0))
{
temp = assign_stack_temp (DECL_MODE (base),
GET_MODE_SIZE (DECL_MODE (base)));
store_expr (base, temp, 0, false, false);
- temp = adjust_address (temp, BLKmode, offset);
- set_mem_size (temp, int_size_in_bytes (type));
+ temp = adjust_address (temp, TYPE_MODE (type), offset);
+ if (TYPE_MODE (type) == BLKmode)
+ set_mem_size (temp, int_size_in_bytes (type));
return temp;
}
exp = build3 (BIT_FIELD_REF, type, base, TYPE_SIZE (type),