re PR middle-end/86714 (tree-ssa-forwprop.c confused by too long initializer)
authorMartin Sebor <msebor@redhat.com>
Wed, 29 Aug 2018 17:17:08 +0000 (17:17 +0000)
committerJeff Law <law@gcc.gnu.org>
Wed, 29 Aug 2018 17:17:08 +0000 (11:17 -0600)
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.

Co-Authored-By: Bernd Edlinger <bernd.edlinger@hotmail.de>
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r263963

12 files changed:
gcc/ChangeLog
gcc/builtins.c
gcc/expr.c
gcc/expr.h
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/memchr-1.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/pr86714.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/widechar-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/strlenopt-58.c [new file with mode: 0644]
gcc/tree-ssa-forwprop.c
gcc/tree-ssa-strlen.c

index 00d6f30..3cf10ca 100644 (file)
@@ -1,3 +1,19 @@
+2018-08-29  Martin Sebor  <msebor@redhat.com>
+           Jeff Law  <law@redhat.com>
+
+       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.
+
 2018-08-29  Jan Hubicka  <jh@suse.cz>
 
        * tree-streamer-in.c (lto_input_ts_function_decl_tree_pointers):
index eb69a40..c9de1e6 100644 (file)
@@ -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;
 
index 2645c25..cd5cf12 100644 (file)
@@ -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;
index d4d2564..4177de8 100644 (file)
@@ -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);
index 68bd64f..bdd24c5 100644 (file)
@@ -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;
 
index d785c90..2011973 100644 (file)
@@ -1,3 +1,13 @@
+2018-08-29  Martin Sebor  <msebor@redhat.com>
+           Bernd Edlinger  <bernd.edlinger@hotmail.de>
+
+       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.
+
 2018-08-29  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/87132
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 (file)
index 0000000..ec37632
--- /dev/null
@@ -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 (file)
index 0000000..3ad6852
--- /dev/null
@@ -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 (file)
index 0000000..0810c7d
--- /dev/null
@@ -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 (file)
index 0000000..e0e8068
--- /dev/null
@@ -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" } } */
index efdf209..6713398 100644 (file)
@@ -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)
index 84e6152..d625b94 100644 (file)
@@ -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)