aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple-fold.c
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2017-11-21 20:01:58 +0000
committerMartin Sebor <msebor@gcc.gnu.org>2017-11-21 13:01:58 -0700
commit6a33d0ff21e941fc3a65f23a753cc318aaae82b5 (patch)
treeb3eedddc82aa715ade9b6b34cd5163e5fd23b551 /gcc/gimple-fold.c
parentab2c4ec8dcbe5d0b93d0250abd42ff9fb791e0b6 (diff)
downloadgcc-6a33d0ff21e941fc3a65f23a753cc318aaae82b5.zip
gcc-6a33d0ff21e941fc3a65f23a753cc318aaae82b5.tar.gz
gcc-6a33d0ff21e941fc3a65f23a753cc318aaae82b5.tar.bz2
PR tree-optimization/82945 - add warning for passing non-strings to functions that expect string arguments
gcc/ChangeLog: PR tree-optimization/82945 * builtins.c (expand_builtin_strlen): Call maybe_warn_nonstring_arg. * calls.h (maybe_warn_nonstring_arg): Declare new function. * calls.c (get_attr_nonstring_decl, maybe_warn_nonstring_arg): New functions. (initialize_argument_information): Call maybe_warn_nonstring_arg. * calls.h (get_attr_nonstring_decl): Declare new function. * doc/extend.texi (attribute nonstring): Update. * gimple-fold.c (gimple_fold_builtin_strncpy): Call get_attr_nonstring_decl and handle it. * tree-ssa-strlen.c (maybe_diag_stxncpy_trunc): Same. Improve detection of nul-termination. (strlen_to_stridx): Change to a pointer. (handle_builtin_strlen, handle_builtin_stxncpy): Adjust. (pass_strlen::execute): Same. gcc/testsuite/ChangeLog: PR tree-optimization/82945 * c-c++-common/Wstringop-truncation-2.c: New test. * c-c++-common/Wstringop-truncation.c: Adjust. * c-c++-common/attr-nonstring-2.c: Adjust. * c-c++-common/attr-nonstring-3.c: New test. From-SVN: r255031
Diffstat (limited to 'gcc/gimple-fold.c')
-rw-r--r--gcc/gimple-fold.c108
1 files changed, 49 insertions, 59 deletions
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 1ed6383..ea8f92e 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -62,6 +62,7 @@ along with GCC; see the file COPYING3. If not see
#include "asan.h"
#include "diagnostic-core.h"
#include "intl.h"
+#include "calls.h"
/* Return true when DECL can be referenced from current unit.
FROM_DECL (if non-null) specify constructor of variable DECL was taken from.
@@ -1558,25 +1559,31 @@ gimple_fold_builtin_strncpy (gimple_stmt_iterator *gsi,
{
gimple *stmt = gsi_stmt (*gsi);
location_t loc = gimple_location (stmt);
+ bool nonstring = get_attr_nonstring_decl (dest) != NULL_TREE;
/* If the LEN parameter is zero, return DEST. */
if (integer_zerop (len))
{
- tree fndecl = gimple_call_fndecl (stmt);
- gcall *call = as_a <gcall *> (stmt);
-
- /* Warn about the lack of nul termination: the result is not
- a (nul-terminated) string. */
- tree slen = get_maxval_strlen (src, 0);
- if (slen && !integer_zerop (slen))
- warning_at (loc, OPT_Wstringop_truncation,
- "%G%qD destination unchanged after copying no bytes "
- "from a string of length %E",
- call, fndecl, slen);
- else
- warning_at (loc, OPT_Wstringop_truncation,
- "%G%qD destination unchanged after copying no bytes",
- call, fndecl);
+ /* Avoid warning if the destination refers to a an array/pointer
+ decorate with attribute nonstring. */
+ if (!nonstring)
+ {
+ tree fndecl = gimple_call_fndecl (stmt);
+ gcall *call = as_a <gcall *> (stmt);
+
+ /* Warn about the lack of nul termination: the result is not
+ a (nul-terminated) string. */
+ tree slen = get_maxval_strlen (src, 0);
+ if (slen && !integer_zerop (slen))
+ warning_at (loc, OPT_Wstringop_truncation,
+ "%G%qD destination unchanged after copying no bytes "
+ "from a string of length %E",
+ call, fndecl, slen);
+ else
+ warning_at (loc, OPT_Wstringop_truncation,
+ "%G%qD destination unchanged after copying no bytes",
+ call, fndecl);
+ }
replace_call_with_value (gsi, dest);
return true;
@@ -1601,53 +1608,36 @@ gimple_fold_builtin_strncpy (gimple_stmt_iterator *gsi,
if (tree_int_cst_lt (ssize, len))
return false;
- if (tree_int_cst_lt (len, slen))
- {
- tree fndecl = gimple_call_fndecl (stmt);
- gcall *call = as_a <gcall *> (stmt);
-
- warning_at (loc, OPT_Wstringop_truncation,
- (tree_int_cst_equal (size_one_node, len)
- ? G_("%G%qD output truncated copying %E byte "
- "from a string of length %E")
- : G_("%G%qD output truncated copying %E bytes "
- "from a string of length %E")),
- call, fndecl, len, slen);
- }
- else if (tree_int_cst_equal (len, slen))
+ if (!nonstring)
{
- tree decl = dest;
- if (TREE_CODE (decl) == SSA_NAME)
+ if (tree_int_cst_lt (len, slen))
{
- gimple *def_stmt = SSA_NAME_DEF_STMT (decl);
- if (is_gimple_assign (def_stmt))
- {
- tree_code code = gimple_assign_rhs_code (def_stmt);
- if (code == ADDR_EXPR || code == VAR_DECL)
- decl = gimple_assign_rhs1 (def_stmt);
- }
+ tree fndecl = gimple_call_fndecl (stmt);
+ gcall *call = as_a <gcall *> (stmt);
+
+ warning_at (loc, OPT_Wstringop_truncation,
+ (tree_int_cst_equal (size_one_node, len)
+ ? G_("%G%qD output truncated copying %E byte "
+ "from a string of length %E")
+ : G_("%G%qD output truncated copying %E bytes "
+ "from a string of length %E")),
+ call, fndecl, len, slen);
+ }
+ else if (tree_int_cst_equal (len, slen))
+ {
+ tree fndecl = gimple_call_fndecl (stmt);
+ gcall *call = as_a <gcall *> (stmt);
+
+ warning_at (loc, OPT_Wstringop_truncation,
+ (tree_int_cst_equal (size_one_node, len)
+ ? G_("%G%qD output truncated before terminating nul "
+ "copying %E byte from a string of the same "
+ "length")
+ : G_("%G%qD output truncated before terminating nul "
+ "copying %E bytes from a string of the same "
+ "length")),
+ call, fndecl, len);
}
-
- if (TREE_CODE (decl) == ADDR_EXPR)
- decl = TREE_OPERAND (decl, 0);
-
- if (TREE_CODE (decl) == COMPONENT_REF)
- decl = TREE_OPERAND (decl, 1);
-
- tree fndecl = gimple_call_fndecl (stmt);
- gcall *call = as_a <gcall *> (stmt);
-
- if (!DECL_P (decl)
- || !lookup_attribute ("nonstring", DECL_ATTRIBUTES (decl)))
- warning_at (loc, OPT_Wstringop_truncation,
- (tree_int_cst_equal (size_one_node, len)
- ? G_("%G%qD output truncated before terminating nul "
- "copying %E byte from a string of the same "
- "length")
- : G_("%G%qD output truncated before terminating nul "
- "copying %E bytes from a string of the same "
- "length")),
- call, fndecl, len);
}
/* OK transform into builtin memcpy. */