diff options
author | Martin Sebor <msebor@redhat.com> | 2019-09-24 19:04:54 +0000 |
---|---|---|
committer | Martin Sebor <msebor@gcc.gnu.org> | 2019-09-24 13:04:54 -0600 |
commit | 931631924b3726db31f2f723e6c7d2d0d9de084f (patch) | |
tree | a8f82d6d6bd021080cbb44eda97228dd3e40e41e /gcc/tree-ssa-strlen.c | |
parent | a0aedc7a41c6756a30669632d3df22e05b174401 (diff) | |
download | gcc-931631924b3726db31f2f723e6c7d2d0d9de084f.zip gcc-931631924b3726db31f2f723e6c7d2d0d9de084f.tar.gz gcc-931631924b3726db31f2f723e6c7d2d0d9de084f.tar.bz2 |
PR tree-optimization/91570 - ICE in get_range_strlen_dynamic on a conditional
PR tree-optimization/91570 - ICE in get_range_strlen_dynamic on a conditional
of two strings
gcc/Changelog:
* tree-ssa-strlen.c (get_range_strlen_dynamic): Handle null and
non-constant minlen, maxlen and maxbound.
gcc/testsuite/Changelog:
* gcc.dg/pr91570.c: New test.
From-SVN: r276105
Diffstat (limited to 'gcc/tree-ssa-strlen.c')
-rw-r--r-- | gcc/tree-ssa-strlen.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index 5e1054b..c82bc7c 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -896,7 +896,8 @@ get_range_strlen_dynamic (tree src, c_strlen_data *pdata, bitmap *visited, if (!argdata.minlen || (integer_zerop (argdata.minlen) - && integer_all_onesp (argdata.maxbound) + && (!argdata.maxbound + || integer_all_onesp (argdata.maxbound)) && integer_all_onesp (argdata.maxlen))) { /* Set the upper bound of the length to unbounded. */ @@ -910,11 +911,13 @@ get_range_strlen_dynamic (tree src, c_strlen_data *pdata, bitmap *visited, || tree_int_cst_lt (argdata.minlen, pdata->minlen)) pdata->minlen = argdata.minlen; if (!pdata->maxlen - || tree_int_cst_lt (pdata->maxlen, argdata.maxlen)) + || (argdata.maxlen + && tree_int_cst_lt (pdata->maxlen, argdata.maxlen))) pdata->maxlen = argdata.maxlen; if (!pdata->maxbound - || (tree_int_cst_lt (pdata->maxbound, - argdata.maxbound) + || (argdata.maxbound + && tree_int_cst_lt (pdata->maxbound, + argdata.maxbound) && !integer_all_onesp (argdata.maxbound))) pdata->maxbound = argdata.maxbound; } @@ -944,8 +947,7 @@ get_range_strlen_dynamic (tree src, c_strlen_data *pdata, bitmap *visited, if (strinfo *si = get_strinfo (idx)) { pdata->minlen = get_string_length (si); - if (!pdata->minlen - && si->nonzero_chars) + if (!pdata->minlen && si->nonzero_chars) { if (TREE_CODE (si->nonzero_chars) == INTEGER_CST) pdata->minlen = si->nonzero_chars; @@ -989,7 +991,7 @@ get_range_strlen_dynamic (tree src, c_strlen_data *pdata, bitmap *visited, else pdata->maxlen = build_all_ones_cst (size_type_node); } - else if (TREE_CODE (pdata->minlen) == SSA_NAME) + else if (pdata->minlen && TREE_CODE (pdata->minlen) == SSA_NAME) { const value_range *vr = CONST_CAST (class vr_values *, rvals) @@ -1007,11 +1009,19 @@ get_range_strlen_dynamic (tree src, c_strlen_data *pdata, bitmap *visited, pdata->maxlen = build_all_ones_cst (size_type_node); } } - else + else if (pdata->minlen && TREE_CODE (pdata->minlen) == INTEGER_CST) { pdata->maxlen = pdata->minlen; pdata->maxbound = pdata->minlen; } + else + { + /* For PDATA->MINLEN that's a non-constant expression such + as PLUS_EXPR whose value range is unknown, set the bounds + to zero and SIZE_MAX. */ + pdata->minlen = build_zero_cst (size_type_node); + pdata->maxlen = build_all_ones_cst (size_type_node); + } return true; } |