From 931631924b3726db31f2f723e6c7d2d0d9de084f Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Tue, 24 Sep 2019 19:04:54 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 6 ++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/pr91570.c | 30 ++++++++++++++++++++++++++++++ gcc/tree-ssa-strlen.c | 26 ++++++++++++++++++-------- 4 files changed, 59 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr91570.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 47f3a006a32..ab0cef72f2b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-09-23 Martin Sebor + + 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 * tree-vectorizer.h (_stmt_vec_info::const_cond_reduc_code): diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b90eb6d13ca..f1f670bf0cf 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-23 Martin Sebor + + PR tree-optimization/91570 + * gcc.dg/pr91570.c: New test. + 2019-09-24 Marek Polacek 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 00000000000..03f268619e9 --- /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 5e1054be48e..c82bc7c4815 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; } -- 2.30.2