diff options
author | Martin Sebor <msebor@redhat.com> | 2019-10-09 21:35:11 +0000 |
---|---|---|
committer | Martin Sebor <msebor@gcc.gnu.org> | 2019-10-09 15:35:11 -0600 |
commit | a7160771da8b77a03317aab2c27706ba70fe3e9c (patch) | |
tree | d959d13c4cf04cf2f20c0cc56cd382c62d3b3b45 /gcc/gimple-ssa-sprintf.c | |
parent | 89e0a492af5bec8ffa2ec5d99c4858df50d22c16 (diff) | |
download | gcc-a7160771da8b77a03317aab2c27706ba70fe3e9c.zip gcc-a7160771da8b77a03317aab2c27706ba70fe3e9c.tar.gz gcc-a7160771da8b77a03317aab2c27706ba70fe3e9c.tar.bz2 |
PR tree-optimization/90879 - fold zero-equality of strcmp between a longer string and a smaller array
gcc/c-family/ChangeLog:
PR tree-optimization/90879
* c.opt (-Wstring-compare): New option.
gcc/testsuite/ChangeLog:
PR tree-optimization/90879
* gcc.dg/Wstring-compare-2.c: New test.
* gcc.dg/Wstring-compare.c: New test.
* gcc.dg/strcmpopt_3.c: Scan the optmized dump instead of strlen.
* gcc.dg/strcmpopt_6.c: New test.
* gcc.dg/strlenopt-65.c: Remove uinnecessary declarations, add
test cases.
* gcc.dg/strlenopt-66.c: Run it.
* gcc.dg/strlenopt-68.c: New test.
gcc/ChangeLog:
PR tree-optimization/90879
* builtins.c (check_access): Avoid using maxbound when null.
* calls.c (maybe_warn_nonstring_arg): Adjust to get_range_strlen change.
* doc/invoke.texi (-Wstring-compare): Document new warning option.
* gimple-fold.c (get_range_strlen_tree): Make setting maxbound
conditional.
(get_range_strlen): Overwrite initial maxbound when non-null.
* gimple-ssa-sprintf.c (get_string_length): Adjust to get_range_strlen
changes.
* tree-ssa-strlen.c (maybe_diag_stxncpy_trunc): Same.
(used_only_for_zero_equality): New function.
(handle_builtin_memcmp): Call it.
(determine_min_objsize): Return an integer instead of tree.
(get_len_or_size, strxcmp_eqz_result): New functions.
(maybe_warn_pointless_strcmp): New function.
(handle_builtin_string_cmp): Call it. Fold zero-equality of strcmp
between a longer string and a smaller array.
(get_range_strlen_dynamic): Overwrite initial maxbound when non-null.
From-SVN: r276773
Diffstat (limited to 'gcc/gimple-ssa-sprintf.c')
-rw-r--r-- | gcc/gimple-ssa-sprintf.c | 44 |
1 files changed, 24 insertions, 20 deletions
diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c index b11d798..b548bbd 100644 --- a/gcc/gimple-ssa-sprintf.c +++ b/gcc/gimple-ssa-sprintf.c @@ -1974,8 +1974,11 @@ get_string_length (tree str, unsigned eltsize, const vr_values *vr) if (!str) return fmtresult (); - /* Try to determine the dynamic string length first. */ + /* Try to determine the dynamic string length first. + Set MAXBOUND to an arbitrary non-null non-integer node as a request + to have it set to the length of the longest string in a PHI. */ c_strlen_data lendata = { }; + lendata.maxbound = str; if (eltsize == 1) get_range_strlen_dynamic (str, &lendata, vr); else @@ -1988,26 +1991,27 @@ get_string_length (tree str, unsigned eltsize, const vr_values *vr) get_range_strlen (str, &lendata, eltsize); } - /* LENDATA.MAXBOUND is null when LENDATA.MIN corresponds to the shortest - string referenced by STR. Otherwise, if it's not equal to .MINLEN it - corresponds to the bound of the largest array STR refers to, if known, - or it's SIZE_MAX otherwise. */ + /* If LENDATA.MAXBOUND is not equal to .MINLEN it corresponds to the bound + of the largest array STR refers to, if known, or it's set to SIZE_MAX + otherwise. */ /* Return the default result when nothing is known about the string. */ - if (lendata.maxbound) + if ((lendata.maxbound && !tree_fits_uhwi_p (lendata.maxbound)) + || !tree_fits_uhwi_p (lendata.maxlen)) { - if (integer_all_onesp (lendata.maxbound) - && integer_all_onesp (lendata.maxlen)) - return fmtresult (); - - if (!tree_fits_uhwi_p (lendata.maxbound) - || !tree_fits_uhwi_p (lendata.maxlen)) - return fmtresult (); - - unsigned HOST_WIDE_INT lenmax = tree_to_uhwi (max_object_size ()) - 2; - if (lenmax <= tree_to_uhwi (lendata.maxbound) - && lenmax <= tree_to_uhwi (lendata.maxlen)) - return fmtresult (); + fmtresult res; + res.nonstr = lendata.decl; + return res; + } + + unsigned HOST_WIDE_INT lenmax = tree_to_uhwi (max_object_size ()) - 2; + if (integer_zerop (lendata.minlen) + && (!lendata.maxbound || lenmax <= tree_to_uhwi (lendata.maxbound)) + && lenmax <= tree_to_uhwi (lendata.maxlen)) + { + fmtresult res; + res.nonstr = lendata.decl; + return res; } HOST_WIDE_INT min @@ -2056,9 +2060,9 @@ get_string_length (tree str, unsigned eltsize, const vr_values *vr) { /* When the upper bound is unknown (it can be zero or excessive) set the likely length to the greater of 1. If MAXBOUND is - set, also reset the length of the lower bound to zero. */ + known, also reset the length of the lower bound to zero. */ res.range.likely = res.range.min ? res.range.min : warn_level > 1; - if (lendata.maxbound) + if (lendata.maxbound && !integer_all_onesp (lendata.maxbound)) res.range.min = 0; } |