This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[committed][tree-optimization/86711][tree-optimization/86714] Gracefully handle non-terminated strings


This is primarily Martin's work.  The core of the change here is to have
string_constant generally not return non-NUL terminated strings.
There's an additional argument which indicates if a non-NUL terminated
string can be handled and to allow string_constant to bubble up the
non-NUL terminated object.

My changes to the work in string_constant are limited to checking both
the MEMSIZE and NOSTR arguments when determining if we can return a
non-NUL terminated string.  I've also added a comment to a chunk of code
I don't think is strictly correct (thanks for raising the concern Bernd)
 and for which I have a follow-up patch.

I've also removed most of the default argument stuff.  It's really bad
to have two default arguments of the same type (tree *) -- it's too damn
easy for clients to mess that up.  The case where default arguments are
a win is when there's many call sites that we don't want to update and
which can all have the default and there isn't more than one default
arg.  In this code the number of call sites is very limited.

Bernd's 86711/86714 testcases are subsets of those Martin has already
included, so there's no need to bring those over from Bernd's patch.

In the discussion threads I did find a related test from Bernd which we
do handle correctly now, but didn't at some point in the recent past.
I've added it as widechar-3.

I've also renamed the strlenopt test from Martin's patch since there was
a name conflict between his original patch and subsequent patches that
have been installed.

Bootstrapped and regression tested on x86_64-linux-gnu.  Installing on
the trunk.

jeff
	PR tree-optimization/86714
	PR tree-optimization/86711
	* builtins.c (c_strlen): Add arguments to call to string_constant.
	* expr.c (string_constant): Add argument.  Detect missing nul
	terminator and outermost declaration it's missing in.
	* expr.h (string_constant): Add argument.
	* fold-const.c (read_from_constant_string): Add arguments to call to
	string_constant.
	(c_getstr): Likewise.
	* tree-ssa-forwprop.c (simplify_builtin_call): Likewise.
	to string_constant.
	* tree-ssa-strlen.c (get_stridx): Likewise.

	PR tree-optimization/86714
	PR tree-optimization/86711
	* gcc.c-torture/execute/memchr-1.c: New test.
	* gcc.c-torture/execute/pr86714.c: New test.
	* gcc.c-torture/execute/widechar-3.c: New test.
	* gcc.dg/strlenopt-58.c: New test.

diff --git a/gcc/builtins.c b/gcc/builtins.c
index eb69a409272..c9de1e6f1f3 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -589,7 +589,7 @@ c_strlen (tree src, int only_value, unsigned eltsize)
   /* Offset from the beginning of the string in bytes.  */
   tree byteoff;
   tree memsize;
-  src = string_constant (src, &byteoff, &memsize);
+  src = string_constant (src, &byteoff, &memsize, NULL);
   if (src == 0)
     return NULL_TREE;
 
diff --git a/gcc/expr.c b/gcc/expr.c
index 2645c259af8..cd5cf12fca6 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -11303,12 +11303,15 @@ is_aligning_offset (const_tree offset, const_tree exp)
 /* Return the tree node if an ARG corresponds to a string constant or zero
    if it doesn't.  If we return nonzero, set *PTR_OFFSET to the (possibly
    non-constant) offset in bytes within the string that ARG is accessing.
+   If NONSTR is non-null, consider valid even sequences of characters that
+   aren't nul-terminated strings.  In that case, if ARG refers to such
+   a sequence set *NONSTR to its declaration and clear it otherwise.
    The type of the offset is sizetype.  If MEM_SIZE is non-zero the storage
    size of the memory is returned.  If MEM_SIZE is zero, the string is
    only returned when it is properly zero terminated.  */
 
 tree
-string_constant (tree arg, tree *ptr_offset, tree *mem_size)
+string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *nonstr)
 {
   tree array;
   STRIP_NOPS (arg);
@@ -11362,7 +11365,7 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size)
 	return NULL_TREE;
 
       tree offset;
