From c7c9468a6c1e21bb140f62d97d427352d90556bc Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Sun, 7 Jan 2018 00:43:27 -0700 Subject: [PATCH] Commit right version From-SVN: r256321 --- gcc/gimple-ssa-warn-restrict.c | 63 ++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 18 deletions(-) diff --git a/gcc/gimple-ssa-warn-restrict.c b/gcc/gimple-ssa-warn-restrict.c index 6384c5714ec..6979403a4f4 100644 --- a/gcc/gimple-ssa-warn-restrict.c +++ b/gcc/gimple-ssa-warn-restrict.c @@ -698,9 +698,10 @@ builtin_access::builtin_access (gcall *call, builtin_memref &dst, /* For string functions, adjust the size range of the source reference by the inverse boundaries of the offset (because - the higher the offset into the string the shorter its + the higher the offset into the string the shorter its length). */ - if (srcref->offrange[1] < srcref->sizrange[0]) + if (srcref->offrange[1] >= 0 + && srcref->offrange[1] < srcref->sizrange[0]) srcref->sizrange[0] -= srcref->offrange[1]; else srcref->sizrange[0] = 0; @@ -1134,30 +1135,53 @@ builtin_access::overlap () if (!dstref->base || !srcref->base) return false; - /* If the base object is an array adjust the lower bound of the offset - to be non-negative. */ + /* Set the access offsets. */ + acs.dstoff[0] = dstref->offrange[0]; + acs.dstoff[1] = dstref->offrange[1]; + + /* If the base object is an array adjust the bounds of the offset + to be non-negative and within the bounds of the array if possible. */ if (dstref->base && TREE_CODE (TREE_TYPE (dstref->base)) == ARRAY_TYPE) - acs.dstoff[0] = wi::smax (dstref->offrange[0], 0); - else - acs.dstoff[0] = dstref->offrange[0]; + { + if (acs.dstoff[0] < 0 && acs.dstoff[1] >= 0) + acs.dstoff[0] = 0; - acs.dstoff[1] = dstref->offrange[1]; + if (acs.dstoff[1] < acs.dstoff[0]) + { + if (tree size = TYPE_SIZE_UNIT (TREE_TYPE (dstref->base))) + acs.dstoff[1] = wi::umin (acs.dstoff[1], wi::to_offset (size)); + else + acs.dstoff[1] = wi::umin (acs.dstoff[1], maxobjsize); + } + } + + acs.srcoff[0] = srcref->offrange[0]; + acs.srcoff[1] = srcref->offrange[1]; if (srcref->base && TREE_CODE (TREE_TYPE (srcref->base)) == ARRAY_TYPE) - acs.srcoff[0] = wi::smax (srcref->offrange[0], 0); - else - acs.srcoff[0] = srcref->offrange[0]; + { + if (acs.srcoff[0] < 0 && acs.srcoff[1] >= 0) + acs.srcoff[0] = 0; - acs.srcoff[1] = srcref->offrange[1]; + if (tree size = TYPE_SIZE_UNIT (TREE_TYPE (srcref->base))) + acs.srcoff[1] = wi::umin (acs.srcoff[1], wi::to_offset (size)); + else if (acs.srcoff[1] < acs.srcoff[0]) + acs.srcoff[1] = wi::umin (acs.srcoff[1], maxobjsize); + } - /* When the lower bound of the offset is less that the upper bound - disregard it and use the inverse of the maximum object size - instead. The upper bound is the result of a negative offset - being represented as a large positive value. */ + /* When the upper bound of the offset is less than the lower bound + the former is the result of a negative offset being represented + as a large positive value or vice versa. The resulting range is + a union of two subranges: [MIN, UB] and [LB, MAX]. Since such + a union is not representable using the current data structure + replace it with the full range of offsets. */ if (acs.dstoff[1] < acs.dstoff[0]) - acs.dstoff[0] = -maxobjsize; + { + acs.dstoff[0] = -maxobjsize - 1; + acs.dstoff[1] = maxobjsize; + } /* Validate the offset and size of each reference on its own first. This is independent of whether or not the base objects are the @@ -1173,7 +1197,10 @@ builtin_access::overlap () /* Repeat the same as above but for the source offsets. */ if (acs.srcoff[1] < acs.srcoff[0]) - acs.srcoff[0] = -maxobjsize; + { + acs.srcoff[0] = -maxobjsize - 1; + acs.srcoff[1] = maxobjsize; + } maxoff = acs.srcoff[0] + srcref->sizrange[0]; if (maxobjsize < maxoff)