summaryrefslogtreecommitdiff
path: root/gcc/gimple-ssa-warn-restrict.c
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2018-03-09 19:06:26 +0000
committerJeff Law <law@gcc.gnu.org>2018-03-09 12:06:26 -0700
commit8286793a2b050a9c51501b0b3737ff73c71d189d (patch)
treecc73b1389589bc7c3249fa1b253487085b72d0a7 /gcc/gimple-ssa-warn-restrict.c
parent998fd1413977a70cfeb7bf9180f3b462a7731237 (diff)
re PR tree-optimization/84526 (ICE in generic_overlap at gcc/gimple-ssa-warn-restrict.c:927 since r257860)
gcc/ChangeLog: PR tree-optimization/84526 * gimple-ssa-warn-restrict.c (builtin_memref::set_base_and_offset): Remove dead code. (builtin_access::generic_overlap): Be prepared to handle non-array base objects. gcc/testsuite/ChangeLog: PR tree-optimization/84526 * gcc.dg/Wrestrict-10.c: New test. * gcc.dg/Wrestrict-11.c: New test. From-SVN: r258394
Diffstat (limited to 'gcc/gimple-ssa-warn-restrict.c')
-rw-r--r--gcc/gimple-ssa-warn-restrict.c46
1 files changed, 30 insertions, 16 deletions
diff --git a/gcc/gimple-ssa-warn-restrict.c b/gcc/gimple-ssa-warn-restrict.c
index df775062758..25cc032c2da 100644
--- a/gcc/gimple-ssa-warn-restrict.c
+++ b/gcc/gimple-ssa-warn-restrict.c
@@ -396,6 +396,9 @@ builtin_memref::set_base_and_offset (tree expr)
if (TREE_CODE (expr) == ADDR_EXPR)
expr = TREE_OPERAND (expr, 0);
+ /* Stash the reference for offset validation. */
+ ref = expr;
+
poly_int64 bitsize, bitpos;
tree var_off;
machine_mode mode;
@@ -409,23 +412,33 @@ builtin_memref::set_base_and_offset (tree expr)
base = get_inner_reference (expr, &bitsize, &bitpos, &var_off,
&mode, &sign, &reverse, &vol);
+ /* get_inner_reference is not expected to return null. */
+ gcc_assert (base != NULL);
+
poly_int64 bytepos = exact_div (bitpos, BITS_PER_UNIT);
- HOST_WIDE_INT const_off;
- if (!base || !bytepos.is_constant (&const_off))
+ /* Convert the poly_int64 offset to to offset_int. The offset
+ should be constant but be prepared for it not to be just in
+ case. */
+ offset_int cstoff;
+ if (bytepos.is_constant (&cstoff))
{
- base = get_base_address (TREE_OPERAND (expr, 0));
- return;
- }
+ offrange[0] += cstoff;
+ offrange[1] += cstoff;
- offrange[0] += const_off;
- offrange[1] += const_off;
+ /* Besides the reference saved above, also stash the offset
+ for validation. */
+ if (TREE_CODE (expr) == COMPONENT_REF)
+ refoff = cstoff;
+ }
+ else
+ offrange[1] += maxobjsize;
if (var_off)
{
if (TREE_CODE (var_off) == INTEGER_CST)
{
- offset_int cstoff = wi::to_offset (var_off);
+ cstoff = wi::to_offset (var_off);
offrange[0] += cstoff;
offrange[1] += cstoff;
}
@@ -433,13 +446,6 @@ builtin_memref::set_base_and_offset (tree expr)
offrange[1] += maxobjsize;
}
- /* Stash the reference for offset validation. */
- ref = expr;
-
- /* Also stash the constant offset for offset validation. */
- if (TREE_CODE (expr) == COMPONENT_REF)
- refoff = const_off;
-
if (TREE_CODE (base) == MEM_REF)
{
tree memrefoff = TREE_OPERAND (base, 1);
@@ -918,12 +924,20 @@ builtin_access::generic_overlap ()
if (!overlap_certain)
{
if (!dstref->strbounded_p && !depends_p)
+ /* Memcpy only considers certain overlap. */
return false;
/* There's no way to distinguish an access to the same member
of a structure from one to two distinct members of the same
structure. Give up to avoid excessive false positives. */
- tree basetype = TREE_TYPE (TREE_TYPE (dstref->base));
+ tree basetype = TREE_TYPE (dstref->base);
+
+ if (POINTER_TYPE_P (basetype))
+ basetype = TREE_TYPE (basetype);
+ else
+ while (TREE_CODE (basetype) == ARRAY_TYPE)
+ basetype = TREE_TYPE (basetype);
+
if (RECORD_OR_UNION_TYPE_P (basetype))
return false;
}