c++: Avoid ICE when constant evaluation of __builtin_strchr fails.
authorJason Merrill <jason@redhat.com>
Thu, 23 Jan 2020 17:43:15 +0000 (12:43 -0500)
committerJason Merrill <jason@redhat.com>
Thu, 23 Jan 2020 18:11:10 +0000 (13:11 -0500)
If we can't change the argument to &"...", use the original arg instead of
the partially munged one.

PR c++/93331 - ICE with __builtin_strchr.
* constexpr.c (cxx_eval_builtin_function_call): Use the original
argument if we didn't manage to extract a STRING_CST.

gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/testsuite/c-c++-common/pr34029-1.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/compile/pr34029-1.c [deleted file]

index f99951cb72c550579a2c49d95314f0de4024986f..b13ee2b38207e3452752f85068a33596810deb7e 100644 (file)
@@ -1,5 +1,9 @@
 2020-01-23  Jason Merrill  <jason@redhat.com>
 
+       PR c++/93331 - ICE with __builtin_strchr.
+       * constexpr.c (cxx_eval_builtin_function_call): Use the original
+       argument if we didn't manage to extract a STRING_CST.
+
        PR c++/93345 - ICE with defaulted dtor and template.
        PR c++/33799
        * decl.c (cxx_maybe_build_cleanup): Don't try to set
index 5864b67d4de0d2607e7623344bb0b36b79ef2093..f6b8f331bc9c3c21ab8d9dda81173058364e84c6 100644 (file)
@@ -1293,6 +1293,7 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
   for (i = 0; i < nargs; ++i)
     {
       tree arg = CALL_EXPR_ARG (t, i);
+      tree oarg = arg;
 
       /* To handle string built-ins we need to pass ADDR_EXPR<STRING_CST> since
         expand_builtin doesn't know how to look in the values table.  */
@@ -1327,6 +1328,8 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
            arg = braced_lists_to_strings (TREE_TYPE (arg), arg);
          if (TREE_CODE (arg) == STRING_CST)
            arg = build_address (arg);
+         else
+           arg = oarg;
        }
 
       args[i] = arg;
diff --git a/gcc/testsuite/c-c++-common/pr34029-1.c b/gcc/testsuite/c-c++-common/pr34029-1.c
new file mode 100644 (file)
index 0000000..5261129
--- /dev/null
@@ -0,0 +1,22 @@
+static const char s[] = "ab.cd.efghijk";
+
+int
+foo (const char *x)
+{
+  const char *a;
+  int b = 0;
+
+  a = __builtin_strchr (s, '.');
+  if (a == 0)
+    b = 1;
+  else if ((a = __builtin_strchr (a + 1, '.')) == 0)
+    b = 1;
+  else if (__builtin_strncmp (s, x, a - s))
+    b = 1;
+  else if (__builtin_strncmp (a + 1, x + (a - s + 1), 4) < 0)
+    b = 1;
+
+  if (b)
+    return 4;
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr34029-1.c b/gcc/testsuite/gcc.c-torture/compile/pr34029-1.c
deleted file mode 100644 (file)
index 5261129..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-static const char s[] = "ab.cd.efghijk";
-
-int
-foo (const char *x)
-{
-  const char *a;
-  int b = 0;
-
-  a = __builtin_strchr (s, '.');
-  if (a == 0)
-    b = 1;
-  else if ((a = __builtin_strchr (a + 1, '.')) == 0)
-    b = 1;
-  else if (__builtin_strncmp (s, x, a - s))
-    b = 1;
-  else if (__builtin_strncmp (a + 1, x + (a - s + 1), 4) < 0)
-    b = 1;
-
-  if (b)
-    return 4;
-  return 0;
-}