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 | |
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
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr91570.c | 30 | ||||
-rw-r--r-- | gcc/tree-ssa-strlen.c | 26 |
4 files changed, 59 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 47f3a00..ab0cef7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-09-23 Martin Sebor <msebor@redhat.com> + + PR tree-optimization/91570 + * tree-ssa-strlen.c (get_range_strlen_dynamic): Handle null and + non-constant minlen, maxlen and maxbound. + 2019-09-24 Richard Biener <rguenther@suse.de> * tree-vectorizer.h (_stmt_vec_info::const_cond_reduc_code): diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b90eb6d..f1f670b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-23 Martin Sebor <msebor@redhat.com> + + PR tree-optimization/91570 + * gcc.dg/pr91570.c: New test. + 2019-09-24 Marek Polacek <polacek@redhat.com> PR c++/91868 - improve -Wshadow location. diff --git a/gcc/testsuite/gcc.dg/pr91570.c b/gcc/testsuite/gcc.dg/pr91570.c new file mode 100644 index 0000000..03f2686 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr91570.c @@ -0,0 +1,30 @@ +/* PR tree-optimization/91570 - ICE in get_range_strlen_dynamic on + a conditional of two strings + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +extern char a[], b[]; + +/* Test case from comment #0 on the bug. */ + +void comment_0 (int i) +{ + a[0] = 0; + b[0] = '1'; + + const char *p = i ? b : a; + + if (__builtin_snprintf (0, 0, "%s", p) < 4) + __builtin_abort (); +} + + +/* Test case from comment #2 on the bug. */ + +void comment_2 (char *s) +{ + char *t = __builtin_strrchr (s, '/'); + __builtin_strcat (s, ".SIF"); + t = t ? t : s; + __builtin_printf ("%s", t); +} 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; } |