diff options
author | Andrew MacLeod <amacleod@redhat.com> | 2020-12-17 09:24:11 -0500 |
---|---|---|
committer | Andrew MacLeod <amacleod@redhat.com> | 2020-12-17 09:38:31 -0500 |
commit | c25b504636fec7bf8f181a84af83a52757ba7e89 (patch) | |
tree | 90aad777bbcc9ba96b68e7cd67db802a9bc30f7c /gcc/range-op.cc | |
parent | d592ee3ada825fe8c022e1d5fa30562b17fc3221 (diff) | |
download | gcc-c25b504636fec7bf8f181a84af83a52757ba7e89.zip gcc-c25b504636fec7bf8f181a84af83a52757ba7e89.tar.gz gcc-c25b504636fec7bf8f181a84af83a52757ba7e89.tar.bz2 |
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.
Diffstat (limited to 'gcc/range-op.cc')
-rw-r--r-- | gcc/range-op.cc | 25 |
1 files changed, 25 insertions, 0 deletions
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 ()) |