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> 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 PR c/85931
* fold-const.c (operand_equal_p): Handle SAVE_EXPR. * fold-const.c (operand_equal_p): Handle SAVE_EXPR.
......
...@@ -3326,10 +3326,29 @@ compute_objsize (tree dest, int ostype) ...@@ -3326,10 +3326,29 @@ compute_objsize (tree dest, int ostype)
{ {
/* compute_builtin_object_size fails for addresses with /* compute_builtin_object_size fails for addresses with
non-constant offsets. Try to determine the range of 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. */ size. */
tree off = gimple_assign_rhs2 (stmt); 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))) && INTEGRAL_TYPE_P (TREE_TYPE (off)))
{ {
wide_int min, max; wide_int min, max;
......
...@@ -1593,8 +1593,6 @@ maybe_diag_offset_bounds (location_t loc, gcall *call, tree func, int strict, ...@@ -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); loc = expansion_point_location_if_in_system_header (loc);
tree type;
char rangestr[2][64]; char rangestr[2][64];
if (ooboff[0] == ooboff[1] if (ooboff[0] == ooboff[1]
|| (ooboff[0] != ref.offrange[0] || (ooboff[0] != ref.offrange[0]
...@@ -1605,6 +1603,8 @@ maybe_diag_offset_bounds (location_t loc, gcall *call, tree func, int strict, ...@@ -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[0].to_shwi (),
(long long) ooboff[1].to_shwi ()); (long long) ooboff[1].to_shwi ());
bool warned = false;
if (oobref == error_mark_node) if (oobref == error_mark_node)
{ {
if (ref.sizrange[0] == ref.sizrange[1]) if (ref.sizrange[0] == ref.sizrange[1])
...@@ -1614,6 +1614,8 @@ maybe_diag_offset_bounds (location_t loc, gcall *call, tree func, int strict, ...@@ -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[0].to_shwi (),
(long long) ref.sizrange[1].to_shwi ()); (long long) ref.sizrange[1].to_shwi ());
tree type;
if (DECL_P (ref.base) if (DECL_P (ref.base)
&& TREE_CODE (type = TREE_TYPE (ref.base)) == ARRAY_TYPE) && 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, ...@@ -1621,19 +1623,22 @@ maybe_diag_offset_bounds (location_t loc, gcall *call, tree func, int strict,
"%G%qD pointer overflow between offset %s " "%G%qD pointer overflow between offset %s "
"and size %s accessing array %qD with type %qT", "and size %s accessing array %qD with type %qT",
call, func, rangestr[0], rangestr[1], ref.base, type)) 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 else
warning_at (loc, OPT_Warray_bounds, warned = warning_at (loc, OPT_Warray_bounds,
"%G%qD pointer overflow between offset %s " "%G%qD pointer overflow between offset %s "
"and size %s", "and size %s",
call, func, rangestr[0], rangestr[1]); call, func, rangestr[0], rangestr[1]);
} }
else else
warning_at (loc, OPT_Warray_bounds, warned = warning_at (loc, OPT_Warray_bounds,
"%G%qD pointer overflow between offset %s " "%G%qD pointer overflow between offset %s "
"and size %s", "and size %s",
call, func, rangestr[0], rangestr[1]); call, func, rangestr[0], rangestr[1]);
} }
else if (oobref == ref.base) else if (oobref == ref.base)
{ {
...@@ -1664,22 +1669,26 @@ maybe_diag_offset_bounds (location_t loc, gcall *call, tree func, int strict, ...@@ -1664,22 +1669,26 @@ maybe_diag_offset_bounds (location_t loc, gcall *call, tree func, int strict,
"of object %qD with type %qT"), "of object %qD with type %qT"),
call, func, rangestr[0], call, func, rangestr[0],
ref.base, TREE_TYPE (ref.base))) 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) else if (ref.basesize < maxobjsize)
warning_at (loc, OPT_Warray_bounds, warned = warning_at (loc, OPT_Warray_bounds,
form form
? G_("%G%qD forming offset %s is out of the bounds " ? G_("%G%qD forming offset %s is out "
"[0, %wu]") "of the bounds [0, %wu]")
: G_("%G%qD offset %s is out of the bounds [0, %wu]"), : G_("%G%qD offset %s is out "
call, func, rangestr[0], ref.basesize.to_uhwi ()); "of the bounds [0, %wu]"),
call, func, rangestr[0], ref.basesize.to_uhwi ());
else else
warning_at (loc, OPT_Warray_bounds, warned = warning_at (loc, OPT_Warray_bounds,
form form
? G_("%G%qD forming offset %s is out of bounds") ? G_("%G%qD forming offset %s is out of bounds")
: G_("%G%qD offset %s is out of bounds"), : G_("%G%qD offset %s is out of bounds"),
call, func, rangestr[0]); call, func, rangestr[0]);
} }
else if (TREE_CODE (ref.ref) == MEM_REF) 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, ...@@ -1688,24 +1697,25 @@ maybe_diag_offset_bounds (location_t loc, gcall *call, tree func, int strict,
type = TREE_TYPE (type); type = TREE_TYPE (type);
type = TYPE_MAIN_VARIANT (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 " "%G%qD offset %s from the object at %qE is out "
"of the bounds of %qT", "of the bounds of %qT",
call, func, rangestr[0], ref.base, type); call, func, rangestr[0], ref.base, type);
} }
else 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 " "%G%qD offset %s from the object at %qE is out "
"of the bounds of referenced subobject %qD with type %qT " "of the bounds of referenced subobject %qD with "
"at offset %wu", "type %qT at offset %wu",
call, func, rangestr[0], ref.base, TREE_OPERAND (ref.ref, 1), call, func, rangestr[0], ref.base,
type, ref.refoff.to_uhwi ()); TREE_OPERAND (ref.ref, 1), type,
ref.refoff.to_uhwi ());
} }
return true; return warned;
} }
/* Check a CALL statement for restrict-violations and issue warnings /* Check a CALL statement for restrict-violations and issue warnings
...@@ -1815,12 +1825,7 @@ bool ...@@ -1815,12 +1825,7 @@ bool
check_bounds_or_overlap (gcall *call, tree dst, tree src, tree dstsize, check_bounds_or_overlap (gcall *call, tree dst, tree src, tree dstsize,
tree srcsize, bool bounds_only /* = false */) tree srcsize, bool bounds_only /* = false */)
{ {
location_t loc = gimple_location (call); location_t loc = gimple_nonartificial_location (call);
if (tree block = gimple_block (call))
if (location_t *pbloc = block_nonartificial_location (block))
loc = *pbloc;
loc = expansion_point_location_if_in_system_header (loc); loc = expansion_point_location_if_in_system_header (loc);
tree func = gimple_call_fndecl (call); tree func = gimple_call_fndecl (call);
......
...@@ -1796,6 +1796,20 @@ gimple_has_location (const gimple *g) ...@@ -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. */ /* Return the file name of the location of STMT. */
static inline const char * static inline const char *
......
...@@ -5,6 +5,12 @@ ...@@ -5,6 +5,12 @@
2018-06-12 Martin Sebor <msebor@redhat.com> 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 PR c/85931
* gcc.dg/Wstringop-truncation-3.c: New test. * 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) ...@@ -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); tree func = gimple_call_fndecl (stmt);
if (lenrange[0] != 0 || !wi::neg_p (lenrange[1])) if (lenrange[0] != 0 || !wi::neg_p (lenrange[1]))
...@@ -2069,7 +2071,8 @@ handle_builtin_stxncpy (built_in_function, gimple_stmt_iterator *gsi) ...@@ -2069,7 +2071,8 @@ handle_builtin_stxncpy (built_in_function, gimple_stmt_iterator *gsi)
to strlen(S)). */ to strlen(S)). */
strinfo *silen = get_strinfo (pss->first); 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); 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