From: Jason Merrill Date: Thu, 23 Jan 2020 17:43:15 +0000 (-0500) Subject: c++: Avoid ICE when constant evaluation of __builtin_strchr fails. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6f346913f2a87e26c6095d9fbf3d20f926c5470a;p=gcc.git c++: Avoid ICE when constant evaluation of __builtin_strchr fails. 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. --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f99951cb72c..b13ee2b3820 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2020-01-23 Jason Merrill + 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 diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 5864b67d4de..f6b8f331bc9 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -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 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 index 00000000000..526112974b2 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr34029-1.c @@ -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 index 526112974b2..00000000000 --- a/gcc/testsuite/gcc.c-torture/compile/pr34029-1.c +++ /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; -}