From: Jakub Jelinek Date: Tue, 13 Feb 2018 08:35:53 +0000 (+0100) Subject: re PR tree-optimization/84339 (Wrong-code with optimizing strlen) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=204a7ecb02199cdef17e445821c1effbfaf21bae;p=gcc.git re PR tree-optimization/84339 (Wrong-code with optimizing strlen) PR tree-optimization/84339 * gimple-fold.c (get_range_strlen): Set *FLEXP to true when handling ARRAY_REF where first operand is array_at_struct_end_p COMPONENT_REF. Formatting fixes. * gcc.c-torture/execute/pr84339.c: New test. From-SVN: r257618 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cd4a1c5327b..325eea60038 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2018-02-13 Jakub Jelinek + PR tree-optimization/84339 + * gimple-fold.c (get_range_strlen): Set *FLEXP to true when handling + ARRAY_REF where first operand is array_at_struct_end_p COMPONENT_REF. + Formatting fixes. + PR middle-end/84309 * match.pd (pow(C,x) -> exp(log(C)*x)): Optimize instead into exp2(log2(C)*x) if C is a power of 2 and c99 runtime is available. diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 38616923555..e556f050e43 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -1380,9 +1380,15 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited, int type, /* Set the minimum size to zero since the string in the array could have zero length. */ *minlen = ssize_int (0); + + if (TREE_CODE (TREE_OPERAND (arg, 0)) == COMPONENT_REF + && type == TREE_TYPE (TREE_OPERAND (arg, 0)) + && array_at_struct_end_p (TREE_OPERAND (arg, 0))) + *flexp = true; } else if (TREE_CODE (arg) == COMPONENT_REF - && TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 1))) == ARRAY_TYPE) + && (TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 1))) + == ARRAY_TYPE)) { /* Use the type of the member array to determine the upper bound on the length of the array. This may be overly @@ -1428,7 +1434,7 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited, int type, || integer_zerop (val)) return false; val = wide_int_to_tree (TREE_TYPE (val), - wi::sub(wi::to_wide (val), 1)); + wi::sub (wi::to_wide (val), 1)); /* Set the minimum size to zero since the string in the array could have zero length. */ *minlen = ssize_int (0); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index aafa6d3466f..cbe0b84cb47 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2018-02-13 Jakub Jelinek + PR tree-optimization/84339 + * gcc.c-torture/execute/pr84339.c: New test. + PR middle-end/84309 * gcc.dg/pr84309.c: New test. * gcc.target/i386/pr84309.c: New test. diff --git a/gcc/testsuite/gcc.c-torture/execute/pr84339.c b/gcc/testsuite/gcc.c-torture/execute/pr84339.c new file mode 100644 index 00000000000..06fa3a0d3d3 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr84339.c @@ -0,0 +1,30 @@ +/* PR tree-optimization/84339 */ + +struct S { int a; char b[1]; }; + +__attribute__((noipa)) int +foo (struct S *p) +{ + return __builtin_strlen (&p->b[0]); +} + +__attribute__((noipa)) int +bar (struct S *p) +{ + return __builtin_strlen (p->b); +} + +int +main () +{ + struct S *p = __builtin_malloc (sizeof (struct S) + 16); + if (p) + { + p->a = 1; + __builtin_strcpy (p->b, "abcdefg"); + if (foo (p) != 7 || bar (p) != 7) + __builtin_abort (); + __builtin_free (p); + } + return 0; +}