From 0a0de9636d29a378961e4c98a129421229918052 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Wed, 12 Feb 2020 13:53:49 -0700 Subject: [PATCH] PR middle-end/93646 - confusing -Wstringop-truncation on strncat where -Wstringop-overflow is expected gcc/ChangeLog: PR middle-end/93646 * tree-ssa-strlen.c (handle_builtin_stxncpy): Rename... (handle_builtin_stxncpy_strncat): ...to this. Change first argument. Issue only -Wstringop-overflow strncat, never -Wstringop-truncation. (strlen_check_and_optimize_call): Adjust callee name. gcc/testsuite/ChangeLog: PR middle-end/93646 * gcc.dg/Wstringop-overflow-31.c: New test. --- gcc/ChangeLog | 8 ++++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.dg/Wstringop-overflow-31.c | 40 ++++++++++++++++++++++++++++ gcc/tree-ssa-strlen.c | 26 +++++++++--------- 4 files changed, 67 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-31.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1927290..3332f565 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2020-02-12 Martin Sebor + + PR middle-end/93646 + * tree-ssa-strlen.c (handle_builtin_stxncpy): Rename... + (handle_builtin_stxncpy_strncat): ...to this. Change first argument. + Issue only -Wstringop-overflow strncat, never -Wstringop-truncation. + (strlen_check_and_optimize_call): Adjust callee name. + 2020-02-12 Jeff Law * config/h8300/h8300.md (comparison shortening peepholes): Drop diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1153c74..c872812 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-02-12 Martin Sebor + + PR middle-end/93646 + * gcc.dg/Wstringop-overflow-31.c: New test. + 2020-02-12 Wilco Dijkstra PR rtl-optimization/93565 diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-31.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-31.c new file mode 100644 index 0000000..24be256 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-31.c @@ -0,0 +1,40 @@ +/* PR middle-end/93646 - confusing -Wstringop-truncation on strncat where + -Wstringop-overflow is expected + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +extern __SIZE_TYPE__ strlen (const char*); +extern char* strncat (char*, const char*, __SIZE_TYPE__); + + +char a[4]; + + +void f0 (char *d, const char *s) +{ + strncat (d, s, strlen (s)); // { dg-warning "specified bound depends on the length of the source argument" } + /* { dg-message "function 'f0'.*inlined from 'f1'" "inlining stack" { target *-*-* } 0 } */ + + // Prevent f0 from being replaced by g0. + *d = 'f'; +} + +void f1 (const char *s) +{ + f0 (a, s); +} + + +static void g0 (char *d, const char *s) +{ + strncat (d, s, strlen (s)); // { dg-warning "specified bound 3 equals source length" } + /* { dg-message "function 'g0'.*inlined from 'g1'" "inlining stack" { target *-*-* } 0 } */ + + // Prevent g0 from being replaced by f0. + *d = 'g'; +} + +void g1 (void) +{ + g0 (a, "123"); +} diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index 1cd6430..9a88a85 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -192,7 +192,7 @@ struct laststmt_struct } laststmt; static int get_stridx_plus_constant (strinfo *, unsigned HOST_WIDE_INT, tree); -static void handle_builtin_stxncpy (built_in_function, gimple_stmt_iterator *); +static void handle_builtin_stxncpy_strncat (bool, gimple_stmt_iterator *); /* Sets MINMAX to either the constant value or the range VAL is in and returns either the constant value or VAL on success or null @@ -2876,10 +2876,10 @@ handle_builtin_strcpy (enum built_in_function bcode, gimple_stmt_iterator *gsi, and if so, issue an appropriate warning. */ static void -handle_builtin_strncat (built_in_function bcode, gimple_stmt_iterator *gsi) +handle_builtin_strncat (built_in_function, gimple_stmt_iterator *gsi) { /* Same as stxncpy(). */ - handle_builtin_stxncpy (bcode, gsi); + handle_builtin_stxncpy_strncat (true, gsi); } /* Return true if LEN depends on a call to strlen(SRC) in an interesting @@ -2974,8 +2974,8 @@ is_strlen_related_p (tree src, tree len) return false; } -/* Called by handle_builtin_stxncpy and by gimple_fold_builtin_strncpy - in gimple-fold.c. +/* Called by handle_builtin_stxncpy_strncat and by + gimple_fold_builtin_strncpy in gimple-fold.c. Check to see if the specified bound is a) equal to the size of the destination DST and if so, b) if it's immediately followed by DST[CNT - 1] = '\0'. If a) holds and b) does not, warn. Otherwise, @@ -3283,13 +3283,14 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt) return false; } -/* Check the arguments to the built-in forms of stpncpy and strncpy for - out-of-bounds offsets or overlapping access, and to see if the size - is derived from calling strlen() on the source argument, and if so, - issue the appropriate warning. */ +/* Check the arguments to the built-in forms of stpncpy, strncpy, and + strncat, for out-of-bounds offsets or overlapping access, and to see + if the size is derived from calling strlen() on the source argument, + and if so, issue the appropriate warning. + APPEND_P is true for strncat. */ static void -handle_builtin_stxncpy (built_in_function, gimple_stmt_iterator *gsi) +handle_builtin_stxncpy_strncat (bool append_p, gimple_stmt_iterator *gsi) { if (!strlen_to_stridx) return; @@ -3385,7 +3386,8 @@ handle_builtin_stxncpy (built_in_function, gimple_stmt_iterator *gsi) whether its value is known. Otherwise, issue the more generic -Wstringop-overflow which triggers for LEN arguments that in any meaningful way depend on strlen(SRC). */ - if (sisrc == silen + if (!append_p + && sisrc == silen && is_strlen_related_p (src, len) && warning_at (callloc, OPT_Wstringop_truncation, "%G%qD output truncated before terminating nul " @@ -5352,7 +5354,7 @@ strlen_check_and_optimize_call (gimple_stmt_iterator *gsi, bool *zero_write, case BUILT_IN_STPNCPY_CHK: case BUILT_IN_STRNCPY: case BUILT_IN_STRNCPY_CHK: - handle_builtin_stxncpy (DECL_FUNCTION_CODE (callee), gsi); + handle_builtin_stxncpy_strncat (false, gsi); break; case BUILT_IN_MEMCPY: -- 2.7.4