diff options
author | Martin Sebor <msebor@redhat.com> | 2019-01-02 06:02:37 +0000 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 2019-01-01 23:02:37 -0700 |
commit | 5d6655ebcc96030644f99eb1c431dd96e374db90 (patch) | |
tree | 254a28a425e845f22414200219cf3f13aec1f0a6 /gcc/calls.c | |
parent | 79b1c2295b3031764904ce66ae294aa57aef50ae (diff) | |
download | gcc-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.c | 41 |
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; } } |