aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple-ssa-sprintf.c
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2019-10-09 21:35:11 +0000
committerMartin Sebor <msebor@gcc.gnu.org>2019-10-09 15:35:11 -0600
commita7160771da8b77a03317aab2c27706ba70fe3e9c (patch)
treed959d13c4cf04cf2f20c0cc56cd382c62d3b3b45 /gcc/gimple-ssa-sprintf.c
parent89e0a492af5bec8ffa2ec5d99c4858df50d22c16 (diff)
downloadgcc-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.c44
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;
}