Commit 1aad7106 by Richard Sandiford Committed by Richard Sandiford

PR 81292: ICE on related strlens after r249880

r249880 installed the result of a strlen in a strinfo if the strinfo
wasn't previously a full string.  But as Jakub says in the PR comments,
we can't just do that in isolation, because there are no vdefs on the
call that would invalidate any related strinfos.

This patch updates the related strinfos if the adjustment is simple and
invalidates them otherwise.  As elsewhere, we treat adjustments of the
form strlen +/- INTEGER_CST as simple but anything else as too complex.

2017-07-04  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
	PR tree-optimization/81292
	* tree-ssa-strlen.c (handle_builtin_strlen): When setting
	full_string_p, also call adjust_related_strinfos if the adjustment
	is simple, otherwise invalidate related strinfos.

gcc/testsuite/
	PR tree-optimization/81292
	* gcc.dg/pr81292-1.c: New test.
	* gcc.dg/pr81292-2.c: Likewise.

From-SVN: r249961
parent 7c819e8a
2017-07-04 Richard Sandiford <richard.sandiford@linaro.org>
PR tree-optimization/81292
* tree-ssa-strlen.c (handle_builtin_strlen): When setting
full_string_p, also call adjust_related_strinfos if the adjustment
is simple, otherwise invalidate related strinfos.
2017-07-04 Martin Liska <mliska@suse.cz>
PR sanitizer/81040
......
2017-07-04 Richard Sandiford <richard.sandiford@linaro.org>
PR tree-optimization/81292
* gcc.dg/pr81292-1.c: New test.
* gcc.dg/pr81292-2.c: Likewise.
2017-07-04 Martin Liska <mliska@suse.cz>
PR sanitizer/81040
......
/* { dg-do run } */
/* { dg-options "-O2 -fdump-tree-strlen" } */
#include "strlenopt.h"
char a[10];
int __attribute__ ((noinline, noclone))
f1 (int n)
{
a[0] = '1';
a[1] = '2';
return strlen (a + 1) < n ? strlen (a) : 100;
}
int __attribute__ ((noinline, noclone))
f2 (char *a, int n)
{
a[0] = '1';
a[1] = '2';
return strlen (a + 1) < n ? strlen (a) : 100;
}
int
main (void)
{
char b[10];
strcpy (a + 2, "345");
strcpy (b + 2, "34567");
if (f1 (100) != 5 || f2 (b, 100) != 7)
__builtin_abort ();
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */
/* { dg-do run } */
/* { dg-options "-O2 -fdump-tree-strlen" } */
#include "strlenopt.h"
char a[] = { 0, 'a', 0, 'b', 'c', 0, 'd', 'e', 'f', 0 };
int __attribute__ ((noinline, noclone))
f1 (void)
{
a[0] = '1';
a[strlen (a)] = '2';
a[strlen (a)] = '3';
return strlen (a);
}
int __attribute__ ((noinline, noclone))
f2 (char *a)
{
a[0] = '1';
a[strlen (a)] = '2';
a[strlen (a)] = '3';
return strlen (a);
}
int
main (void)
{
char b[] = { 0, 0, 'a', 'b', 0, 0 };
if (f1 () != 9 || f2 (b) != 5)
__builtin_abort ();
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 6 "strlen" } } */
......@@ -1214,8 +1214,23 @@ handle_builtin_strlen (gimple_stmt_iterator *gsi)
/* Until now we only had a lower bound on the string length.
Install LHS as the actual length. */
si = unshare_strinfo (si);
tree old = si->nonzero_chars;
si->nonzero_chars = lhs;
si->full_string_p = true;
if (TREE_CODE (old) == INTEGER_CST)
{
location_t loc = gimple_location (stmt);
old = fold_convert_loc (loc, TREE_TYPE (lhs), old);
tree adj = fold_build2_loc (loc, MINUS_EXPR,
TREE_TYPE (lhs), lhs, old);
adjust_related_strinfos (loc, si, adj);
}
else
{
si->first = 0;
si->prev = 0;
si->next = 0;
}
}
return;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment