aboutsummaryrefslogtreecommitdiff
path: root/gcc/calls.c
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2019-01-02 06:02:37 +0000
committerJeff Law <law@gcc.gnu.org>2019-01-01 23:02:37 -0700
commit5d6655ebcc96030644f99eb1c431dd96e374db90 (patch)
tree254a28a425e845f22414200219cf3f13aec1f0a6 /gcc/calls.c
parent79b1c2295b3031764904ce66ae294aa57aef50ae (diff)
downloadgcc-5d6655ebcc96030644f99eb1c431dd96e374db90.zip
gcc-5d6655ebcc96030644f99eb1c431dd96e374db90.tar.gz
gcc-5d6655ebcc96030644f99eb1c431dd96e374db90.tar.bz2
gimple-fold.h (get_range_strlen): Update prototype.
* gimple-fold.h (get_range_strlen): Update prototype. * builtins.c (check_access): Update call to get_range_strlen to use c_strlen_data pointer. Change various variable accesses to instead pull data from the c_strlen_data structure. (check_strncat_sizes, expand_builtin_strncat): Likewise. * calls.c (maybe_warn_nonstring_arg): Likewise. * tree-ssa-strlen.c (maybe_diag_stxncpy_trunc): Likewise. Reset minimum length if maximum lengh is unknown. * gimple-ssa-sprintf.c (get_string_length): Likewise. Drop code that used c_strlen, it's no longer needed. Restructure slightly. (format_string): Set unlikely range appropriately. * gimple-fold.c (get_range_strlen): Update comments. Fix minor formatting issues. (get_range_strlen): Accept c_strlen_data pointer for external call sites as well. Pass through to call to internal get_range_strlen. Adjust minlen, maxlen and maxbound as needed. (get_maxval_strlen): Update comments. (gimple_fold_builtin_strlen): Update call to get_range_strlen to use c_strlen_data pointer. Change variable accesses to instead use c_strlen_data data members. * gcc.dg/strlenopt-40.c: Disable a couple tests. * gcc.dg/strlenopt-48.c: Twiddle test. * gcc.dg/strlenopt-59.c: New test. * gcc.dg/tree-ssa/builtin-snprintf-5.c: New test. * g++.dg/init/strlen.C: New test. Co-Authored-By: Jeff Law <law@redhat.com> From-SVN: r267503
Diffstat (limited to 'gcc/calls.c')
-rw-r--r--gcc/calls.c41
1 files changed, 25 insertions, 16 deletions
diff --git a/gcc/calls.c b/gcc/calls.c
index 867ae81..04aafde 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -1569,9 +1569,11 @@ maybe_warn_nonstring_arg (tree fndecl, tree exp)
/* The bound argument to a bounded string function like strncpy. */
tree bound = NULL_TREE;
- /* The range of lengths of a string argument to one of the comparison
- functions. If the length is less than the bound it is used instead. */
- tree lenrng[2] = { NULL_TREE, NULL_TREE };
+ /* The longest known or possible string argument to one of the comparison
+ functions. If the length is less than the bound it is used instead.
+ Since the length is only used for warning and not for code generation
+ disable strict mode in the calls to get_range_strlen below. */
+ tree maxlen = NULL_TREE;
/* It's safe to call "bounded" string functions with a non-string
argument since the functions provide an explicit bound for this
@@ -1591,11 +1593,15 @@ maybe_warn_nonstring_arg (tree fndecl, tree exp)
and to adjust the range of the bound of the bounded ones. */
for (unsigned argno = 0;
argno < MIN (nargs, 2)
- && !(lenrng[1] && TREE_CODE (lenrng[1]) == INTEGER_CST); argno++)
+ && !(maxlen && TREE_CODE (maxlen) == INTEGER_CST); argno++)
{
tree arg = CALL_EXPR_ARG (exp, argno);
if (!get_attr_nonstring_decl (arg))
- get_range_strlen (arg, lenrng);
+ {
+ c_strlen_data lendata = { };
+ get_range_strlen (arg, &lendata, /* eltsize = */ 1);
+ maxlen = lendata.maxbound;
+ }
}
}
/* Fall through. */
@@ -1616,8 +1622,11 @@ maybe_warn_nonstring_arg (tree fndecl, tree exp)
{
tree arg = CALL_EXPR_ARG (exp, 0);
if (!get_attr_nonstring_decl (arg))
- get_range_strlen (arg, lenrng);
-
+ {
+ c_strlen_data lendata = { };
+ get_range_strlen (arg, &lendata, /* eltsize = */ 1);
+ maxlen = lendata.maxbound;
+ }
if (nargs > 1)
bound = CALL_EXPR_ARG (exp, 1);
break;
@@ -1658,28 +1667,28 @@ maybe_warn_nonstring_arg (tree fndecl, tree exp)
}
}
- if (lenrng[1] && TREE_CODE (lenrng[1]) == INTEGER_CST)
+ if (maxlen && !integer_all_onesp (maxlen))
{
/* Add one for the nul. */
- lenrng[1] = const_binop (PLUS_EXPR, TREE_TYPE (lenrng[1]),
- lenrng[1], size_one_node);
+ maxlen = const_binop (PLUS_EXPR, TREE_TYPE (maxlen), maxlen,
+ size_one_node);
if (!bndrng[0])
{
/* Conservatively use the upper bound of the lengths for
both the lower and the upper bound of the operation. */
- bndrng[0] = lenrng[1];
- bndrng[1] = lenrng[1];
+ bndrng[0] = maxlen;
+ bndrng[1] = maxlen;
bound = void_type_node;
}
else
{
/* Replace the bound on the operation with the upper bound
of the length of the string if the latter is smaller. */
- if (tree_int_cst_lt (lenrng[1], bndrng[0]))
- bndrng[0] = lenrng[1];
- else if (tree_int_cst_lt (lenrng[1], bndrng[1]))
- bndrng[1] = lenrng[1];
+ if (tree_int_cst_lt (maxlen, bndrng[0]))
+ bndrng[0] = maxlen;
+ else if (tree_int_cst_lt (maxlen, bndrng[1]))
+ bndrng[1] = maxlen;
}
}