-      if (tree str = string_constant (arg0, &offset, mem_size))
+      if (tree str = string_constant (arg0, &offset, mem_size, nonstr))
 	{
 	  /* Avoid pointers to arrays (see bug 86622).  */
 	  if (POINTER_TYPE_P (TREE_TYPE (arg))
@@ -11404,6 +11407,9 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size)
       *ptr_offset = fold_convert (sizetype, offset);
       if (mem_size)
 	*mem_size = TYPE_SIZE_UNIT (TREE_TYPE (array));
+      /* This is not strictly correct.  FIXME in follow-up patch.  */
+      if (nonstr)
+	*nonstr = NULL_TREE;
       return array;
     }
 
@@ -11450,22 +11456,35 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size)
   if (!array_size || TREE_CODE (array_size) != INTEGER_CST)
     return NULL_TREE;
 
-  /* Avoid returning a string that doesn't fit in the array
-     it is stored in, like
+  /* Avoid returning an array that is unterminated because it lacks
+     a terminating nul, like
      const char a[4] = "abcde";
-     but do handle those that fit even if they have excess
+     but do handle those that are strings even if they have excess
      initializers, such as in
      const char a[4] = "abc\000\000";
      The excess elements contribute to TREE_STRING_LENGTH()
      but not to strlen().  */
   unsigned HOST_WIDE_INT charsize
     = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (init))));
+  /* Compute the lower bound number of elements (not bytes) in the array
+     that the string is used to initialize.  The actual size of the array
+     may be greater if the string is shorter, but the the important
+     data point is whether the literal, inlcuding the terminating nul,
+     fits the array.  */
+  unsigned HOST_WIDE_INT array_elts
+    = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (init))) / charsize;
+
+  /* Compute the string length in (wide) characters.  */
   unsigned HOST_WIDE_INT length = TREE_STRING_LENGTH (init);
   length = string_length (TREE_STRING_POINTER (init), charsize,
 			  length / charsize);
   if (mem_size)
     *mem_size = TYPE_SIZE_UNIT (TREE_TYPE (init));
-  else if (compare_tree_int (array_size, length + 1) < 0)
+  if (nonstr)
+    *nonstr = array_elts > length ? NULL_TREE : array;
+
+  if ((!mem_size && !nonstr)
+      && array_elts <= length)
     return NULL_TREE;
 
   *ptr_offset = offset;
diff --git a/gcc/expr.h b/gcc/expr.h
index d4d25645f61..4177de8060b 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -288,7 +288,7 @@ expand_normal (tree exp)
 
 /* Return the tree node and offset if a given argument corresponds to
    a string constant.  */
-extern tree string_constant (tree, tree *, tree * = NULL);
+extern tree string_constant (tree, tree *, tree *, tree *);
 
 /* Two different ways of generating switch statements.  */
 extern int try_casesi (tree, tree, tree, tree, rtx, rtx, rtx, profile_probability);
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 68bd64fcc59..bdd24c5969b 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -13779,7 +13779,7 @@ fold_read_from_constant_string (tree exp)
       location_t loc = EXPR_LOCATION (exp);
 
       if (TREE_CODE (exp) == INDIRECT_REF)
