From c25b504636fec7bf8f181a84af83a52757ba7e89 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Thu, 17 Dec 2020 09:24:11 -0500 Subject: [PATCH] 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 +++++++++++++++++++++++++ gcc/testsuite/gcc.dg/pr97750.c | 21 +++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr97750.c diff --git a/gcc/range-op.cc b/gcc/range-op.cc index 36f9fd66cb3..a473f33169d 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 ()) diff --git a/gcc/testsuite/gcc.dg/pr97750.c b/gcc/testsuite/gcc.dg/pr97750.c new file mode 100644 index 00000000000..822b53abcff --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr97750.c @@ -0,0 +1,21 @@ +/* PR tree-optimization/97750 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wall -Wextra" } */ + +char CopyPlane_src; +long CopyPlane_copy_pitch; +char *CopyFromUswc_src; +int CopyFromUswc_height; +void CopyPlane(char *dst) { + __builtin_memcpy(dst, &CopyPlane_src, CopyPlane_copy_pitch); +} +void CopyFromUswc(long src_pitch) { + char *dst; + for (; CopyFromUswc_height;) { + unsigned unaligned = (long)CopyFromUswc_src; + if (unaligned) + CopyPlane(&dst[unaligned]); /* { dg-warning "may be used uninitialized" } */ + CopyFromUswc_src += src_pitch; + } +} + -- 2.30.2