https://gcc.gnu.org/g:4291071a6aa3b50800ad5fc70b5fb83cb9398237
commit r16-661-g4291071a6aa3b50800ad5fc70b5fb83cb9398237 Author: Andrew MacLeod <amacl...@redhat.com> Date: Thu May 15 11:06:05 2025 -0400 Check for casts becoming UNDEFINED. In various situations a cast that is ultimately unreahcable may produce an UNDEFINED result, and we can't check the bounds in this case. PR tree-optimization/120277 gcc/ * range-op-ptr.cc (operator_cast::fold_range): Check if the cast if UNDEFINED before setting bounds. gcc/testsuite/ * gcc.dg/pr120277.c: New. Diff: --- gcc/range-op-ptr.cc | 10 ++++++++-- gcc/testsuite/gcc.dg/pr120277.c | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/gcc/range-op-ptr.cc b/gcc/range-op-ptr.cc index 36e9dfc20baf..6aadc9cf2c95 100644 --- a/gcc/range-op-ptr.cc +++ b/gcc/range-op-ptr.cc @@ -602,8 +602,14 @@ operator_cast::fold_range (prange &r, tree type, int_range<2> tmp = inner; tree pointer_uint_type = make_unsigned_type (TYPE_PRECISION (type)); range_cast (tmp, pointer_uint_type); - r.set (type, tmp.lower_bound (), tmp.upper_bound ()); - r.update_bitmask (tmp.get_bitmask ()); + // Casts may cause ranges to become UNDEFINED based on bitmasks. + if (tmp.undefined_p ()) + r.set_varying (type); + else + { + r.set (type, tmp.lower_bound (), tmp.upper_bound ()); + r.update_bitmask (tmp.get_bitmask ()); + } return true; } diff --git a/gcc/testsuite/gcc.dg/pr120277.c b/gcc/testsuite/gcc.dg/pr120277.c new file mode 100644 index 000000000000..f291e920db16 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr120277.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int a, b; +int c(int d, long e) { + switch (d) { + case 129: + a = 1; + case 128: + break; + default: + return 1; + } + *(int *)e = 0; +} +void f(int d, long e) { c(d, e); } +void g() { + int h = b * sizeof(int); + f(h + 7, h); +} +void main() {}