PR tree-optimization/85259 - Missing -Wstringop-overflow= since r256683

gcc/ChangeLog:

	PR tree-optimization/85259
	* builtins.c (compute_objsize): Handle constant offsets.
	* gimple-ssa-warn-restrict.c (maybe_diag_offset_bounds): Return
	true iff a warning has been issued.
	* gimple.h (gimple_nonartificial_location): New function.
	* tree-ssa-strlen.c (maybe_diag_stxncpy_trunc): Call
	gimple_nonartificial_location and handle -Wno-system-headers.
	(handle_builtin_stxncpy): Same.

gcc/testsuite/ChangeLog:

	PR tree-optimization/85259
	* gcc.dg/Wstringop-overflow-5.c: New test.
	* gcc.dg/Wstringop-overflow-6.c: New test.

From-SVN: r261518
This commit is contained in:
Martin Sebor 2018-06-12 18:05:13 +00:00 committed by Martin Sebor
parent 47feeb3652
commit e3329a782f
8 changed files with 222 additions and 47 deletions

View File

@ -1,3 +1,14 @@
2018-06-12 Martin Sebor <msebor@redhat.com>
PR tree-optimization/85259
* builtins.c (compute_objsize): Handle constant offsets.
* gimple-ssa-warn-restrict.c (maybe_diag_offset_bounds): Return
true iff a warning has been issued.
* gimple.h (gimple_nonartificial_location): New function.
* tree-ssa-strlen.c (maybe_diag_stxncpy_trunc): Call
gimple_nonartificial_location and handle -Wno-system-headers.
(handle_builtin_stxncpy): Same.
2018-06-12 Martin Sebor <msebor@redhat.com>
PR c/85931

View File

