aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple-fold.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-fold.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-fold.c')
-rw-r--r--gcc/gimple-fold.c36
1 files changed, 22 insertions, 14 deletions
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 8d642de..a085ab2 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -1348,6 +1348,10 @@ get_range_strlen_tree (tree arg, bitmap *visited, strlen_range_kind rkind,
}
}
+ /* Set if VAL represents the maximum length based on array size (set
+ when exact length cannot be determined). */
+ bool maxbound = false;
+
if (!val && rkind == SRK_LENRANGE)
{
if (TREE_CODE (arg) == ADDR_EXPR)
@@ -1443,6 +1447,7 @@ get_range_strlen_tree (tree arg, bitmap *visited, strlen_range_kind rkind,
pdata->minlen = ssize_int (0);
}
}
+ maxbound = true;
}
if (!val)
@@ -1456,25 +1461,23 @@ get_range_strlen_tree (tree arg, bitmap *visited, strlen_range_kind rkind,
&& tree_int_cst_lt (val, pdata->minlen)))
pdata->minlen = val;
- if (pdata->maxbound)
+ if (pdata->maxbound && TREE_CODE (pdata->maxbound) == INTEGER_CST)
{
/* Adjust the tighter (more optimistic) string length bound
if necessary and proceed to adjust the more conservative
bound. */
if (TREE_CODE (val) == INTEGER_CST)
{
- if (TREE_CODE (pdata->maxbound) == INTEGER_CST)
- {
- if (tree_int_cst_lt (pdata->maxbound, val))
- pdata->maxbound = val;
- }
- else
- pdata->maxbound = build_all_ones_cst (size_type_node);
+ if (tree_int_cst_lt (pdata->maxbound, val))
+ pdata->maxbound = val;
}
else
pdata->maxbound = val;
}
- else
+ else if (pdata->maxbound || maxbound)
+ /* Set PDATA->MAXBOUND only if it either isn't INTEGER_CST or
+ if VAL corresponds to the maximum length determined based
+ on the type of the object. */
pdata->maxbound = val;
if (tight_bound)
@@ -1655,8 +1658,11 @@ get_range_strlen (tree arg, bitmap *visited,
/* Try to obtain the range of the lengths of the string(s) referenced
by ARG, or the size of the largest array ARG refers to if the range
- of lengths cannot be determined, and store all in *PDATA. ELTSIZE
- is the expected size of the string element in bytes: 1 for char and
+ of lengths cannot be determined, and store all in *PDATA which must
+ be zero-initialized on input except PDATA->MAXBOUND may be set to
+ a non-null tree node other than INTEGER_CST to request to have it
+ set to the length of the longest string in a PHI. ELTSIZE is
+ the expected size of the string element in bytes: 1 for char and
some power of 2 for wide characters.
Return true if the range [PDATA->MINLEN, PDATA->MAXLEN] is suitable
for optimization. Returning false means that a nonzero PDATA->MINLEN
@@ -1668,6 +1674,7 @@ bool
get_range_strlen (tree arg, c_strlen_data *pdata, unsigned eltsize)
{
bitmap visited = NULL;
+ tree maxbound = pdata->maxbound;
if (!get_range_strlen (arg, &visited, SRK_LENRANGE, pdata, eltsize))
{
@@ -1680,9 +1687,10 @@ get_range_strlen (tree arg, c_strlen_data *pdata, unsigned eltsize)
else if (!pdata->minlen)
pdata->minlen = ssize_int (0);
- /* Unless its null, leave the more conservative MAXBOUND unchanged. */
- if (!pdata->maxbound)
- pdata->maxbound = pdata->maxlen;
+ /* If it's unchanged from it initial non-null value, set the conservative
+ MAXBOUND to SIZE_MAX. Otherwise leave it null (if it is null). */
+ if (maxbound && pdata->maxbound == maxbound)
+ pdata->maxbound = build_all_ones_cst (size_type_node);
if (visited)
BITMAP_FREE (visited);