PR tree-optimization/89350 - Wrong -Wstringop-overflow= warning since r261518
gcc/ChangeLog: PR tree-optimization/89350 * builtins.c (compute_objsize): Also ignore offsets whose upper bound is negative. * gimple-ssa-warn-restrict.c (builtin_memref): Add new member. (builtin_memref::builtin_memref): Initialize new member. Allow EXPR to be null. (builtin_memref::extend_offset_range): Replace local with a member. Avoid assuming pointer offsets are unsigned. (builtin_memref::set_base_and_offset): Determine base object before computing offset range. (builtin_access::builtin_access): Handle memset. (builtin_access::generic_overlap): Replace local with a member. (builtin_access::strcat_overlap): Same. (builtin_access::overlap): Same. (maybe_diag_overlap): Same. (maybe_diag_access_bounds): Same. (wrestrict_dom_walker::check_call): Handle memset. (check_bounds_or_overlap): Same. gcc/testsuite/ChangeLog: PR tree-optimization/89350 * gcc.dg/Wstringop-overflow.c: Xfail overly ambitious tests. * gcc.dg/Wstringop-overflow-11.c: New test. * gcc.dg/Wstringop-overflow-12.c: New test. * gcc.dg/pr89350.c: New test. * gcc.dg/pr40340-1.c: Adjust expected warning. * gcc.dg/pr40340-2.c: Same. * gcc.dg/pr40340-4.c: Same. * gcc.dg/pr40340-5.c: Same. From-SVN: r269867
This commit is contained in:
parent
11bf9a075a
commit
a411ae9b35
@ -1,3 +1,24 @@
|
||||
2019-03-21 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR tree-optimization/89350
|
||||
* builtins.c (compute_objsize): Also ignore offsets whose upper
|
||||
bound is negative.
|
||||
* gimple-ssa-warn-restrict.c (builtin_memref): Add new member.
|
||||
(builtin_memref::builtin_memref): Initialize new member.
|
||||
Allow EXPR to be null.
|
||||
(builtin_memref::extend_offset_range): Replace local with a member.
|
||||
Avoid assuming pointer offsets are unsigned.
|
||||
(builtin_memref::set_base_and_offset): Determine base object
|
||||
before computing offset range.
|
||||
(builtin_access::builtin_access): Handle memset.
|
||||
(builtin_access::generic_overlap): Replace local with a member.
|
||||
(builtin_access::strcat_overlap): Same.
|
||||
(builtin_access::overlap): Same.
|
||||
(maybe_diag_overlap): Same.
|
||||
(maybe_diag_access_bounds): Same.
|
||||
(wrestrict_dom_walker::check_call): Handle memset.
|
||||
(check_bounds_or_overlap): Same.
|
||||
|
||||
2019-03-21 Jan Hubicka <hubicka@ucw.cz>
|
||||
Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
|
@ -3650,7 +3650,8 @@ compute_objsize (tree dest, int ostype)
|
||||
/* Ignore negative offsets for now. For others,
|
||||
use the lower bound as the most optimistic
|
||||
estimate of the (remaining)size. */
|
||||
if (wi::sign_mask (min))
|
||||
if (wi::sign_mask (min)
|
||||
|| wi::sign_mask (max))
|
||||
;
|
||||
else if (wi::ltu_p (min, wisiz))
|
||||
return wide_int_to_tree (TREE_TYPE (size),
|
||||
|
@ -147,6 +147,9 @@ struct builtin_memref
|
||||
/* The size range of the access to this reference. */
|
||||
offset_int sizrange[2];
|
||||
|
||||
/* Cached result of get_max_objsize(). */
|
||||
const offset_int maxobjsize;
|
||||
|
||||
/* True for "bounded" string functions like strncat, and strncpy
|
||||
and their variants that specify either an exact or upper bound
|
||||
on the size of the accesses they perform. For strncat both
|
||||
@ -233,6 +236,7 @@ builtin_memref::builtin_memref (tree expr, tree size)
|
||||
refoff (HOST_WIDE_INT_MIN),
|
||||
offrange (),
|
||||
sizrange (),
|
||||
maxobjsize (tree_to_shwi (max_object_size ())),
|
||||
strbounded_p ()
|
||||
{
|
||||
/* Unfortunately, wide_int default ctor is a no-op so array members
|
||||
@ -240,7 +244,8 @@ builtin_memref::builtin_memref (tree expr, tree size)
|
||||
offrange[0] = offrange[1] = 0;
|
||||
sizrange[0] = sizrange[1] = 0;
|
||||
|
||||
const offset_int maxobjsize = tree_to_shwi (max_object_size ());
|
||||
if (!expr)
|
||||
return;
|
||||
|
||||
/* Find the BASE object or pointer referenced by EXPR and set
|
||||
the offset range OFFRANGE in the process. */
|
||||
@ -292,13 +297,13 @@ builtin_memref::builtin_memref (tree expr, tree size)
|
||||
}
|
||||
}
|
||||
|
||||
/* Ctor helper to set or extend OFFRANGE based on the OFFSET argument. */
|
||||
/* Ctor helper to set or extend OFFRANGE based on the OFFSET argument.
|
||||
Pointer offsets are represented as unsigned sizetype but must be
|
||||
treated as signed. */
|
||||
|
||||
void
|
||||
builtin_memref::extend_offset_range (tree offset)
|
||||
{
|
||||
const offset_int maxobjsize = tree_to_shwi (max_object_size ());
|
||||
|
||||
if (TREE_CODE (offset) == INTEGER_CST)
|
||||
{
|
||||
offset_int off = int_cst_value (offset);
|
||||
@ -312,36 +317,57 @@ builtin_memref::extend_offset_range (tree offset)
|
||||
|
||||
if (TREE_CODE (offset) == SSA_NAME)
|
||||
{
|
||||
/* A pointer offset is represented as sizetype but treated
|
||||
as signed. */
|
||||
wide_int min, max;
|
||||
value_range_kind rng = get_range_info (offset, &min, &max);
|
||||
if (rng == VR_RANGE)
|
||||
if (rng == VR_ANTI_RANGE && wi::lts_p (max, min))
|
||||
{
|
||||
/* Convert an anti-range whose upper bound is less than
|
||||
its lower bound to a signed range. */
|
||||
offrange[0] += offset_int::from (max + 1, SIGNED);
|
||||
offrange[1] += offset_int::from (min - 1, SIGNED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rng == VR_RANGE
|
||||
&& (DECL_P (base) || wi::lts_p (min, max)))
|
||||
{
|
||||
/* Preserve the bounds of the range for an offset into
|
||||
a known object (it may be adjusted later relative to
|
||||
a constant offset from its beginning). Otherwise use
|
||||
the bounds only when they are ascending when treated
|
||||
as signed. */
|
||||
offrange[0] += offset_int::from (min, SIGNED);
|
||||
offrange[1] += offset_int::from (max, SIGNED);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Handle an anti-range the same as no range at all. */
|
||||
gimple *stmt = SSA_NAME_DEF_STMT (offset);
|
||||
tree type;
|
||||
if (is_gimple_assign (stmt)
|
||||
&& gimple_assign_rhs_code (stmt) == NOP_EXPR
|
||||
&& (type = TREE_TYPE (gimple_assign_rhs1 (stmt)))
|
||||
&& INTEGRAL_TYPE_P (type))
|
||||
{
|
||||
tree_code code = gimple_assign_rhs_code (stmt);
|
||||
if (code == NOP_EXPR)
|
||||
{
|
||||
/* Use the bounds of the type of the NOP_EXPR operand
|
||||
even if it's signed. The result doesn't trigger
|
||||
warnings but makes their output more readable. */
|
||||
offrange[0] += wi::to_offset (TYPE_MIN_VALUE (type));
|
||||
offrange[1] += wi::to_offset (TYPE_MAX_VALUE (type));
|
||||
}
|
||||
else
|
||||
offrange[1] += maxobjsize;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
offrange[1] += maxobjsize;
|
||||
const offset_int maxoff = tree_to_shwi (max_object_size ()) >> 1;
|
||||
const offset_int minoff = -maxoff - 1;
|
||||
|
||||
offrange[0] += minoff;
|
||||
offrange[1] += maxoff;
|
||||
}
|
||||
|
||||
/* Determines the base object or pointer of the reference EXPR
|
||||
@ -350,7 +376,7 @@ builtin_memref::extend_offset_range (tree offset)
|
||||
void
|
||||
builtin_memref::set_base_and_offset (tree expr)
|
||||
{
|
||||
const offset_int maxobjsize = tree_to_shwi (max_object_size ());
|
||||
tree offset = NULL_TREE;
|
||||
|
||||
if (TREE_CODE (expr) == SSA_NAME)
|
||||
{
|
||||
@ -377,9 +403,7 @@ builtin_memref::set_base_and_offset (tree expr)
|
||||
else if (code == POINTER_PLUS_EXPR)
|
||||
{
|
||||
expr = gimple_assign_rhs1 (stmt);
|
||||
|
||||
tree offset = gimple_assign_rhs2 (stmt);
|
||||
extend_offset_range (offset);
|
||||
offset = gimple_assign_rhs2 (stmt);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -389,6 +413,12 @@ builtin_memref::set_base_and_offset (tree expr)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME: Handle PHI nodes in case like:
|
||||
_12 = &MEM[(void *)&a + 2B] + _10;
|
||||
|
||||
<bb> [local count: 1073741824]:
|
||||
# prephitmp_13 = PHI <_12, &MEM[(void *)&a + 2B]>
|
||||
memcpy (prephitmp_13, p_7(D), 6); */
|
||||
base = expr;
|
||||
return;
|
||||
}
|
||||
@ -416,6 +446,9 @@ builtin_memref::set_base_and_offset (tree expr)
|
||||
/* get_inner_reference is not expected to return null. */
|
||||
gcc_assert (base != NULL);
|
||||
|
||||
if (offset)
|
||||
extend_offset_range (offset);
|
||||
|
||||
poly_int64 bytepos = exact_div (bitpos, BITS_PER_UNIT);
|
||||
|
||||
/* Convert the poly_int64 offset to offset_int. The offset
|
||||
@ -471,7 +504,8 @@ builtin_memref::set_base_and_offset (tree expr)
|
||||
tree
|
||||
builtin_memref::offset_out_of_bounds (int strict, offset_int ooboff[2]) const
|
||||
{
|
||||
const offset_int maxobjsize = tree_to_shwi (max_object_size ());
|
||||
if (!ptr)
|
||||
return NULL_TREE;
|
||||
|
||||
/* A temporary, possibly adjusted, copy of the offset range. */
|
||||
offset_int offrng[2] = { offrange[0], offrange[1] };
|
||||
@ -606,6 +640,14 @@ builtin_access::builtin_access (gimple *call, builtin_memref &dst,
|
||||
detect_overlap = &builtin_access::no_overlap;
|
||||
break;
|
||||
|
||||
case BUILT_IN_MEMSET:
|
||||
case BUILT_IN_MEMSET_CHK:
|
||||
/* For memset there is never any overlap to check for. */
|
||||
ostype = 0;
|
||||
depends_p = false;
|
||||
detect_overlap = &builtin_access::no_overlap;
|
||||
break;
|
||||
|
||||
case BUILT_IN_STPNCPY:
|
||||
case BUILT_IN_STPNCPY_CHK:
|
||||
case BUILT_IN_STRNCPY:
|
||||
@ -640,7 +682,7 @@ builtin_access::builtin_access (gimple *call, builtin_memref &dst,
|
||||
return;
|
||||
}
|
||||
|
||||
const offset_int maxobjsize = tree_to_shwi (max_object_size ());
|
||||
const offset_int maxobjsize = dst.maxobjsize;
|
||||
|
||||
/* Try to determine the size of the base object. compute_objsize
|
||||
expects a pointer so create one if BASE is a non-pointer object. */
|
||||
@ -659,7 +701,7 @@ builtin_access::builtin_access (gimple *call, builtin_memref &dst,
|
||||
dst.basesize = maxobjsize;
|
||||
}
|
||||
|
||||
if (src.basesize < 0)
|
||||
if (src.base && src.basesize < 0)
|
||||
{
|
||||
addr = src.base;
|
||||
if (!POINTER_TYPE_P (TREE_TYPE (addr)))
|
||||
@ -845,7 +887,7 @@ builtin_access::generic_overlap ()
|
||||
|
||||
gcc_assert (dstref->base == srcref->base);
|
||||
|
||||
const offset_int maxobjsize = tree_to_shwi (max_object_size ());
|
||||
const offset_int maxobjsize = acs.dstref->maxobjsize;
|
||||
|
||||
offset_int maxsize = dstref->basesize < 0 ? maxobjsize : dstref->basesize;
|
||||
gcc_assert (maxsize <= maxobjsize);
|
||||
@ -1054,7 +1096,7 @@ builtin_access::strcat_overlap ()
|
||||
|
||||
gcc_assert (dstref->base == srcref->base);
|
||||
|
||||
const offset_int maxobjsize = tree_to_shwi (max_object_size ());
|
||||
const offset_int maxobjsize = acs.dstref->maxobjsize;
|
||||
|
||||
gcc_assert (dstref->base && dstref->base == srcref->base);
|
||||
|
||||
@ -1191,7 +1233,7 @@ builtin_access::overlap ()
|
||||
{
|
||||
builtin_access &acs = *this;
|
||||
|
||||
const offset_int maxobjsize = tree_to_shwi (max_object_size ());
|
||||
const offset_int maxobjsize = dstref->maxobjsize;
|
||||
|
||||
acs.sizrange[0] = wi::smax (dstref->sizrange[0],
|
||||
srcref->sizrange[0]).to_shwi ();
|
||||
@ -1372,7 +1414,7 @@ maybe_diag_overlap (location_t loc, gimple *call, builtin_access &acs)
|
||||
"[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
|
||||
ovloff[0], ovloff[1]);
|
||||
|
||||
const offset_int maxobjsize = tree_to_shwi (max_object_size ());
|
||||
const offset_int maxobjsize = dstref.maxobjsize;
|
||||
bool must_overlap = ovlsiz[0] > 0;
|
||||
|
||||
if (ovlsiz[1] == 0)
|
||||
@ -1581,7 +1623,7 @@ static bool
|
||||
maybe_diag_access_bounds (location_t loc, gimple *call, tree func, int strict,
|
||||
const builtin_memref &ref, bool do_warn)
|
||||
{
|
||||
const offset_int maxobjsize = tree_to_shwi (max_object_size ());
|
||||
const offset_int maxobjsize = ref.maxobjsize;
|
||||
|
||||
/* Check for excessive size first and regardless of warning options
|
||||
since the result is used to make codegen decisions. */
|
||||
@ -1690,8 +1732,6 @@ maybe_diag_access_bounds (location_t loc, gimple *call, tree func, int strict,
|
||||
}
|
||||
else if (oobref == ref.base)
|
||||
{
|
||||
const offset_int maxobjsize = tree_to_shwi (max_object_size ());
|
||||
|
||||
/* True when the offset formed by an access to the reference
|
||||
is out of bounds, rather than the initial offset wich is
|
||||
in bounds. This implies access past the end. */
|
||||
@ -1814,6 +1854,12 @@ wrestrict_dom_walker::check_call (gimple *call)
|
||||
bnd_idx = 2;
|
||||
break;
|
||||
|
||||
case BUILT_IN_MEMSET:
|
||||
case BUILT_IN_MEMSET_CHK:
|
||||
dst_idx = 0;
|
||||
bnd_idx = 2;
|
||||
break;
|
||||
|
||||
case BUILT_IN_STPCPY:
|
||||
case BUILT_IN_STPCPY_CHK:
|
||||
case BUILT_IN_STRCPY:
|
||||
@ -1844,14 +1890,14 @@ wrestrict_dom_walker::check_call (gimple *call)
|
||||
|
||||
/* DST and SRC can be null for a call with an insufficient number
|
||||
of arguments to a built-in function declared without a protype. */
|
||||
if (!dst || !src)
|
||||
if (!dst || (src_idx < nargs && !src))
|
||||
return;
|
||||
|
||||
/* DST, SRC, or DSTWR can also have the wrong type in a call to
|
||||
a function declared without a prototype. Avoid checking such
|
||||
invalid calls. */
|
||||
if (TREE_CODE (TREE_TYPE (dst)) != POINTER_TYPE
|
||||
|| TREE_CODE (TREE_TYPE (src)) != POINTER_TYPE
|
||||
|| (src && TREE_CODE (TREE_TYPE (src)) != POINTER_TYPE)
|
||||
|| (dstwr && !INTEGRAL_TYPE_P (TREE_TYPE (dstwr))))
|
||||
return;
|
||||
|
||||
@ -1901,15 +1947,23 @@ check_bounds_or_overlap (gimple *call, tree dst, tree src, tree dstsize,
|
||||
return OPT_Warray_bounds;
|
||||
}
|
||||
|
||||
bool check_overlap
|
||||
= (warn_restrict
|
||||
&& (bounds_only
|
||||
|| (DECL_FUNCTION_CODE (func) != BUILT_IN_MEMMOVE
|
||||
&& DECL_FUNCTION_CODE (func) != BUILT_IN_MEMMOVE_CHK)));
|
||||
|
||||
if (!check_overlap)
|
||||
if (!warn_restrict || bounds_only || !src)
|
||||
return 0;
|
||||
|
||||
if (!bounds_only)
|
||||
{
|
||||
switch (DECL_FUNCTION_CODE (func))
|
||||
{
|
||||
case BUILT_IN_MEMMOVE:
|
||||
case BUILT_IN_MEMMOVE_CHK:
|
||||
case BUILT_IN_MEMSET:
|
||||
case BUILT_IN_MEMSET_CHK:
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (operand_equal_p (dst, src, 0))
|
||||
{
|
||||
/* Issue -Wrestrict unless the pointers are null (those do
|
||||
|
@ -1,3 +1,16 @@
|
||||
2019-03-21 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR tree-optimization/89350
|
||||
* gcc.dg/Warray-bounds-40.c: Remove an xfail.
|
||||
* gcc.dg/Wstringop-overflow.c: Xfail overly ambitious tests.
|
||||
* gcc.dg/Wstringop-overflow-11.c: New test.
|
||||
* gcc.dg/Wstringop-overflow-12.c: New test.
|
||||
* gcc.dg/pr89350.c: New test.
|
||||
* gcc.dg/pr40340-1.c: Adjust expected warning.
|
||||
* gcc.dg/pr40340-2.c: Same.
|
||||
* gcc.dg/pr40340-4.c: Same.
|
||||
* gcc.dg/pr40340-5.c: Same.
|
||||
|
||||
2019-03-21 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR lto/89692
|
||||
|
@ -42,7 +42,7 @@ void test_memmove (void)
|
||||
|
||||
void test_memset (void)
|
||||
{
|
||||
memset (d, 0, SIZE_MAX - 2); /* { dg-warning ".memset. pointer overflow between offset 0 and size \[0-9\]+ \\\[-Warray-bounds" "bug" { xfail *-*-* } } */
|
||||
memset (d, 0, SIZE_MAX - 2); /* { dg-warning ".memset. pointer overflow between offset 0 and size \[0-9\]+ \\\[-Warray-bounds" } */
|
||||
}
|
||||
|
||||
|
||||
|
321
gcc/testsuite/gcc.dg/Wstringop-overflow-11.c
Normal file
321
gcc/testsuite/gcc.dg/Wstringop-overflow-11.c
Normal file
@ -0,0 +1,321 @@
|
||||
/* PR tree-optimization/89350 - Wrong -Wstringop-overflow warning
|
||||
on a variable offset from the end of an array
|
||||
Test exercising -Wstringop-truncation with -Wall.
|
||||
-Wstringop-truncation is disabled to avoid warnings for strncpy
|
||||
calls whose bound matches the size of the destination getting
|
||||
in the way of -Wstringop-overflow.
|
||||
{ dg-do compile }
|
||||
{ dg-options "-O2 -Wall -Wno-stringop-truncation -ftrack-macro-expansion=0" } */
|
||||
|
||||
#include "range.h"
|
||||
|
||||
extern void* memcpy (void*, const void*, size_t);
|
||||
extern void* memset (void*, int, size_t);
|
||||
extern char* strcpy (char*, const char*);
|
||||
extern char* strncpy (char*, const char*, size_t);
|
||||
|
||||
void sink (void*);
|
||||
|
||||
#define CAT(pfx, line) pfx ## line
|
||||
#define CONCAT(pfx, line) CAT (pfx, line)
|
||||
#define UNIQ_NAME(pfx) CONCAT (pfx, __LINE__)
|
||||
|
||||
/* Exercise a call to memset with a distinct destination object each
|
||||
time to prevent GCC from reusing the destination pointer in later
|
||||
tests. */
|
||||
#define T(off1, off2, n) \
|
||||
do { \
|
||||
extern char UNIQ_NAME (ga)[7]; \
|
||||
char *d = UNIQ_NAME (ga) + off1; \
|
||||
d += off2; \
|
||||
memset (d, 0, n); \
|
||||
sink (d); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* Exercise calls to memset with a destination pointer pointing to
|
||||
an array plus constant offset plus variable offset, in that order. */
|
||||
|
||||
void test_memset_array_cst_range_off (void)
|
||||
{
|
||||
T (1, SR (-7, 7), 7);
|
||||
T (1, SR (-1, 1), 7);
|
||||
T (1, SR (-1, 1), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (1, SR ( 1, 2), 1);
|
||||
T (1, SR ( 1, 2), 5);
|
||||
|
||||
T (1, SR ( 0, 1), 6);
|
||||
T (1, UR ( 1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
|
||||
T (2, SR (-7, 7), 7);
|
||||
T (2, SR (-2, 7), 7);
|
||||
T (2, SR (-1, 1), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (2, SR (-1, 1), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (2, SR ( 1, 2), 1);
|
||||
T (2, SR ( 1, 2), 3);
|
||||
T (2, SR ( 1, 2), 4);
|
||||
T (2, SR ( 1, 2), 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
|
||||
T (2, SR ( 0, 1), 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" { xfail *-*-* } } */
|
||||
T (2, UR ( 1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (7, UR (-7, 0), 7);
|
||||
T (7, UR (-7, 0), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (7, UR (-3, 2), 3);
|
||||
T (7, UR (-2, 2), 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
|
||||
/* Exercise calls to memset with a destination pointer pointing to
|
||||
an array plus variable offset plus constant offset. */
|
||||
|
||||
void test_memset_array_range_cst_off (void)
|
||||
{
|
||||
T (SR (-7, 7), 1, 7);
|
||||
T (SR (-1, 1), 1, 7);
|
||||
T (SR (-1, 1), 1, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" { xfail *-*-*} } */
|
||||
T (SR ( 1, 2), 1, 1);
|
||||
T (SR ( 1, 2), 1, 5);
|
||||
|
||||
T (SR ( 0, 1), 1, 6);
|
||||
T (UR ( 1, 2), 1, 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
|
||||
T (SR (-7, 7), 2, 7);
|
||||
T (SR (-1, 1), 2, 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (SR (-1, 1), 2, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (SR ( 1, 2), 2, 1);
|
||||
T (SR ( 1, 2), 2, 3);
|
||||
T (SR ( 1, 2), 2, 4);
|
||||
T (SR ( 1, 2), 2, 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
|
||||
T (SR ( 0, 1), 2, 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
|
||||
T (UR ( 1, 2), 2, 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
|
||||
void test_memset_array_range_range_off (void)
|
||||
{
|
||||
T (UR (0, 1), UR (0, 1), 7);
|
||||
T (UR (3, 5), UR (2, 7), 1);
|
||||
T (UR (3, 7), UR (2, 9), 2);
|
||||
T (UR (3, 9), UR (2, 9), 3); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (UR (0, 1), UR (1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
|
||||
#undef T
|
||||
#define T(off1, off2, n) \
|
||||
do { \
|
||||
extern char UNIQ_NAME (ga)[7]; \
|
||||
char *d = UNIQ_NAME (ga) + off1; \
|
||||
d += off2; \
|
||||
memcpy (d, s, n); \
|
||||
sink (d); \
|
||||
} while (0)
|
||||
|
||||
|
||||
void test_memcpy_array_cst_range_off (const void *s)
|
||||
{
|
||||
T (1, SR (-7, 7), 7);
|
||||
T (1, SR (-1, 1), 7);
|
||||
T (1, SR (-1, 1), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (1, SR ( 1, 2), 1);
|
||||
T (1, SR ( 1, 2), 5);
|
||||
|
||||
T (1, SR ( 0, 1), 6);
|
||||
T (1, UR ( 1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
|
||||
T (2, SR (-7, 7), 7);
|
||||
T (2, SR (-2, 7), 7);
|
||||
T (2, SR (-1, 1), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (2, SR (-1, 1), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (2, SR ( 1, 2), 1);
|
||||
T (2, SR ( 1, 2), 3);
|
||||
T (2, SR ( 1, 2), 4);
|
||||
T (2, SR ( 1, 2), 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
|
||||
T (2, SR ( 0, 1), 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" { xfail *-*-* } } */
|
||||
T (2, UR ( 1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (7, UR (-7, 0), 7);
|
||||
T (7, UR (-7, 0), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (7, UR (-3, 2), 3);
|
||||
T (7, UR (-2, 2), 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
|
||||
void test_memcpy_array_range_cst_off (const void *s)
|
||||
{
|
||||
T (SR (-7, 7), 1, 7);
|
||||
T (SR (-1, 1), 1, 7);
|
||||
T (SR (-1, 1), 1, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" { xfail *-*-*} } */
|
||||
T (SR ( 1, 2), 1, 1);
|
||||
T (SR ( 1, 2), 1, 5);
|
||||
|
||||
T (SR ( 0, 1), 1, 6);
|
||||
T (UR ( 1, 2), 1, 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
|
||||
T (SR (-7, 7), 2, 7);
|
||||
T (SR (-1, 1), 2, 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (SR (-1, 1), 2, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (SR ( 1, 2), 2, 1);
|
||||
T (SR ( 1, 2), 2, 3);
|
||||
T (SR ( 1, 2), 2, 4);
|
||||
T (SR ( 1, 2), 2, 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
|
||||
T (SR ( 0, 1), 2, 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
|
||||
T (UR ( 1, 2), 2, 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
|
||||
void test_memcpy_array_range_range_off (const void *s)
|
||||
{
|
||||
T (UR (0, 1), UR (0, 1), 7);
|
||||
T (UR (3, 5), UR (2, 7), 1);
|
||||
T (UR (3, 7), UR (2, 9), 2);
|
||||
T (UR (3, 9), UR (2, 9), 3); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (UR (0, 1), UR (1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
|
||||
#undef T
|
||||
#define T(off1, off2, n) \
|
||||
do { \
|
||||
extern char UNIQ_NAME (ga)[7]; \
|
||||
char *d = UNIQ_NAME (ga) + off1; \
|
||||
d += off2; \
|
||||
const char str[] = "0123456789"; \
|
||||
const char *s = str + sizeof str - 1 - n; \
|
||||
strcpy (d, s); \
|
||||
sink (d); \
|
||||
} while (0)
|
||||
|
||||
|
||||
void test_strcpy_array_cst_range_off (void)
|
||||
{
|
||||
T (1, SR (-7, 7), 6);
|
||||
T (1, SR (-1, 1), 6);
|
||||
T (1, SR (-1, 1), 8); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (1, SR ( 1, 2), 0);
|
||||
T (1, SR ( 1, 2), 4);
|
||||
|
||||
T (1, SR ( 0, 1), 5);
|
||||
T (1, UR ( 1, 2), 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
|
||||
T (2, SR (-7, 7), 6);
|
||||
T (2, SR (-2, 7), 6);
|
||||
T (2, SR (-1, 1), 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (2, SR (-1, 1), 8); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (2, SR ( 1, 2), 0);
|
||||
T (2, SR ( 1, 2), 2);
|
||||
T (2, SR ( 1, 2), 3);
|
||||
T (2, SR ( 1, 2), 4); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
|
||||
T (2, SR ( 0, 1), 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" { xfail *-*-* } } */
|
||||
T (2, UR ( 1, 2), 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (7, UR (-7, 0), 6);
|
||||
T (7, UR (-7, 0), 8); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (7, UR (-3, 2), 2);
|
||||
T (7, UR (-2, 2), 4); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
|
||||
void test_strcpy_array_range_cst_off (const char *s)
|
||||
{
|
||||
T (SR (-7, 7), 1, 6);
|
||||
T (SR (-1, 1), 1, 6);
|
||||
T (SR (-1, 1), 1, 8); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" { xfail *-*-*} } */
|
||||
T (SR ( 1, 2), 1, 0);
|
||||
T (SR ( 1, 2), 1, 1);
|
||||
T (SR ( 1, 2), 1, 4);
|
||||
|
||||
T (SR ( 0, 1), 1, 5);
|
||||
T (UR ( 1, 2), 1, 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
|
||||
T (SR (-7, 7), 2, 6);
|
||||
T (SR (-1, 1), 2, 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (SR (-1, 1), 2, 8); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (SR ( 1, 2), 2, 0);
|
||||
T (SR ( 1, 2), 2, 1);
|
||||
T (SR ( 1, 2), 2, 2);
|
||||
T (SR ( 1, 2), 2, 3);
|
||||
T (SR ( 1, 2), 2, 4); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
|
||||
T (SR ( 0, 1), 2, 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
|
||||
T (UR ( 1, 2), 2, 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
|
||||
#undef T
|
||||
#define T(off1, off2, n) \
|
||||
do { \
|
||||
extern char UNIQ_NAME (ga)[7]; \
|
||||
char *d = UNIQ_NAME (ga) + off1; \
|
||||
d += off2; \
|
||||
strncpy (d, s, n); \
|
||||
sink (d); \
|
||||
} while (0)
|
||||
|
||||
|
||||
void test_strncpy_array_cst_range_off (const char *s)
|
||||
{
|
||||
T (1, SR (-7, 7), 7);
|
||||
T (1, SR (-1, 1), 7);
|
||||
T (1, SR (-1, 1), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (1, SR ( 1, 2), 1);
|
||||
T (1, SR ( 1, 2), 5);
|
||||
|
||||
T (1, SR ( 0, 1), 6);
|
||||
T (1, UR ( 1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
|
||||
T (2, SR ( -7, 7), 7);
|
||||
T (2, SR ( -1, 1), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (2, SR ( -1, 1), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (2, SR ( 1, 2), 1);
|
||||
T (2, SR ( 1, 2), 3);
|
||||
T (2, SR ( 1, 2), 4);
|
||||
T (2, SR ( 1, 2), 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
|
||||
T (2, SR ( 0, 1), 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" { xfail *-*-* } } */
|
||||
T (2, UR ( 1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (7, UR (-7, 0), 7);
|
||||
T (7, UR (-7, 0), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (7, UR (-3, 2), 3);
|
||||
T (7, UR (-2, 2), 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
|
||||
void test_strncpy_array_range_cst_off (const char *s)
|
||||
{
|
||||
T (SR (-7, 7), 1, 7);
|
||||
T (SR (-1, 1), 1, 7);
|
||||
T (SR (-1, 1), 1, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" { xfail *-*-*} } */
|
||||
T (SR ( 1, 2), 1, 1);
|
||||
T (SR ( 1, 2), 1, 5);
|
||||
|
||||
T (SR ( 0, 1), 1, 6);
|
||||
T (UR ( 1, 2), 1, 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
|
||||
T (SR (-7, 7), 2, 7);
|
||||
T (SR (-1, 1), 2, 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (SR (-1, 1), 2, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (SR ( 1, 2), 2, 1);
|
||||
T (SR ( 1, 2), 2, 3);
|
||||
T (SR ( 1, 2), 2, 4);
|
||||
T (SR ( 1, 2), 2, 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
|
||||
T (SR ( 0, 1), 2, 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
|
||||
T (UR ( 1, 2), 2, 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
|
||||
|
||||
void test_strncpy_array_range_range_off (const char *s)
|
||||
{
|
||||
T (UR (0, 1), UR (0, 1), 7);
|
||||
T (UR (3, 5), UR (2, 7), 1);
|
||||
T (UR (3, 7), UR (2, 9), 2);
|
||||
T (UR (3, 9), UR (2, 9), 3); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
T (UR (0, 1), UR (1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
120
gcc/testsuite/gcc.dg/Wstringop-overflow-12.c
Normal file
120
gcc/testsuite/gcc.dg/Wstringop-overflow-12.c
Normal file
@ -0,0 +1,120 @@
|
||||
/* PR tree-optimization/89350 - Wrong -Wstringop-overflow warning
|
||||
on a variable offset from the end of an array
|
||||
Test exercising -Wstringop-truncation alone, with -Warray-bounds
|
||||
explicitly disabled.
|
||||
{ dg-do compile }
|
||||
{ dg-options "-O2 -Wno-array-bounds -Wstringop-overflow -ftrack-macro-expansion=0" } */
|
||||
|
||||
#include "range.h"
|
||||
|
||||
extern void* memcpy (void*, const void*, size_t);
|
||||
extern void* memset (void*, int, size_t);
|
||||
|
||||
void sink (void*);
|
||||
|
||||
extern char ga7[7];
|
||||
|
||||
|
||||
#define T(d, n) (memcpy ((d), s, (n)), sink (d))
|
||||
|
||||
void test_memcpy_array_cst_range_off (const void *s)
|
||||
{
|
||||
char *d = ga7 + 1;
|
||||
|
||||
T (d + UR (1, 2), 1);
|
||||
T (d + UR (1, 2), 5);
|
||||
|
||||
T (d + UR (0, 1), 6);
|
||||
T (d + UR (0, 1), 7); /* { dg-warning ".memcpy. writing 6 bytes into a region of size 5 overflows the destination" "pr89428" { xfail *-*-* } } */
|
||||
T (d + UR (1, 2), 6); /* { dg-warning ".memcpy. writing 6 bytes into a region of size 5 overflows the destination" } */
|
||||
T (d + UR (1, 2), 7); /* { dg-warning "writing 7 bytes into a region of size 5 " } */
|
||||
|
||||
T (d + SR (-3, -2), 1); /* { dg-warning "writing 1 byte into a region of size 0 " "pr85350" { xfail *-*-* } } */
|
||||
T (d + SR (-2, -1), 1);
|
||||
T (d + SR (-2, -1), 2); /* { dg-warning "writing 2 bytes into a region of size 7 " "pr89428" { xfail *-*-* } } */
|
||||
T (d + SR (-2, -1), 9); /* { dg-warning "writing 9 bytes into a region of size 7 " "pr85350" { xfail *-*-* } } */
|
||||
|
||||
d = ga7 + 7;
|
||||
T (d + SR (-7, -6), 1);
|
||||
T (d + SR (-7, -1), 1);
|
||||
T (d + SR (-2, -1), 3); /* { dg-warning "writing 3 bytes into a region of size 2 " "pr85350" { xfail *-*-* } } */
|
||||
|
||||
T (d + UR (1, 2), 1); /* { dg-warning "writing 1 byte into a region of size 0 " "pr89350" { xfail *-*-* } } */
|
||||
}
|
||||
|
||||
|
||||
void test_memcpy_array_range_range_off (const void *s)
|
||||
{
|
||||
char *d = ga7 + UR (0, 1);
|
||||
T (d + SR (-1, 0), 1);
|
||||
T (d + SR (-1, 0), 7);
|
||||
T (d + SR (-1, 0), 9); /* { dg-warning "writing 1 byte into a region of size 0 " "pr89350" { xfail *-*-* } } */
|
||||
}
|
||||
|
||||
|
||||
#undef T
|
||||
#define T(d, n) (memset ((d), 0, (n)), sink (d))
|
||||
|
||||
void test_memset_array_unsigned_off (void)
|
||||
{
|
||||
char *d = ga7 + 1;
|
||||
|
||||
T (d + UR (1, 2), 1);
|
||||
T (d + UR (1, 2), 5);
|
||||
|
||||
T (d + UR (0, 1), 6);
|
||||
T (d + UR (0, 1), 7); /* { dg-warning ".memset. writing 6 bytes into a region of size 5 overflows the destination" "pr89428" { xfail *-*-* } } */
|
||||
T (d + UR (1, 2), 6); /* { dg-warning ".memset. writing 6 bytes into a region of size 5 overflows the destination" } */
|
||||
T (d + UR (1, 2), 7); /* { dg-warning "writing 7 bytes into a region of size 5 " } */
|
||||
|
||||
T (d + SR (-3, -2), 1); /* { dg-warning "writing 1 byte into a region of size 0 " "pr85350" { xfail *-*-* } } */
|
||||
T (d + SR (-2, -1), 1);
|
||||
T (d + SR (-2, -1), 2); /* { dg-warning "writing 2 bytes into a region of size 7 " "pr89428" { xfail *-*-* } } */
|
||||
T (d + SR (-2, -1), 9); /* { dg-warning "writing 9 bytes into a region of size 7 " "pr85350" { xfail *-*-* } } */
|
||||
|
||||
d = ga7 + 7;
|
||||
T (d + SR (-7, -6), 1);
|
||||
T (d + SR (-7, -1), 1);
|
||||
T (d + SR (-2, -1), 3); /* { dg-warning "writing 3 bytes into a region of size 2 " "pr85350" { xfail *-*-* } } */
|
||||
|
||||
T (d + UR (1, 2), 1); /* { dg-warning "writing 1 byte into a region of size 0 " } */
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct MemArray { char a7[7], a3[3], c; };
|
||||
|
||||
extern struct MemArray gma;
|
||||
|
||||
void test_memset_memarray (void)
|
||||
{
|
||||
char *d = gma.a7 + 1;
|
||||
|
||||
T (d + UR (1, 2), 1);
|
||||
T (d + UR (1, 2), 5);
|
||||
|
||||
T (d + UR (0, 1), 6);
|
||||
T (d + UR (0, 1), 7); /* { dg-warning ".memset. writing 6 bytes into a region of size 5 overflows the destination" "pr89428" { xfail *-*-* } } */
|
||||
T (d + UR (1, 2), 6); /* { dg-warning ".memset. writing 6 bytes into a region of size 5 overflows the destination" "pr89350" { xfail *-*-* } } */
|
||||
T (d + UR (1, 2), 7); /* { dg-warning "writing 7 bytes into a region of size 5 " "pr85350" { xfail *-*-* } } */
|
||||
|
||||
}
|
||||
|
||||
|
||||
#undef T
|
||||
#define T(d, n) (memcpy ((d), s, (n)), sink (d))
|
||||
|
||||
void test_memcpy_array_signed_off (const void *s)
|
||||
{
|
||||
char *d = ga7 + 1;
|
||||
|
||||
T (d + SR (-7, 7), 7);
|
||||
T (d + SR (-1, 1), 7);
|
||||
T (d + SR (-1, 1), 9); /* { dg-warning "writing 9 bytes into a region of size " "pr89428" { xfail *-*-* } } */
|
||||
T (d + SR (-1, 2), 9); /* { dg-warning "writing 9 bytes into a region of size " "pr89428" { xfail *-*-* } } */
|
||||
T (d + SR (1, 2), 1);
|
||||
T (d + SR (1, 2), 5);
|
||||
|
||||
T (d + SR (0, 1), 6);
|
||||
T (d + UR (1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
@ -51,8 +51,8 @@ void test_memcpy_array (const void *s)
|
||||
T (a7 + UR (8, 9), s, 7); /* { dg-warning "writing 7 bytes into a region of size 0" } */
|
||||
|
||||
T (a7 + UR (9, 10), s, 7); /* { dg-warning "writing 7 bytes into a region of size 0" } */
|
||||
T (a7 + UR (DIFF_MAX, DIFF_MAX + (size_t)1), s, 7); /* { dg-warning "writing 7 bytes into a region of size 0" } */
|
||||
T (a7 + UR (DIFF_MAX, SIZE_MAX), s, 7); /* { dg-warning "writing 7 bytes into a region of size 0" } */
|
||||
T (a7 + UR (DIFF_MAX, DIFF_MAX + (size_t)1), s, 7); /* { dg-warning "writing 7 bytes into a region of size 0" "pr85350" { xfail *-*-* } } */
|
||||
T (a7 + UR (DIFF_MAX, SIZE_MAX), s, 7); /* { dg-warning "writing 7 bytes into a region of size 0" "pr85350" { xfail *-*-*} } */
|
||||
|
||||
/* This is valid. */
|
||||
char *d = a7 + 7;
|
||||
@ -102,8 +102,8 @@ void test_strcpy_array (void)
|
||||
T (a7 + UR (8, 9), "012345"); /* { dg-warning "writing 7 bytes into a region of size 0" } */
|
||||
|
||||
T (a7 + UR (9, 10), "012345"); /* { dg-warning "writing 7 bytes into a region of size 0" } */
|
||||
T (a7 + UR (DIFF_MAX, DIFF_MAX + (size_t)1), "012345"); /* { dg-warning "writing 7 bytes into a region of size 0" } */
|
||||
T (a7 + UR (DIFF_MAX, SIZE_MAX), "012345"); /* { dg-warning "writing 7 bytes into a region of size 0" } */
|
||||
T (a7 + UR (DIFF_MAX, DIFF_MAX + (size_t)1), "012345"); /* { dg-warning "writing 7 bytes into a region of size 0" "pr85350" { xfail *-*-* } } */
|
||||
T (a7 + UR (DIFF_MAX, SIZE_MAX), "012345"); /* { dg-warning "writing 7 bytes into a region of size 0" "pr85350" { xfail *-*-* } } */
|
||||
|
||||
char *d = a7 + 7;
|
||||
|
||||
@ -127,6 +127,6 @@ void test_strncpy_memarray (struct MemArray *p, const void *s)
|
||||
T (p->a9 + UR (9, 10), s, 9); /* { dg-warning "writing 9 bytes into a region of size 0" } */
|
||||
T (p->a9 + UR (10, 11), s, 9); /* { dg-warning "writing 9 bytes into a region of size 0" } */
|
||||
|
||||
T (p->a9 + UR (DIFF_MAX, DIFF_MAX + (size_t)1), s, 1); /* { dg-warning "writing 1 byte into a region of size 0" } */
|
||||
T (p->a9 + UR (DIFF_MAX, SIZE_MAX), s, 3); /* { dg-warning "writing 3 bytes into a region of size 0" } */
|
||||
T (p->a9 + UR (DIFF_MAX, DIFF_MAX + (size_t)1), s, 1); /* { dg-warning "writing 1 byte into a region of size 0" "pr85350" { xfail *-*-* } } */
|
||||
T (p->a9 + UR (DIFF_MAX, SIZE_MAX), s, 3); /* { dg-warning "writing 3 bytes into a region of size 0" "pr85350" { xfail *-*-* } } */
|
||||
}
|
||||
|
@ -20,5 +20,5 @@ main (void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-warning "writing" "" { target *-*-* } 10 } */
|
||||
/* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "" { target *-*-* } 10 } */
|
||||
/* { dg-message "file included" "In file included" { target *-*-* } 0 } */
|
||||
|
@ -12,5 +12,5 @@ main (void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-warning "writing" "" { target *-*-* } 10 } */
|
||||
/* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "" { target *-*-* } 10 } */
|
||||
/* { dg-message "file included" "In file included" { target *-*-* } 0 } */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* PR middle-end/40340 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -Wall -Wno-system-headers -g" } */
|
||||
/* { dg-options "-O2 -Wall -Wno-array-bounds -Wno-system-headers -g" } */
|
||||
|
||||
#define TEST3
|
||||
#include "pr40340.h"
|
||||
|
@ -13,5 +13,5 @@ main (void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-warning "writing" "" { target *-*-* } 10 } */
|
||||
/* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "" { target *-*-* } 10 } */
|
||||
/* { dg-message "file included" "In file included" { target *-*-* } 0 } */
|
||||
|
18
gcc/testsuite/gcc.dg/pr89350.c
Normal file
18
gcc/testsuite/gcc.dg/pr89350.c
Normal file
@ -0,0 +1,18 @@
|
||||
/* PR tree-optimization/89350 - Wrong -Wstringop-overflow warning
|
||||
on a variable offset from the end of an array
|
||||
{ dg-do compile }
|
||||
{ dg-options "-O2 -Wall" } */
|
||||
|
||||
char buf[128];
|
||||
char *src = "HCSparta";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *dst = buf + sizeof(buf);
|
||||
|
||||
if (argc)
|
||||
{
|
||||
dst -= argc;
|
||||
__builtin_memcpy(dst, src, argc + 0); /* { dg-bogus "\\\[-Warray-bounds|-Wstringop-overflow" } */
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user