From: Richard Biener Date: Mon, 27 Jan 2025 10:28:47 +0000 (+0100) Subject: middle-end/118643 - ICE with out-of-bound decl access X-Git-Tag: basepoints/gcc-16~2327 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=52366356fe7b638f66c4011b8a61fb6c22b08087;p=thirdparty%2Fgcc.git 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. --- diff --git a/gcc/expr.cc b/gcc/expr.cc index a310b2d9131..a06411e1c27 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), diff --git a/gcc/testsuite/gcc.dg/pr118643.c b/gcc/testsuite/gcc.dg/pr118643.c new file mode 100644 index 00000000000..ff2b081ae0b --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr118643.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O" } */ + +typedef __attribute__((__vector_size__(1))) unsigned char V; + +V x; +void foo() +{ + V v = x; + x = *(V *)(&v - 1); +}