@ -3326,10 +3326,29 @@ compute_objsize (tree dest, int ostype)
{
/* compute_builtin_object_size fails for addresses with
non-constant offsets. Try to determine the range of
such an offset here and use it to adjus the constant
such an offset here and use it to adjust the constant
size. */
tree off = gimple_assign_rhs2 (stmt);
if (TREE_CODE (off) == SSA_NAME
if (TREE_CODE (off) == INTEGER_CST)
{
if (tree size = compute_objsize (dest, ostype))
{
wide_int wioff = wi::to_wide (off);
wide_int wisiz = wi::to_wide (size);
/* Ignore negative offsets for now. For others,
use the lower bound as the most optimistic
estimate of the (remaining) size. */
if (wi::sign_mask (wioff))
;
else if (wi::ltu_p (wioff, wisiz))
return wide_int_to_tree (TREE_TYPE (size),
wi::sub (wisiz, wioff));
else
return size_zero_node;
}
}
else if (TREE_CODE (off) == SSA_NAME
&& INTEGRAL_TYPE_P (TREE_TYPE (off)))
{
wide_int min, max;

View File

@ -1593,8 +1593,6 @@ maybe_diag_offset_bounds (location_t loc, gcall *call, tree func, int strict,
loc = expansion_point_location_if_in_system_header (loc);
tree type;
char rangestr[2][64];
if (ooboff[0] == ooboff[1]
|| (ooboff[0] != ref.offrange[0]
@ -1605,6 +1603,8 @@ maybe_diag_offset_bounds (location_t loc, gcall *call, tree func, int strict,
(long long) ooboff[0].to_shwi (),
(long long) ooboff[1].to_shwi ());
bool warned = false;
if (oobref == error_mark_node)
{
if (ref.sizrange[0] == ref.sizrange[1])
@ -1614,6 +1614,8 @@ maybe_diag_offset_bounds (location_t loc, gcall *call, tree func, int strict,
(long long) ref.sizrange[0].to_shwi (),
(long long) ref.sizrange[1].to_shwi ());
tree type;
if (DECL_P (ref.base)
&& TREE_CODE (type = TREE_TYPE (ref.base)) == ARRAY_TYPE)
{
@ -1621,16 +1623,19 @@ maybe_diag_offset_bounds (location_t loc, gcall *call, tree func, int strict,
"%G%qD pointer overflow between offset %s "
"and size %s accessing array %qD with type %qT",
call, func, rangestr[0], rangestr[1], ref.base, type))
{
inform (DECL_SOURCE_LOCATION (ref.base),
"array %qD declared here", ref.base);
warned = true;
}
else
warning_at (loc, OPT_Warray_bounds,
warned = warning_at (loc, OPT_Warray_bounds,
"%G%qD pointer overflow between offset %s "
"and size %s",
call, func, rangestr[0], rangestr[1]);
}
else
warning_at (loc, OPT_Warray_bounds,
warned = warning_at (loc, OPT_Warray_bounds,
"%G%qD pointer overflow between offset %s "
"and size %s",
call, func, rangestr[0], rangestr[1]);
@ -1664,18 +1669,22 @@ maybe_diag_offset_bounds (location_t loc, gcall *call, tree func, int strict,
"of object %qD with type %qT"),
call, func, rangestr[0],
ref.base, TREE_TYPE (ref.base)))
{
inform (DECL_SOURCE_LOCATION (ref.base),
"%qD declared here", ref.base);
warned = true;
}
}
else if (ref.basesize < maxobjsize)
warning_at (loc, OPT_Warray_bounds,
warned = warning_at (loc, OPT_Warray_bounds,
form
? G_("%G%qD forming offset %s is out of the bounds "
"[0, %wu]")
: G_("%G%qD offset %s is out of the bounds [0, %wu]"),
? G_("%G%qD forming offset %s is out "
"of the bounds [0, %wu]")
: G_("%G%qD offset %s is out "
"of the bounds [0, %wu]"),
call, func, rangestr[0], ref.basesize.to_uhwi ());
else
warning_at (loc, OPT_Warray_bounds,
warned = warning_at (loc, OPT_Warray_bounds,
form
? G_("%G%qD forming offset %s is out of bounds")
: G_("%G%qD offset %s is out of bounds"),
@ -1688,24 +1697,25 @@ maybe_diag_offset_bounds (location_t loc, gcall *call, tree func, int strict,
type = TREE_TYPE (type);
type = TYPE_MAIN_VARIANT (type);
warning_at (loc, OPT_Warray_bounds,
warned = warning_at (loc, OPT_Warray_bounds,
"%G%qD offset %s from the object at %qE is out "
"of the bounds of %qT",
call, func, rangestr[0], ref.base, type);
}
else
{
type = TYPE_MAIN_VARIANT (TREE_TYPE (ref.ref));
tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ref.ref));
warning_at (loc, OPT_Warray_bounds,
warned = warning_at (loc, OPT_Warray_bounds,
"%G%qD offset %s from the object at %qE is out "
"of the bounds of referenced subobject %qD with type %qT "
"at offset %wu",
call, func, rangestr[0], ref.base, TREE_OPERAND (ref.ref, 1),
type, ref.refoff.to_uhwi ());
"of the bounds of referenced subobject %qD with "
"type %qT at offset %wu",
call, func, rangestr[0], ref.base,
TREE_OPERAND (ref.ref, 1), type,
ref.refoff.to_uhwi ());
}
return true;
return warned;
}
/* Check a CALL statement for restrict-violations and issue warnings
@ -1815,12 +1825,7 @@ bool
check_bounds_or_overlap (gcall *call, tree dst, tree src, tree dstsize,
tree srcsize, bool bounds_only /* = false */)
{
location_t loc = gimple_location (call);
if (tree block = gimple_block (call))
if (location_t *pbloc = block_nonartificial_location (block))
loc = *pbloc;
location_t loc = gimple_nonartificial_location (call);
loc = expansion_point_location_if_in_system_header (loc);
tree func = gimple_call_fndecl (call);

View File

@ -1796,6 +1796,20 @@ gimple_has_location (const gimple *g)
}
/* Return non-artificial location information for statement G. */
static inline location_t
gimple_nonartificial_location (const gimple *g)
{
location_t *ploc = NULL;
if (tree block = gimple_block (g))
ploc = block_nonartificial_location (block);
return ploc ? *ploc : gimple_location (g);
}
/* Return the file name of the location of STMT. */
static inline const char *

View File

@ -3,6 +3,12 @@
PR fortran/44491
* gfortran.dg/pr44491.f90: New testcase
2018-06-12 Martin Sebor <msebor@redhat.com>
PR tree-optimization/85259
* gcc.dg/Wstringop-overflow-5.c: New test.
* gcc.dg/Wstringop-overflow-6.c: New test.
2018-06-12 Martin Sebor <msebor@redhat.com>
PR c/85931

View File

@ -0,0 +1,58 @@
/* PR tree-optimization/85259 - Missing -Wstringop-overflow= since r256683
{ dg-do compile }
{ dg-options "-O2 -Wstringop-overflow" } */
extern char* strcpy (char*, const char*);
extern char* strcat (char*, const char*);
char a1[1];
char a2[2];
char a3[3];
char a4[4];
char a5[5];
char a6[6];
char a7[7];
char a8[8];
/* Verify that at least one instance of -Wstringop-overflow is issued
for each pair of strcpy/strcat calls. */
void test_strcpy_strcat_1 (void)
{
strcpy (a1, "1"), strcat (a1, "2"); /* { dg-warning "\\\[-Wstringop-overflow=]" } */
}
void test_strcpy_strcat_2 (void)
{
strcpy (a2, "12"), strcat (a2, "3"); /* { dg-warning "\\\[-Wstringop-overflow=]" } */
}
void test_strcpy_strcat_3 (void)
{
strcpy (a3, "123"), strcat (a3, "4"); /* { dg-warning "\\\[-Wstringop-overflow=]" } */
}
void test_strcpy_strcat_4 (void)
{
strcpy (a4, "1234"), strcat (a4, "5"); /* { dg-warning "\\\[-Wstringop-overflow=]" } */
}
void test_strcpy_strcat_5 (void)
{
strcpy (a5, "12345"), strcat (a5, "6"); /* { dg-warning "\\\[-Wstringop-overflow=]" } */
}
void test_strcpy_strcat_6 (void)
{
strcpy (a6, "123456"), strcat (a6, "7"); /* { dg-warning "\\\[-Wstringop-overflow=]" } */
}
void test_strcpy_strcat_7 (void)
{
strcpy (a7, "1234567"), strcat (a7, "8"); /* { dg-warning "\\\[-Wstringop-overflow=]" } */
}
void test_strcpy_strcat_8 (void)
{
strcpy (a8, "12345678"), strcat (a8, "9"); /* { dg-warning "\\\[-Wstringop-overflow=]" } */
}

View File

@ -0,0 +1,59 @@
/* PR tree-optimization/85259 - Missing -Wstringop-overflow= since r256683
{ dg-do compile }
{ dg-options "-O2 -Wstringop-overflow -ftrack-macro-expansion=0" } */
#define bos1(p) __builtin_object_size (p, 1)
#define strcat(d, s) __builtin___strcat_chk (d, s, bos1 (d))
#define strcpy(d, s) __builtin___strcpy_chk (d, s, bos1 (d))
char a1[1];
char a2[2];
char a3[3];
char a4[4];
char a5[5];
char a6[6];
char a7[7];
char a8[8];
/* Verify that at least one instance of -Wstringop-overflow is issued
for each pair of strcpy/strcat calls. */
void test_strcpy_strcat_1 (void)
{
strcpy (a1, "1"), strcat (a1, "2"); /* { dg-warning "\\\[-Wstringop-overflow=]" } */
}
void test_strcpy_strcat_2 (void)
{
strcpy (a2, "12"), strcat (a2, "3"); /* { dg-warning "\\\[-Wstringop-overflow=]" "bug 86121" { xfail *-*-* } } */
}
void test_strcpy_strcat_3 (void)
{
strcpy (a3, "123"), strcat (a3, "4"); /* { dg-warning "\\\[-Wstringop-overflow=]" } */
}
void test_strcpy_strcat_4 (void)
{
strcpy (a4, "1234"), strcat (a4, "5"); /* { dg-warning "\\\[-Wstringop-overflow=]" } */
}
void test_strcpy_strcat_5 (void)
{
strcpy (a5, "12345"), strcat (a5, "6"); /* { dg-warning "\\\[-Wstringop-overflow=]" } */
}
void test_strcpy_strcat_6 (void)
{
strcpy (a6, "123456"), strcat (a6, "7"); /* { dg-warning "\\\[-Wstringop-overflow=]" } */
}
void test_strcpy_strcat_7 (void)
{
strcpy (a7, "1234567"), strcat (a7, "8"); /* { dg-warning "\\\[-Wstringop-overflow=]" } */
}
void test_strcpy_strcat_8 (void)
{
strcpy (a8, "12345678"), strcat (a8, "9"); /* { dg-warning "\\\[-Wstringop-overflow=]" } */
}

View File

@ -1886,7 +1886,9 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt)
}
}
location_t callloc = gimple_location (stmt);
location_t callloc = gimple_nonartificial_location (stmt);
callloc = expansion_point_location_if_in_system_header (callloc);
tree func = gimple_call_fndecl (stmt);
if (lenrange[0] != 0 || !wi::neg_p (lenrange[1]))
@ -2069,7 +2071,8 @@ handle_builtin_stxncpy (built_in_function, gimple_stmt_iterator *gsi)
to strlen(S)). */
strinfo *silen = get_strinfo (pss->first);
location_t callloc = gimple_location (stmt);
location_t callloc = gimple_nonartificial_location (stmt);
callloc = expansion_point_location_if_in_system_header (callloc);
tree func = gimple_call_fndecl (stmt);