-	string = string_constant (exp1, &index);
+	string = string_constant (exp1, &index, NULL, NULL);
       else
 	{
 	  tree low_bound = array_ref_low_bound (exp);
@@ -14592,7 +14592,7 @@ c_getstr (tree src, unsigned HOST_WIDE_INT *strlen /* = NULL */,
   if (strlen)
     *strlen = 0;
 
-  src = string_constant (src, &offset_node);
+  src = string_constant (src, &offset_node, NULL, NULL);
   if (src == 0)
     return NULL;
 
diff --git a/gcc/testsuite/gcc.c-torture/execute/memchr-1.c b/gcc/testsuite/gcc.c-torture/execute/memchr-1.c
new file mode 100644
index 00000000000..ec376322992
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/memchr-1.c
@@ -0,0 +1,153 @@
+/* PR tree-optimization/86711 - wrong folding of memchr
+
+   Verify that memchr() of arrays initialized with string literals
+   where the nul doesn't fit in the array doesn't find the nul.  */
+typedef __SIZE_TYPE__  size_t;
+typedef __WCHAR_TYPE__ wchar_t;
+
+extern void* memchr (const void*, int, size_t);
+
+#define A(expr)							\
+  ((expr)							\
+   ? (void)0							\
+   : (__builtin_printf ("assertion failed on line %i: %s\n",	\
+			__LINE__, #expr),			\
+      __builtin_abort ()))
+
+static const char c = '1';
+static const char s1[1] = "1";
+static const char s4[4] = "1234";
+
+static const char s4_2[2][4] = { "1234", "5678" };
+static const char s5_3[3][5] = { "12345", "6789", "01234" };
+
+volatile int v0 = 0;
+volatile int v1 = 1;
+volatile int v2 = 2;
+volatile int v3 = 3;
+volatile int v4 = 3;
+
+void test_narrow (void)
+{
+  int i0 = 0;
+  int i1 = i0 + 1;
+  int i2 = i1 + 1;
+  int i3 = i2 + 1;
+  int i4 = i3 + 1;
+
+  A (memchr ("" + 1, 0, 0) == 0);
+
+  A (memchr (&c, 0, sizeof c) == 0);
+  A (memchr (&c + 1, 0, sizeof c - 1) == 0);
+  A (memchr (&c + i1, 0, sizeof c - i1) == 0);
+  A (memchr (&c + v1, 0, sizeof c - v1) == 0);
+
+  A (memchr (s1, 0, sizeof s1) == 0);
+  A (memchr (s1 + 1, 0, sizeof s1 - 1) == 0);
+  A (memchr (s1 + i1, 0, sizeof s1 - i1) == 0);
+  A (memchr (s1 + v1, 0, sizeof s1 - v1) == 0);
+
+  A (memchr (&s1, 0, sizeof s1) == 0);
+  A (memchr (&s1 + 1, 0, sizeof s1 - 1) == 0);
+  A (memchr (&s1 + i1, 0, sizeof s1 - i1) == 0);
+  A (memchr (&s1 + v1, 0, sizeof s1 - v1) == 0);
+
+  A (memchr (&s1[0], 0, sizeof s1) == 0);
+  A (memchr (&s1[0] + 1, 0, sizeof s1 - 1) == 0);
+  A (memchr (&s1[0] + i1, 0, sizeof s1 - i1) == 0);
+  A (memchr (&s1[0] + v1, 0, sizeof s1 - v1) == 0);
+
+  A (memchr (&s1[i0], 0, sizeof s1) == 0);
+  A (memchr (&s1[i0] + 1, 0, sizeof s1 - 1) == 0);
+  A (memchr (&s1[i0] + i1, 0, sizeof s1 - i1) == 0);
+  A (memchr (&s1[i0] + v1, 0, sizeof s1 - v1) == 0);
+
+  A (memchr (&s1[v0], 0, sizeof s1) == 0);
+  A (memchr (&s1[v0] + 1, 0, sizeof s1 - 1) == 0);
+  A (memchr (&s1[v0] + i1, 0, sizeof s1 - i1) == 0);
+  A (memchr (&s1[v0] + v1, 0, sizeof s1 - v1) == 0);
+
+
+  A (memchr (s4 + i0, 0, sizeof s4 - i0) == 0);
+  A (memchr (s4 + i1, 0, sizeof s4 - i1) == 0);
+  A (memchr (s4 + i2, 0, sizeof s4 - i2) == 0);
+  A (memchr (s4 + i3, 0, sizeof s4 - i3) == 0);
+  A (memchr (s4 + i4, 0, sizeof s4 - i4) == 0);
+
+  A (memchr (s4 + v0, 0, sizeof s4 - v0) == 0);
+  A (memchr (s4 + v1, 0, sizeof s4 - v1) == 0);
+  A (memchr (s4 + v2, 0, sizeof s4 - v2) == 0);
+  A (memchr (s4 + v3, 0, sizeof s4 - v3) == 0);
+  A (memchr (s4 + v4, 0, sizeof s4 - v4) == 0);
+
+
+  A (memchr (s4_2, 0, sizeof s4_2) == 0);
+
+  A (memchr (s4_2[0], 0, sizeof s4_2[0]) == 0);
+  A (memchr (s4_2[1], 0, sizeof s4_2[1]) == 0);
+
+  A (memchr (s4_2[0] + 1, 0, sizeof s4_2[0] - 1) == 0);
+  A (memchr (s4_2[1] + 2, 0, sizeof s4_2[1] - 2) == 0);
+  A (memchr (s4_2[1] + 3, 0, sizeof s4_2[1] - 3) == 0);
+
+  A (memchr (s4_2[v0], 0, sizeof s4_2[v0]) == 0);
+  A (memchr (s4_2[v0] + 1, 0, sizeof s4_2[v0] - 1) == 0);
+
+
+  /* The following calls must find the nul.  */
+  A (memchr ("", 0, 1) != 0);
+  A (memchr (s5_3, 0, sizeof s5_3) == &s5_3[1][4]);
+
+  A (memchr (&s5_3[0][0] + i0, 0, sizeof s5_3 - i0) == &s5_3[1][4]);
+  A (memchr (&s5_3[0][0] + i1, 0, sizeof s5_3 - i1) == &s5_3[1][4]);
+  A (memchr (&s5_3[0][0] + i2, 0, sizeof s5_3 - i2) == &s5_3[1][4]);
+  A (memchr (&s5_3[0][0] + i4, 0, sizeof s5_3 - i4) == &s5_3[1][4]);
+
+  A (memchr (&s5_3[1][i0], 0, sizeof s5_3[1] - i0) == &s5_3[1][4]);
+}
+
+static const wchar_t wc = L'1';
+static const wchar_t ws1[] = L"1";
+static const wchar_t ws4[] = L"\x00123456\x12005678\x12340078\x12345600";
+
+void test_wide (void)
+{
+  int i0 = 0;
+  int i1 = i0 + 1;
+  int i2 = i1 + 1;
+  int i3 = i2 + 1;
+  int i4 = i3 + 1;
+
+  A (memchr (L"" + 1, 0, 0) == 0);
+  A (memchr (&wc + 1, 0, 0) == 0);
+  A (memchr (L"\x12345678", 0, sizeof (wchar_t)) == 0);
+
+  const size_t nb = sizeof ws4;
+  const size_t nwb = sizeof (wchar_t);
+
+  const char *pws1 = (const char*)ws1;
+  const char *pws4 = (const char*)ws4;
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+  A (memchr (ws1, 0, sizeof ws1) == pws1 + 1);
+
+  A (memchr (&ws4[0], 0, nb) == pws4 + 3);
+  A (memchr (&ws4[1], 0, nb - 1 * nwb) == pws4 + 1 * nwb + 2);
+  A (memchr (&ws4[2], 0, nb - 2 * nwb) == pws4 + 2 * nwb + 1);
+  A (memchr (&ws4[3], 0, nb - 3 * nwb) == pws4 + 3 * nwb + 0);
+#else
+  A (memchr (ws1, 0, sizeof ws1) == pws1 + 0);
+
+  A (memchr (&ws4[0], 0, nb) == pws4 + 0);
+  A (memchr (&ws4[1], 0, nb - 1 * nwb) == pws4 + 1 * nwb + 0);
+  A (memchr (&ws4[2], 0, nb - 2 * nwb) == pws4 + 2 * nwb + 1);
+  A (memchr (&ws4[3], 0, nb - 3 * nwb) == pws4 + 3 * nwb + 2);
+#endif
+}
+
+
+int main ()
+{
+  test_narrow ();
+  test_wide ();
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr86714.c b/gcc/testsuite/gcc.c-torture/execute/pr86714.c
new file mode 100644
index 00000000000..3ad68522e71
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr86714.c
@@ -0,0 +1,26 @@
+/* PR tree-optimization/86714 - tree-ssa-forwprop.c confused by too
+   long initializer
+
+   The excessively long initializer for a[0] is undefined but this
+   test verifies that the excess elements are not considered a part
+   of the value of the array as a matter of QoI.  */
+
+const char a[2][3] = { "1234", "xyz" };
+char b[6];
+
+void *pb = b;
+
+int main ()
+{
+   __builtin_memcpy (b, a, 4);
+   __builtin_memset (b + 4, 'a', 2);
+
+   if (b[0] != '1' || b[1] != '2' || b[2] != '3'
+       || b[3] != 'x' || b[4] != 'a' || b[5] != 'a')
+     __builtin_abort ();
+
+   if (__builtin_memcmp (pb, "123xaa", 6))
+     __builtin_abort ();
+
+   return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/widechar-3.c b/gcc/testsuite/gcc.c-torture/execute/widechar-3.c
new file mode 100644
index 00000000000..0810c7dd5f4
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/widechar-3.c
@@ -0,0 +1,26 @@
+extern void abort (void);
+extern void exit (int);
+
+static int f(char *x)
+{
+   return __builtin_strlen(x);
+}
+
+int foo ()
+{
+   return f((char*)&L"abcdef"[0]);
+}
+
+
+int
+main()
+{
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+  if (foo () != 0)
+    abort ();
+#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+  if (foo () != 1)
+    abort ();
+#endif
+  exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/strlenopt-58.c b/gcc/testsuite/gcc.dg/strlenopt-58.c
new file mode 100644
index 00000000000..e0e80680936
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/strlenopt-58.c
@@ -0,0 +1,93 @@
+/* PR tree-optimization/86711 - wrong folding of memchr
+
+   Verify that calls to memchr() with constant arrays initialized
+   with wide string literals are folded.
+
+   { dg-do compile }
+   { dg-options "-O1 -Wall -fdump-tree-optimized" } */
+
+#include "strlenopt.h"
+
+typedef __WCHAR_TYPE__ wchar_t;
+
+extern void* memchr (const void*, int, size_t);
+
+#define CONCAT(x, y) x ## y
+#define CAT(x, y) CONCAT (x, y)
+#define FAILNAME(name) CAT (call_ ## name ##_on_line_, __LINE__)
+
+#define FAIL(name) do {				\
+    extern void FAILNAME (name) (void);		\
+    FAILNAME (name)();				\
+  } while (0)
+
+/* Macro to emit a call to funcation named
+   call_in_true_branch_not_eliminated_on_line_NNN()
+   for each call that's expected to be eliminated.  The dg-final
+   scan-tree-dump-time directive at the bottom of the test verifies
+   that no such call appears in output.  */
+#define ELIM(expr)							\
+  if (!(expr)) FAIL (in_true_branch_not_eliminated); else (void)0
+
+#define T(s, n) ELIM (strlen (s) == n)
+
+
+static const wchar_t wc = L'1';
+static const wchar_t ws1[] = L"1";
+static const wchar_t wsx[] = L"\x12345678";
+static const wchar_t ws4[] = L"\x00123456\x12005678\x12340078\x12345600";
+
+void test_wide (void)
+{
+  int i0 = 0;
+  int i1 = i0 + 1;
+  int i2 = i1 + 1;
+  int i3 = i2 + 1;
+  int i4 = i3 + 1;
+
+  ELIM (memchr (L"" + 1, 0, 0) == 0);
+  ELIM (memchr (&wc + 1, 0, 0) == 0);
+  ELIM (memchr (L"\x12345678", 0, sizeof (wchar_t)) == 0);
+
+  const size_t nb = sizeof ws4;
+  const size_t nwb = sizeof (wchar_t);
+
+  const char *pws1 = (const char*)ws1;
+  const char *pws4 = (const char*)ws4;
+  const char *pwsx = (const char*)wsx;
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+  ELIM (memchr (ws1, 0, sizeof ws1) == pws1 + 1);
+  ELIM (memchr (wsx, 0, sizeof wsx) == pwsx + sizeof *wsx);
+
+  ELIM (memchr (&ws4[0], 0, nb) == pws4 + 3);
+  ELIM (memchr (&ws4[1], 0, nb - 1 * nwb) == pws4 + 1 * nwb + 2);
+  ELIM (memchr (&ws4[2], 0, nb - 2 * nwb) == pws4 + 2 * nwb + 1);
+  ELIM (memchr (&ws4[3], 0, nb - 3 * nwb) == pws4 + 3 * nwb + 0);
+  ELIM (memchr (&ws4[4], 0, nb - 4 * nwb) == pws4 + 4 * nwb + 0);
+
+  ELIM (memchr (&ws4[i0], 0, nb) == pws4 + 3);
+  ELIM (memchr (&ws4[i1], 0, nb - 1 * nwb) == pws4 + 1 * nwb + 2);
+  ELIM (memchr (&ws4[i2], 0, nb - 2 * nwb) == pws4 + 2 * nwb + 1);
+  ELIM (memchr (&ws4[i3], 0, nb - 3 * nwb) == pws4 + 3 * nwb + 0);
+  ELIM (memchr (&ws4[i4], 0, nb - 4 * nwb) == pws4 + 4 * nwb + 0);
+#else
+  ELIM (memchr (ws1, 0, sizeof ws1) == pws1 + 0);
+  ELIM (memchr (wsx, 0, sizeof wsx) == pwsx + sizeof *wsx);
+
+  ELIM (memchr (&ws4[0], 0, nb) == pws4 + 0);
+  ELIM (memchr (&ws4[1], 0, nb - 1 * nwb) == pws4 + 1 * nwb + 1);
+  ELIM (memchr (&ws4[2], 0, nb - 2 * nwb) == pws4 + 2 * nwb + 2);
+  ELIM (memchr (&ws4[3], 0, nb - 3 * nwb) == pws4 + 3 * nwb + 3);
+  ELIM (memchr (&ws4[4], 0, nb - 4 * nwb) == pws4 + 4 * nwb + 0);
+
+  ELIM (memchr (&ws4[i0], 0, nb) == pws4 + 0);
+  ELIM (memchr (&ws4[i1], 0, nb - 1 * nwb) == pws4 + 1 * nwb + 1);
+  ELIM (memchr (&ws4[i2], 0, nb - 2 * nwb) == pws4 + 2 * nwb + 2);
+  ELIM (memchr (&ws4[i3], 0, nb - 3 * nwb) == pws4 + 3 * nwb + 3);
+  ELIM (memchr (&ws4[i4], 0, nb - 4 * nwb) == pws4 + 4 * nwb + 0);
+#endif
+}
+
+/* { dg-final { scan-tree-dump-times "memchr" 0 "optimized" } }
+   { dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated" 0 "optimized" } } */
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index efdf2094c8b..67133983cc3 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -1290,7 +1290,7 @@ simplify_builtin_call (gimple_stmt_iterator *gsi_p, tree callee2)
 	      lhs1 = gimple_call_lhs (stmt1);
 	      if (!tree_fits_uhwi_p (len1))
 		break;
-	      str1 = string_constant (src1, &off1);
+	      str1 = string_constant (src1, &off1, NULL, NULL);
 	      if (str1 == NULL_TREE)
 		break;
 	      if (!tree_fits_uhwi_p (off1)
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index 84e61526f94..d625b940c1f 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -336,7 +336,7 @@ get_stridx (tree exp)
 	return idx;
     }
 
-  s = string_constant (exp, &o);
+  s = string_constant (exp, &o, NULL, NULL);
   if (s != NULL_TREE
       && (o == NULL_TREE || tree_fits_shwi_p (o))
       && TREE_STRING_LENGTH (s) > 0)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]