Commit eec5f615 by Martin Sebor Committed by Martin Sebor

PR tree-optimization/85700 - Spurious -Wstringop-truncation warning with strncat

gcc/ChangeLog:

	PR tree-optimization/85700
	* gimple-fold.c (gimple_fold_builtin_strncat): Adjust comment.
	* tree-ssa-strlen.c (is_strlen_related_p): Handle integer subtraction.
	(maybe_diag_stxncpy_trunc): Distinguish strncat from strncpy.

gcc/testsuite/ChangeLog:

	PR tree-optimization/85700
	* gcc.dg/Wstringop-truncation-4.c: New test.

From-SVN: r262110
parent 2bcd87a7
2018-06-25 Martin Sebor <msebor@redhat.com>
PR tree-optimization/85700
* gimple-fold.c (gimple_fold_builtin_strncat): Adjust comment.
* tree-ssa-strlen.c (is_strlen_related_p): Handle integer subtraction.
(maybe_diag_stxncpy_trunc): Distinguish strncat from strncpy.
2018-06-25 Martin Sebor <msebor@redhat.com>
* doc/extend.texi (Zero-length arrays): Update and clarify.
2018-06-25 Michael Meissner <meissner@linux.ibm.com>
......
......@@ -2051,10 +2051,12 @@ gimple_fold_builtin_strncat (gimple_stmt_iterator *gsi)
if (!nowarn && cmpsrc == 0)
{
tree fndecl = gimple_call_fndecl (stmt);
/* To avoid certain truncation the specified bound should also
not be equal to (or less than) the length of the source. */
location_t loc = gimple_location (stmt);
/* To avoid possible overflow the specified bound should also
not be equal to the length of the source, even when the size
of the destination is unknown (it's not an uncommon mistake
to specify as the bound to strncpy the length of the source). */
if (warning_at (loc, OPT_Wstringop_overflow_,
"%G%qD specified bound %E equals source length",
stmt, fndecl, len))
......
2018-06-25 Martin Sebor <msebor@redhat.com>
PR tree-optimization/85700
* gcc.dg/Wstringop-truncation-4.c: New test.
2018-06-25 Fritz Reese <fritzoreese@gmail.com>
PR fortran/82972
......
/* PR tree-optimization/85700 - Spurious -Wstringop-truncation warning
with strncat
{ dg-do compile }
{ dg-options "-O2 -Wno-stringop-overflow -Wstringop-truncation -ftrack-macro-expansion=0" } */
#define NOIPA __attribute__ ((noipa))
#define strncat __builtin_strncat
#define strlen __builtin_strlen
extern char a4[4], b4[4], ax[];
NOIPA void cat_a4_s1_1 (void)
{
/* There is no truncation here but since the bound of 1 equals
the length of the source string it's likely a mistake that
could cause overflow so it's diagnosed by -Wstringop-overflow */
strncat (a4, "1", 1);
}
NOIPA void cat_a4_s1_2 (void)
{
strncat (a4, "1", 2);
}
NOIPA void cat_a4_s1_3 (void)
{
strncat (a4, "1", 3);
}
NOIPA void cat_a4_s1_4 (void)
{
/* There is no truncation here but since the bound of 1 equals
the length of the source string it's likely a mistake that
could cause overflow so it's diagnosed by -Wstringop-overflow */
strncat (a4, "1", 4);
}
NOIPA void cat_a4_s1_5 (void)
{
/* A bound in excess of the destination size is diagnosed by
-Wstringop-overflow. */
strncat (a4, "1", 5);
}
NOIPA void cat_a4_s1_dlen (void)
{
strncat (a4, "1", sizeof a4 - strlen (a4) - 1);
}
NOIPA void cat_a4_s2_dlen (void)
{
strncat (a4, "12", sizeof a4 - strlen (a4) - 1); /* { dg-bogus "\\\[-Wstringop-truncation]" } */
}
NOIPA void cat_a4_b4_dlen (void)
{
strncat (a4, b4, sizeof a4 - strlen (a4) - 1); /* { dg-bogus "\\\[-Wstringop-truncation]" } */
}
NOIPA void cat_ax_b4_dlen (void)
{
strncat (ax, b4, 32 - strlen (ax) - 1); /* { dg-bogus "\\\[-Wstringop-truncation]" } */
}
......@@ -2014,6 +2014,12 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt)
gcall *call = as_a <gcall *> (stmt);
/* Set to true for strncat whose bound is derived from the length
of the destination (the expected usage pattern). */
bool cat_dstlen_bounded = false;
if (DECL_FUNCTION_CODE (func) == BUILT_IN_STRNCAT)
cat_dstlen_bounded = is_strlen_related_p (dst, cnt);
if (lenrange[0] == cntrange[1] && cntrange[0] == cntrange[1])
return warning_n (callloc, OPT_Wstringop_truncation,
cntrange[0].to_uhwi (),
......@@ -2024,7 +2030,9 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt)
"copying %E bytes from a string of the same "
"length",
call, func, cnt);
else if (wi::geu_p (lenrange[0], cntrange[1]))
else if (!cat_dstlen_bounded)
{
if (wi::geu_p (lenrange[0], cntrange[1]))
{
/* The shortest string is longer than the upper bound of
the count so the truncation is certain. */
......@@ -2057,13 +2065,15 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt)
call, func, cnt, lenrange[1].to_uhwi ());
return warning_at (callloc, OPT_Wstringop_truncation,
"%G%qD output may be truncated copying between %wu "
"and %wu bytes from a string of length %wu",
"%G%qD output may be truncated copying between "
"%wu and %wu bytes from a string of length %wu",
call, func, cntrange[0].to_uhwi (),
cntrange[1].to_uhwi (), lenrange[1].to_uhwi ());
}
}
if (cntrange[0] != cntrange[1]
if (!cat_dstlen_bounded
&& cntrange[0] != cntrange[1]
&& wi::leu_p (cntrange[0], lenrange[0])
&& wi::leu_p (cntrange[1], lenrange[0] + 1))
{
......
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