Commit a411ae9b by Martin Sebor Committed by Martin Sebor

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
parent 11bf9a07
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> 2019-03-21 Jan Hubicka <hubicka@ucw.cz>
Jakub Jelinek <jakub@redhat.com> Jakub Jelinek <jakub@redhat.com>
......
...@@ -3650,7 +3650,8 @@ compute_objsize (tree dest, int ostype) ...@@ -3650,7 +3650,8 @@ compute_objsize (tree dest, int ostype)
/* Ignore negative offsets for now. For others, /* Ignore negative offsets for now. For others,
use the lower bound as the most optimistic use the lower bound as the most optimistic
estimate of the (remaining)size. */ 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)) else if (wi::ltu_p (min, wisiz))
return wide_int_to_tree (TREE_TYPE (size), return wide_int_to_tree (TREE_TYPE (size),
......
...@@ -147,6 +147,9 @@ struct builtin_memref ...@@ -147,6 +147,9 @@ struct builtin_memref
/* The size range of the access to this reference. */ /* The size range of the access to this reference. */
offset_int sizrange[2]; offset_int sizrange[2];
/* Cached result of get_max_objsize(). */
const offset_int maxobjsize;
/* True for "bounded" string functions like strncat, and strncpy /* True for "bounded" string functions like strncat, and strncpy
and their variants that specify either an exact or upper bound and their variants that specify either an exact or upper bound
on the size of the accesses they perform. For strncat both on the size of the accesses they perform. For strncat both
...@@ -233,6 +236,7 @@ builtin_memref::builtin_memref (tree expr, tree size) ...@@ -233,6 +236,7 @@ builtin_memref::builtin_memref (tree expr, tree size)
refoff (HOST_WIDE_INT_MIN), refoff (HOST_WIDE_INT_MIN),
offrange (), offrange (),
sizrange (), sizrange (),
maxobjsize (tree_to_shwi (max_object_size ())),
strbounded_p () strbounded_p ()
{ {
/* Unfortunately, wide_int default ctor is a no-op so array members /* Unfortunately, wide_int default ctor is a no-op so array members
...@@ -240,7 +244,8 @@ builtin_memref::builtin_memref (tree expr, tree size) ...@@ -240,7 +244,8 @@ builtin_memref::builtin_memref (tree expr, tree size)
offrange[0] = offrange[1] = 0; offrange[0] = offrange[1] = 0;
sizrange[0] = sizrange[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 /* Find the BASE object or pointer referenced by EXPR and set
the offset range OFFRANGE in the process. */ the offset range OFFRANGE in the process. */
...@@ -292,13 +297,13 @@ builtin_memref::builtin_memref (tree expr, tree size) ...@@ -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 void
builtin_memref::extend_offset_range (tree offset) builtin_memref::extend_offset_range (tree offset)
{ {
const offset_int maxobjsize = tree_to_shwi (max_object_size ());
if (TREE_CODE (offset) == INTEGER_CST) if (TREE_CODE (offset) == INTEGER_CST)
{ {
offset_int off = int_cst_value (offset); offset_int off = int_cst_value (offset);
...@@ -312,36 +317,57 @@ builtin_memref::extend_offset_range (tree offset) ...@@ -312,36 +317,57 @@ builtin_memref::extend_offset_range (tree offset)
if (TREE_CODE (offset) == SSA_NAME) if (TREE_CODE (offset) == SSA_NAME)
{ {
/* A pointer offset is represented as sizetype but treated
as signed. */
wide_int min, max; wide_int min, max;
value_range_kind rng = get_range_info (offset, &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[0] += offset_int::from (min, SIGNED);
offrange[1] += offset_int::from (max, 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)
&& (type = TREE_TYPE (gimple_assign_rhs1 (stmt)))
&& INTEGRAL_TYPE_P (type))
{ {
/* Handle an anti-range the same as no range at all. */ tree_code code = gimple_assign_rhs_code (stmt);
gimple *stmt = SSA_NAME_DEF_STMT (offset); if (code == NOP_EXPR)
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))
{ {
/* Use the bounds of the type of the NOP_EXPR operand /* Use the bounds of the type of the NOP_EXPR operand
even if it's signed. The result doesn't trigger even if it's signed. The result doesn't trigger
warnings but makes their output more readable. */ warnings but makes their output more readable. */
offrange[0] += wi::to_offset (TYPE_MIN_VALUE (type)); offrange[0] += wi::to_offset (TYPE_MIN_VALUE (type));
offrange[1] += wi::to_offset (TYPE_MAX_VALUE (type)); offrange[1] += wi::to_offset (TYPE_MAX_VALUE (type));
return;
} }
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 /* Determines the base object or pointer of the reference EXPR
...@@ -350,7 +376,7 @@ builtin_memref::extend_offset_range (tree offset) ...@@ -350,7 +376,7 @@ builtin_memref::extend_offset_range (tree offset)
void void
builtin_memref::set_base_and_offset (tree expr) 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) if (TREE_CODE (expr) == SSA_NAME)
{ {
...@@ -377,9 +403,7 @@ builtin_memref::set_base_and_offset (tree expr) ...@@ -377,9 +403,7 @@ builtin_memref::set_base_and_offset (tree expr)
else if (code == POINTER_PLUS_EXPR) else if (code == POINTER_PLUS_EXPR)
{ {
expr = gimple_assign_rhs1 (stmt); expr = gimple_assign_rhs1 (stmt);
offset = gimple_assign_rhs2 (stmt);
tree offset = gimple_assign_rhs2 (stmt);
extend_offset_range (offset);
} }
else else
{ {
...@@ -389,6 +413,12 @@ builtin_memref::set_base_and_offset (tree expr) ...@@ -389,6 +413,12 @@ builtin_memref::set_base_and_offset (tree expr)
} }
else 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; base = expr;
return; return;
} }
...@@ -416,6 +446,9 @@ builtin_memref::set_base_and_offset (tree expr) ...@@ -416,6 +446,9 @@ builtin_memref::set_base_and_offset (tree expr)
/* get_inner_reference is not expected to return null. */ /* get_inner_reference is not expected to return null. */
gcc_assert (base != NULL); gcc_assert (base != NULL);
if (offset)
extend_offset_range (offset);
poly_int64 bytepos = exact_div (bitpos, BITS_PER_UNIT); poly_int64 bytepos = exact_div (bitpos, BITS_PER_UNIT);
/* Convert the poly_int64 offset to offset_int. The offset /* Convert the poly_int64 offset to offset_int. The offset
...@@ -471,7 +504,8 @@ builtin_memref::set_base_and_offset (tree expr) ...@@ -471,7 +504,8 @@ builtin_memref::set_base_and_offset (tree expr)
tree tree
builtin_memref::offset_out_of_bounds (int strict, offset_int ooboff[2]) const 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. */ /* A temporary, possibly adjusted, copy of the offset range. */
offset_int offrng[2] = { offrange[0], offrange[1] }; offset_int offrng[2] = { offrange[0], offrange[1] };
...@@ -606,6 +640,14 @@ builtin_access::builtin_access (gimple *call, builtin_memref &dst, ...@@ -606,6 +640,14 @@ builtin_access::builtin_access (gimple *call, builtin_memref &dst,
detect_overlap = &builtin_access::no_overlap; detect_overlap = &builtin_access::no_overlap;
break; 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:
case BUILT_IN_STPNCPY_CHK: case BUILT_IN_STPNCPY_CHK:
case BUILT_IN_STRNCPY: case BUILT_IN_STRNCPY:
...@@ -640,7 +682,7 @@ builtin_access::builtin_access (gimple *call, builtin_memref &dst, ...@@ -640,7 +682,7 @@ builtin_access::builtin_access (gimple *call, builtin_memref &dst,
return; 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 /* Try to determine the size of the base object. compute_objsize
expects a pointer so create one if BASE is a non-pointer object. */ 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, ...@@ -659,7 +701,7 @@ builtin_access::builtin_access (gimple *call, builtin_memref &dst,
dst.basesize = maxobjsize; dst.basesize = maxobjsize;
} }
if (src.basesize < 0) if (src.base && src.basesize < 0)
{ {
addr = src.base; addr = src.base;
if (!POINTER_TYPE_P (TREE_TYPE (addr))) if (!POINTER_TYPE_P (TREE_TYPE (addr)))
...@@ -845,7 +887,7 @@ builtin_access::generic_overlap () ...@@ -845,7 +887,7 @@ builtin_access::generic_overlap ()
gcc_assert (dstref->base == srcref->base); 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; offset_int maxsize = dstref->basesize < 0 ? maxobjsize : dstref->basesize;
gcc_assert (maxsize <= maxobjsize); gcc_assert (maxsize <= maxobjsize);
...@@ -1054,7 +1096,7 @@ builtin_access::strcat_overlap () ...@@ -1054,7 +1096,7 @@ builtin_access::strcat_overlap ()
gcc_assert (dstref->base == srcref->base); 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); gcc_assert (dstref->base && dstref->base == srcref->base);
...@@ -1191,7 +1233,7 @@ builtin_access::overlap () ...@@ -1191,7 +1233,7 @@ builtin_access::overlap ()
{ {
builtin_access &acs = *this; 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], acs.sizrange[0] = wi::smax (dstref->sizrange[0],
srcref->sizrange[0]).to_shwi (); srcref->sizrange[0]).to_shwi ();
...@@ -1372,7 +1414,7 @@ maybe_diag_overlap (location_t loc, gimple *call, builtin_access &acs) ...@@ -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 "]", "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
ovloff[0], ovloff[1]); 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; bool must_overlap = ovlsiz[0] > 0;
if (ovlsiz[1] == 0) if (ovlsiz[1] == 0)
...@@ -1581,7 +1623,7 @@ static bool ...@@ -1581,7 +1623,7 @@ static bool
maybe_diag_access_bounds (location_t loc, gimple *call, tree func, int strict, maybe_diag_access_bounds (location_t loc, gimple *call, tree func, int strict,
const builtin_memref &ref, bool do_warn) 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 /* Check for excessive size first and regardless of warning options
since the result is used to make codegen decisions. */ 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, ...@@ -1690,8 +1732,6 @@ maybe_diag_access_bounds (location_t loc, gimple *call, tree func, int strict,
} }
else if (oobref == ref.base) 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 /* True when the offset formed by an access to the reference
is out of bounds, rather than the initial offset wich is is out of bounds, rather than the initial offset wich is
in bounds. This implies access past the end. */ in bounds. This implies access past the end. */
...@@ -1814,6 +1854,12 @@ wrestrict_dom_walker::check_call (gimple *call) ...@@ -1814,6 +1854,12 @@ wrestrict_dom_walker::check_call (gimple *call)
bnd_idx = 2; bnd_idx = 2;
break; 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:
case BUILT_IN_STPCPY_CHK: case BUILT_IN_STPCPY_CHK:
case BUILT_IN_STRCPY: case BUILT_IN_STRCPY:
...@@ -1844,14 +1890,14 @@ wrestrict_dom_walker::check_call (gimple *call) ...@@ -1844,14 +1890,14 @@ wrestrict_dom_walker::check_call (gimple *call)
/* DST and SRC can be null for a call with an insufficient number /* DST and SRC can be null for a call with an insufficient number
of arguments to a built-in function declared without a protype. */ of arguments to a built-in function declared without a protype. */
if (!dst || !src) if (!dst || (src_idx < nargs && !src))
return; return;
/* DST, SRC, or DSTWR can also have the wrong type in a call to /* DST, SRC, or DSTWR can also have the wrong type in a call to
a function declared without a prototype. Avoid checking such a function declared without a prototype. Avoid checking such
invalid calls. */ invalid calls. */
if (TREE_CODE (TREE_TYPE (dst)) != POINTER_TYPE 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)))) || (dstwr && !INTEGRAL_TYPE_P (TREE_TYPE (dstwr))))
return; return;
...@@ -1901,15 +1947,23 @@ check_bounds_or_overlap (gimple *call, tree dst, tree src, tree dstsize, ...@@ -1901,15 +1947,23 @@ check_bounds_or_overlap (gimple *call, tree dst, tree src, tree dstsize,
return OPT_Warray_bounds; return OPT_Warray_bounds;
} }
bool check_overlap if (!warn_restrict || bounds_only || !src)
= (warn_restrict
&& (bounds_only
|| (DECL_FUNCTION_CODE (func) != BUILT_IN_MEMMOVE
&& DECL_FUNCTION_CODE (func) != BUILT_IN_MEMMOVE_CHK)));
if (!check_overlap)
return 0; 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)) if (operand_equal_p (dst, src, 0))
{ {
/* Issue -Wrestrict unless the pointers are null (those do /* Issue -Wrestrict unless the pointers are null (those do
......
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> 2019-03-21 Jakub Jelinek <jakub@redhat.com>
PR lto/89692 PR lto/89692
......
...@@ -42,7 +42,7 @@ void test_memmove (void) ...@@ -42,7 +42,7 @@ void test_memmove (void)
void test_memset (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" } */
} }
......
/* 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" } */
}
/* 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) ...@@ -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 (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 (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, 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" } */ 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. */ /* This is valid. */
char *d = a7 + 7; char *d = a7 + 7;
...@@ -102,8 +102,8 @@ void test_strcpy_array (void) ...@@ -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 (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 (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, 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" } */ 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; char *d = a7 + 7;
...@@ -127,6 +127,6 @@ void test_strncpy_memarray (struct MemArray *p, const void *s) ...@@ -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 (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 (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, 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" } */ 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) ...@@ -20,5 +20,5 @@ main (void)
return 0; return 0;
} }
/* { dg-warning "writing" "" { target *-*-* } 10 } */ /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "" { target *-*-* } 10 } */
/* { dg-message "file included" "In file included" { target *-*-* } 0 } */ /* { dg-message "file included" "In file included" { target *-*-* } 0 } */
...@@ -12,5 +12,5 @@ main (void) ...@@ -12,5 +12,5 @@ main (void)
return 0; return 0;
} }
/* { dg-warning "writing" "" { target *-*-* } 10 } */ /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "" { target *-*-* } 10 } */
/* { dg-message "file included" "In file included" { target *-*-* } 0 } */ /* { dg-message "file included" "In file included" { target *-*-* } 0 } */
/* PR middle-end/40340 */ /* PR middle-end/40340 */
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O2 -Wall -Wno-system-headers -g" } */ /* { dg-options "-O2 -Wall -Wno-array-bounds -Wno-system-headers -g" } */
#define TEST3 #define TEST3
#include "pr40340.h" #include "pr40340.h"
......
...@@ -13,5 +13,5 @@ main (void) ...@@ -13,5 +13,5 @@ main (void)
return 0; return 0;
} }
/* { dg-warning "writing" "" { target *-*-* } 10 } */ /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "" { target *-*-* } 10 } */
/* { dg-message "file included" "In file included" { target *-*-* } 0 } */ /* { dg-message "file included" "In file included" { target *-*-* } 0 } */
/* 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" } */
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment