Commit e3329a78 by Martin Sebor Committed by Martin Sebor

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
parent 47feeb36
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
* fold-const.c (operand_equal_p): Handle SAVE_EXPR.
......
......@@ -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;
......
......@@ -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,19 +1623,22 @@ 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);
{
inform (DECL_SOURCE_LOCATION (ref.base),
"array %qD declared here", ref.base);
warned = true;
}
else
warning_at (loc, OPT_Warray_bounds,
"%G%qD pointer overflow between offset %s "
"and size %s",
call, func, rangestr[0], rangestr[1]);
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,
"%G%qD pointer overflow between offset %s "
"and size %s",
call, func, rangestr[0], rangestr[1]);
warned = warning_at (loc, OPT_Warray_bounds,
"%G%qD pointer overflow between offset %s "
"and size %s",
call, func, rangestr[0], rangestr[1]);
}
else if (oobref == ref.base)
{
......@@ -1664,22 +1669,26 @@ 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);
{
inform (DECL_SOURCE_LOCATION (ref.base),
"%qD declared here", ref.base);
warned = true;
}
}
else if (ref.basesize < maxobjsize)
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]"),
call, func, rangestr[0], ref.basesize.to_uhwi ());
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]"),
call, func, rangestr[0], ref.basesize.to_uhwi ());
else
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"),
call, func, rangestr[0]);
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"),
call, func, rangestr[0]);
}
else if (TREE_CODE (ref.ref) == MEM_REF)
{
......@@ -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,
"%G%qD offset %s from the object at %qE is out "
"of the bounds of %qT",
call, func, rangestr[0], ref.base, type);
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));
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 ());
tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ref.ref));
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 ());
}
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);
......
......@@ -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 *
......
......@@ -5,6 +5,12 @@
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
* gcc.dg/Wstringop-truncation-3.c: New test.
......
/* 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=]" } */
}
/* 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=]" } */
}
......@@ -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);
......
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