From a011292a9e0c4fc64738237f01a0fd03ff07a6ae Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Fri, 26 Jan 2018 16:47:22 +0000 Subject: [PATCH] PR tree-optimization/83896 - ice in get_string_len on a call to strlen with PR tree-optimization/83896 - ice in get_string_len on a call to strlen with non-constant length gcc/ChangeLog: PR tree-optimization/83896 * tree-ssa-strlen.c (get_string_len): Rename... (get_string_cst_length): ...to this. Return HOST_WIDE_INT. Avoid assuming length is constant. (handle_char_store): Use HOST_WIDE_INT for string length. gcc/testsuite/ChangeLog: PR tree-optimization/83896 * gcc.dg/strlenopt-43.c: New test. From-SVN: r257100 --- gcc/ChangeLog | 8 ++++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/strlenopt-43.c | 15 +++++++++++++++ gcc/tree-ssa-strlen.c | 28 +++++++++++++++------------- 4 files changed, 43 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/strlenopt-43.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a65cac117f3..d37cc7836fb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2018-01-26 Martin Sebor + + PR tree-optimization/83896 + * tree-ssa-strlen.c (get_string_len): Rename... + (get_string_cst_length): ...to this. Return HOST_WIDE_INT. + Avoid assuming length is constant. + (handle_char_store): Use HOST_WIDE_INT for string length. + 2018-01-26 Uros Bizjak PR target/81763 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index adf8c01a82e..63bae36ea38 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-01-26 Martin Sebor + + PR tree-optimization/83896 + * gcc.dg/strlenopt-43.c: New. + 2018-01-26 Will Schmidt * gcc.target/powerpc/fold-vec-abs-int.c: Remove scan-assembler stanzas. diff --git a/gcc/testsuite/gcc.dg/strlenopt-43.c b/gcc/testsuite/gcc.dg/strlenopt-43.c new file mode 100644 index 00000000000..13539fcb868 --- /dev/null +++ b/gcc/testsuite/gcc.dg/strlenopt-43.c @@ -0,0 +1,15 @@ +/* PR tree-optimization/83896 - ice in get_string_len on a call to strlen + with non-constant length + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +#include "strlenopt.h" + +extern char a[5]; +extern char b[]; + +void f (void) +{ + if (strlen (b) != 4) + memcpy (a, b, sizeof a); +} diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index 4e363278ea2..c3cf432a921 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -2772,16 +2772,20 @@ handle_pointer_plus (gimple_stmt_iterator *gsi) } } -/* Check if RHS is string_cst possibly wrapped by mem_ref. */ -static int -get_string_len (tree rhs) +/* If RHS, either directly or indirectly, refers to a string of constant + length, return it. Otherwise return a negative value. */ + +static HOST_WIDE_INT +get_string_cst_length (tree rhs) { if (TREE_CODE (rhs) == MEM_REF && integer_zerop (TREE_OPERAND (rhs, 1))) { - tree rhs_addr = rhs = TREE_OPERAND (rhs, 0); + rhs = TREE_OPERAND (rhs, 0); if (TREE_CODE (rhs) == ADDR_EXPR) { + tree rhs_addr = rhs; + rhs = TREE_OPERAND (rhs, 0); if (TREE_CODE (rhs) != STRING_CST) { @@ -2789,7 +2793,9 @@ get_string_len (tree rhs) if (idx > 0) { strinfo *si = get_strinfo (idx); - if (si && si->full_string_p) + if (si + && si->full_string_p + && tree_fits_shwi_p (si->nonzero_chars)) return tree_to_shwi (si->nonzero_chars); } } @@ -2801,10 +2807,7 @@ get_string_len (tree rhs) rhs = DECL_INITIAL (rhs); if (rhs && TREE_CODE (rhs) == STRING_CST) - { - unsigned HOST_WIDE_INT ilen = strlen (TREE_STRING_POINTER (rhs)); - return ilen <= INT_MAX ? ilen : -1; - } + return strlen (TREE_STRING_POINTER (rhs)); return -1; } @@ -2821,9 +2824,6 @@ handle_char_store (gimple_stmt_iterator *gsi) tree rhs = gimple_assign_rhs1 (stmt); unsigned HOST_WIDE_INT offset = 0; - /* Set to the length of the string being assigned if known. */ - int rhslen; - if (TREE_CODE (lhs) == MEM_REF && TREE_CODE (TREE_OPERAND (lhs, 0)) == SSA_NAME) { @@ -2854,6 +2854,8 @@ handle_char_store (gimple_stmt_iterator *gsi) bool storing_nonzero_p = (!storing_zero_p && TREE_CODE (rhs) == INTEGER_CST && integer_nonzerop (rhs)); + /* Set to the length of the string being assigned if known. */ + HOST_WIDE_INT rhslen; if (si != NULL) { @@ -2967,7 +2969,7 @@ handle_char_store (gimple_stmt_iterator *gsi) } } else if (idx == 0 - && (rhslen = get_string_len (gimple_assign_rhs1 (stmt))) >= 0 + && (rhslen = get_string_cst_length (gimple_assign_rhs1 (stmt))) >= 0 && ssaname == NULL_TREE && TREE_CODE (TREE_TYPE (lhs)) == ARRAY_TYPE) { -- 2.30.2