From c25b504636fec7bf8f181a84af83a52757ba7e89 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Thu, 17 Dec 2020 09:24:11 -0500 Subject: Fix trap in pointer conversion in op1_range. Processing op1_range for conversion between a non-pointer and pointer shouldnt do any fancy math. gcc/ PR tree-optimization/97750 * range-op.cc (operator_cast::op1_range): Handle pointers better. gcc/testsuite/ * gcc.dg/pr97750.c: New. --- gcc/range-op.cc | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'gcc/range-op.cc') diff --git a/gcc/range-op.cc b/gcc/range-op.cc index 36f9fd6..a473f33 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -1850,6 +1850,31 @@ operator_cast::op1_range (irange &r, tree type, tree lhs_type = lhs.type (); gcc_checking_assert (types_compatible_p (op2.type(), type)); + // If we are calculating a pointer, shortcut to what we really care about. + if (POINTER_TYPE_P (type)) + { + // Conversion from other pointers or a constant (including 0/NULL) + // are straightforward. + if (POINTER_TYPE_P (lhs.type ()) + || (lhs.singleton_p () + && TYPE_PRECISION (lhs.type ()) >= TYPE_PRECISION (type))) + { + r = lhs; + range_cast (r, type); + } + else + { + // If the LHS is not a pointer nor a singleton, then it is + // either VARYING or non-zero. + if (!lhs.contains_p (build_zero_cst (lhs.type ()))) + r.set_nonzero (type); + else + r.set_varying (type); + } + r.intersect (op2); + return true; + } + if (truncating_cast_p (op2, lhs)) { if (lhs.varying_p ()) -- cgit v1.1