+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
--- /dev/null
+/* { 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" } } */
--- /dev/null
+/* { 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" } } */
/* 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;
}