+2018-02-14 Martin Sebor <msebor@redhat.com>
+
+ PR tree-optimization/83698
+ * gimple-ssa-warn-restrict.c (builtin_memref::builtin_memref): For
+ arrays constrain the offset range to their bounds.
+ (builtin_access::strcat_overlap): Adjust the bounds of overlap offset.
+ (builtin_access::overlap): Avoid setting the size of overlap if it's
+ already been set.
+ (maybe_diag_overlap): Also consider arrays when deciding what values
+ of offsets to include in diagnostics.
+
2018-02-14 Martin Sebor <msebor@redhat.com>
PR c/84108
}
}
+ if (DECL_P (base) && TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE)
+ {
+ /* For array objects, where a negative offset wouldn't make
+ sense, use zero instead if the upper bound is positive. */
+ if (offrange[0] < 0 && offrange[1] > 0)
+ offrange[0] = 0;
+ }
+
if (size)
{
tree range[2];
return false;
/* When strcat overlap is certain it is always a single byte:
- the terminatinn NUL, regardless of offsets and sizes. When
+ the terminating NUL, regardless of offsets and sizes. When
overlap is only possible its range is [0, 1]. */
acs.ovlsiz[0] = dstref->sizrange[0] == dstref->sizrange[1] ? 1 : 0;
acs.ovlsiz[1] = 1;
- acs.ovloff[0] = (dstref->sizrange[0] + dstref->offrange[0]).to_shwi ();
- acs.ovloff[1] = (dstref->sizrange[1] + dstref->offrange[1]).to_shwi ();
- acs.sizrange[0] = wi::smax (acs.dstsiz[0], srcref->sizrange[0]).to_shwi ();
+ offset_int endoff = dstref->offrange[0] + dstref->sizrange[0];
+ if (endoff <= srcref->offrange[0])
+ acs.ovloff[0] = wi::smin (maxobjsize, srcref->offrange[0]).to_shwi ();
+ else
+ acs.ovloff[0] = wi::smin (maxobjsize, endoff).to_shwi ();
+
+ acs.sizrange[0] = wi::smax (wi::abs (endoff - srcref->offrange[0]) + 1,
+ srcref->sizrange[0]).to_shwi ();
+ if (dstref->offrange[0] == dstref->offrange[1])
+ {
+ if (srcref->offrange[0] == srcref->offrange[1])
+ acs.ovloff[1] = acs.ovloff[0];
+ else
+ acs.ovloff[1]
+ = wi::smin (maxobjsize,
+ srcref->offrange[1] + srcref->sizrange[1]).to_shwi ();
+ }
+ else
+ acs.ovloff[1]
+ = wi::smin (maxobjsize,
+ dstref->offrange[1] + dstref->sizrange[1]).to_shwi ();
+
+ if (acs.sizrange[0] == 0)
+ acs.sizrange[0] = 1;
acs.sizrange[1] = wi::smax (acs.dstsiz[1], srcref->sizrange[1]).to_shwi ();
return true;
}
/* Call the appropriate function to determine the overlap. */
if ((this->*detect_overlap) ())
{
- sizrange[0] = wi::smax (acs.dstsiz[0], srcref->sizrange[0]).to_shwi ();
- sizrange[1] = wi::smax (acs.dstsiz[1], srcref->sizrange[1]).to_shwi ();
+ if (!sizrange[1])
+ {
+ /* Unless the access size range has already been set, do so here. */
+ sizrange[0] = wi::smax (acs.dstsiz[0], srcref->sizrange[0]).to_shwi ();
+ sizrange[1] = wi::smax (acs.dstsiz[1], srcref->sizrange[1]).to_shwi ();
+ }
return true;
}
/* Use more concise wording when one of the offsets is unbounded
to avoid confusing the user with large and mostly meaningless
numbers. */
- bool open_range = ((dstref.offrange[0] == -maxobjsize - 1
- && dstref.offrange[1] == maxobjsize)
- || (srcref.offrange[0] == -maxobjsize - 1
- && srcref.offrange[1] == maxobjsize));
+ bool open_range;
+ if (DECL_P (dstref.base) && TREE_CODE (TREE_TYPE (dstref.base)) == ARRAY_TYPE)
+ open_range = ((dstref.offrange[0] == 0
+ && dstref.offrange[1] == maxobjsize)
+ || (srcref.offrange[0] == 0
+ && srcref.offrange[1] == maxobjsize));
+ else
+ open_range = ((dstref.offrange[0] == -maxobjsize - 1
+ && dstref.offrange[1] == maxobjsize)
+ || (srcref.offrange[0] == -maxobjsize - 1
+ && srcref.offrange[1] == maxobjsize));
if (sizrange[0] == sizrange[1] || sizrange[1] == 1)
{
(dg-require-effective-target): Change vsx_hw to p8vector_hw.
(dg-options): Change -maltivec -mvsx to -mpower8-vector.
+2018-02-14 Martin Sebor <msebor@redhat.com>
+
+ PR tree-optimization/83698
+ * gcc.dg/Wrestrict-7.c: New test.
+ * c-c++-common/Wrestrict.c: Adjust expected values for strcat.
+ * gcc.target/i386/chkp-stropt-17.c: Same.
+
2018-02-14 Martin Sebor <msebor@redhat.com>
PR c/84108
} while (0)
T (d, d); /* { dg-warning "source argument is the same as destination" "strcat" } */
- T (d, d + 1); /* { dg-warning "accessing 0 or more bytes at offsets 0 and 1 may overlap 1 byte" "strcat" } */
- T (d, d + 2); /* { dg-warning "accessing 0 or more bytes at offsets 0 and 2 may overlap 1 byte" "strcat" } */
- T (d, d + 999); /* { dg-warning "accessing 0 or more bytes at offsets 0 and 999 may overlap 1 byte" "strcat" } */
- T (d, d + -99); /* { dg-warning "accessing 0 or more bytes at offsets 0 and -99 may overlap 1 byte" "strcat" } */
+ T (d, d + 1); /* { dg-warning "accessing 2 or more bytes at offsets 0 and 1 may overlap 1 byte" "strcat" } */
+ T (d, d + 2); /* { dg-warning "accessing 3 or more bytes at offsets 0 and 2 may overlap 1 byte at offset 2" "strcat" } */
+ T (d, d + 999); /* { dg-warning "accessing 1000 or more bytes at offsets 0 and 999 may overlap 1 byte at offset 999" "strcat" } */
+
+ /* The source string must be at least 100 bytes in length for the copy
+ below to overlap. */
+ T (d, d + -99); /* { dg-warning "accessing 100 or more bytes at offsets 0 and -99 may overlap 1 byte" "strcat" } */
size_t n = unsigned_value ();
--- /dev/null
+/* PR tree-optimization/83698 - bogus offset in -Wrestrict messages for
+ strcat of unknown strings
+ { dg-do compile }
+ { dg-options "-O2 -Wrestrict -ftrack-macro-expansion=0" } */
+
+extern char* strcat (char*, const char*);
+
+void sink (char*);
+
+#define T(d, s) sink (strcat (d, s))
+
+extern char arr[];
+
+
+void test_strcat_array_cst_offset (void)
+{
+ T (arr, arr + 1); /* { dg-warning "accessing 2 or more bytes at offsets 0 and 1 may overlap 1 byte at offset 1" } */
+ T (arr, arr + 2); /* { dg-warning "accessing 3 or more bytes at offsets 0 and 2 may overlap 1 byte at offset 2" } */
+ T (arr, arr + 13); /* { dg-warning "accessing 14 or more bytes at offsets 0 and 13 may overlap 1 byte at offset 13" } */
+
+ T (arr + 1, arr); /* { dg-warning "accessing 2 or more bytes at offsets 1 and 0 may overlap 1 byte at offset 1" } */
+ T (arr + 17, arr + 11); /* { dg-warning "accessing 7 or more bytes at offsets 17 and 11 may overlap 1 byte at offset 17" } */
+ T (arr + 36, arr + 20); /* { dg-warning "accessing 17 or more bytes at offsets 36 and 20 may overlap 1 byte at offset 36" } */
+}
+
+void test_strcat_ptr_cst_offset (char *d)
+{
+ T (d - 12, d + 34); /* { dg-warning "accessing 47 or more bytes at offsets -12 and 34 may overlap 1 byte at offset 34" } */
+ T (d + 12, d + 34); /* { dg-warning "accessing 23 or more bytes at offsets 12 and 34 may overlap 1 byte at offset 34" } */
+ T (d + 20, d + 36); /* { dg-warning "accessing 17 or more bytes at offsets 20 and 36 may overlap 1 byte at offset 36" } */
+}
+
+void test_strcat_array_var_offset (int i, int j)
+{
+ T (arr + i, arr); /* { dg-warning "accessing 1 or more bytes at offsets \\\[0, \[0-9\]+] and 0 may overlap 1 byte at offset \\\[0, \[0-9\]+]" } */
+ T (arr, arr + j); /* { dg-warning "accessing 1 or more bytes at offsets 0 and \\\[0, \[0-9\]+] may overlap 1 byte at offset \\\[0, \[0-9\]+]" } */
+ T (arr + i, arr + j); /* { dg-warning "accessing 1 or more bytes at offsets \\\[0, \[0-9\]+] and \\\[0, \[0-9\]+] may overlap 1 byte at offset \\\[0, \[0-9\]+]" } */
+
+ T (arr + i, arr + 5); /* { dg-warning "accessing 6 or more bytes at offsets \\\[0, \[0-9\]+] and 5 may overlap 1 byte at offset \\\[5, \[0-9\]+]" } */
+ T (arr + 7, arr + j); /* { dg-warning "accessing 8 or more bytes at offsets 7 and \\\[0, \[0-9\]+] may overlap 1 byte at offset \\\[7, \[0-9\]+]" } */
+}
+
+void test_strcat_ptr_var_offset (char *d, int i, int j)
+{
+ T (d + i, d); /* { dg-warning "accessing \[0-9\]+ or more bytes at offsets \\\[-\[0-9\]+, \[0-9\]+] and 0 may overlap 1 byte at offset \\\[0, \[0-9\]+]" } */
+ T (d, d + j); /* { dg-warning "accessing \[0-9\]+ or more bytes at offsets 0 and \\\[-\[0-9\]+, \[0-9\]+] may overlap 1 byte at offset \\\[0, \[0-9\]+]" } */
+ T (d + i, d + j); /* { dg-warning "accessing 1 or more bytes at offsets \\\[-\[0-9\]+, \[0-9\]+] and \\\[-\[0-9\]+, \[0-9\]+] may overlap 1 byte at offset \\\[-\[0-9\]+, \[0-9\]+]" } */
+
+ T (d + i, d + 3); /* { dg-warning "accessing \[0-9\]+ or more bytes at offsets \\\[-\[0-9\]+, \[0-9\]+] and 3 may overlap 1 byte at offset \\\[3, \[0-9\]+]" } */
+ T (d + 9, d + j); /* { dg-warning "accessing \[0-9\]+ or more bytes at offsets 9 and \\\[-\[0-9\]+, \[0-9\]+] may overlap 1 byte at offset \\\[9, \[0-9\]+]" } */
+}
void test_strcat (int n)
{
- strcat (a, a + 3); /* { dg-warning ".strcat\.chkp. accessing 0 or more bytes at offsets 0 and 3 may overlap 1 byte" } */
+ strcat (a, a + 3); /* { dg-warning ".strcat\.chkp. accessing 4 or more bytes at offsets 0 and 3 may overlap 1 byte at offset 3" } */
}
void test_strncat (int n)