Hi!

convert.c doesn't verify the CALL_EXPRs to builtin functions have exactly
one argument (and a scalar float one) and can ICE if that is not the case
due to K&R declarations of the library functions and passing too few
arguments.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?

2019-02-27  Jakub Jelinek  <ja...@redhat.com>

        PR c/89520
        * convert.c (convert_to_real_1, convert_to_integer_1): Punt for
        builtins if they don't have a single scalar floating point argument.
        Formatting fixes.

        * gcc.dg/pr89520-1.c: New test.
        * gcc.dg/pr89520-2.c: New test.

--- gcc/convert.c.jj    2019-02-11 18:04:18.253586235 +0100
+++ gcc/convert.c       2019-02-27 21:01:19.176180131 +0100
@@ -216,12 +216,15 @@ convert_to_real_1 (tree type, tree expr,
          CASE_MATHFN (FABS)
          CASE_MATHFN (LOGB)
 #undef CASE_MATHFN
+           if (call_expr_nargs (expr) != 1
+               || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (expr, 0))))
+             break;
            {
              tree arg0 = strip_float_extensions (CALL_EXPR_ARG (expr, 0));
              tree newtype = type;
 
-             /* We have (outertype)sqrt((innertype)x).  Choose the wider mode 
from
-                the both as the safe type for operation.  */
+             /* We have (outertype)sqrt((innertype)x).  Choose the wider mode
+                from the both as the safe type for operation.  */
              if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (type))
                newtype = TREE_TYPE (arg0);
 
@@ -618,7 +621,8 @@ convert_to_integer_1 (tree type, tree ex
        CASE_FLT_FN (BUILT_IN_ROUND):
        CASE_FLT_FN_FLOATN_NX (BUILT_IN_ROUND):
          /* Only convert in ISO C99 mode and with -fno-math-errno.  */
-         if (!targetm.libc_has_function (function_c99_misc) || flag_errno_math)
+         if (!targetm.libc_has_function (function_c99_misc)
+             || flag_errno_math)
            break;
          if (outprec < TYPE_PRECISION (integer_type_node)
              || (outprec == TYPE_PRECISION (integer_type_node)
@@ -641,7 +645,8 @@ convert_to_integer_1 (tree type, tree ex
        CASE_FLT_FN (BUILT_IN_RINT):
        CASE_FLT_FN_FLOATN_NX (BUILT_IN_RINT):
          /* Only convert in ISO C99 mode and with -fno-math-errno.  */
-         if (!targetm.libc_has_function (function_c99_misc) || flag_errno_math)
+         if (!targetm.libc_has_function (function_c99_misc)
+             || flag_errno_math)
            break;
          if (outprec < TYPE_PRECISION (integer_type_node)
              || (outprec == TYPE_PRECISION (integer_type_node)
@@ -657,14 +662,20 @@ convert_to_integer_1 (tree type, tree ex
 
        CASE_FLT_FN (BUILT_IN_TRUNC):
        CASE_FLT_FN_FLOATN_NX (BUILT_IN_TRUNC):
-         return convert_to_integer_1 (type, CALL_EXPR_ARG (s_expr, 0), dofold);
+         if (call_expr_nargs (s_expr) != 1
+             || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (s_expr, 0))))
+           break;
+         return convert_to_integer_1 (type, CALL_EXPR_ARG (s_expr, 0),
+                                      dofold);
 
        default:
          break;
        }
 
-      if (fn)
-        {
+      if (fn
+         && call_expr_nargs (s_expr) == 1
+         && SCALAR_FLOAT_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (s_expr, 0))))
+       {
          tree newexpr = build_call_expr (fn, 1, CALL_EXPR_ARG (s_expr, 0));
          return convert_to_integer_1 (type, newexpr, dofold);
        }
@@ -694,7 +705,9 @@ convert_to_integer_1 (tree type, tree ex
          break;
        }
 
-      if (fn)
+      if (fn
+         && call_expr_nargs (s_expr) == 1
+         && SCALAR_FLOAT_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (s_expr, 0))))
         {
          tree newexpr = build_call_expr (fn, 1, CALL_EXPR_ARG (s_expr, 0));
          return convert_to_integer_1 (type, newexpr, dofold);
--- gcc/testsuite/gcc.dg/pr89520-1.c.jj 2019-02-27 21:12:00.036510855 +0100
+++ gcc/testsuite/gcc.dg/pr89520-1.c    2019-02-27 21:10:07.306467864 +0100
@@ -0,0 +1,13 @@
+/* PR c/89520 */
+/* { dg-do compile } */
+/* { dg-options "-Ofast -w" } */
+
+#define A(name) __typeof (__builtin_##name (0)) name (); long name##1 () { 
return name (); }
+#define B(name) A(name) A(name##f) A(name##l)
+B (ceil)
+B (floor)
+B (round)
+B (trunc)
+B (nearbyint)
+B (rint)
+B (logb)
--- gcc/testsuite/gcc.dg/pr89520-2.c.jj 2019-02-27 21:17:42.753561235 +0100
+++ gcc/testsuite/gcc.dg/pr89520-2.c    2019-02-27 21:17:19.607963044 +0100
@@ -0,0 +1,42 @@
+/* PR c/89520 */
+/* { dg-do compile } */
+/* { dg-options "-Ofast -w" } */
+
+#define A(name) __typeof (__builtin_##name (0)) name (); \
+  float name##1 () { return name (); } \
+  double name##2 () { return name (); }
+#define B(name) A(name) A(name##l)
+B (cosh)
+B (exp)
+B (exp10)
+B (exp2)
+B (expm1)
+B (gamma)
+B (j0)
+B (j1)
+B (lgamma)
+B (pow10)
+B (sinh)
+B (tgamma)
+B (y0)
+B (y1)
+B (acos)
+B (acosh)
+B (asin)
+B (asinh)
+B (atan)
+B (atanh)
+B (cbrt)
+B (cos)
+B (erf)
+B (erfc)
+B (log)
+B (log10)
+B (log2)
+B (log1p)
+B (sin)
+B (tan)
+B (tanh)
+B (sqrt)
+B (fabs)
+B (logb)

        Jakub

Reply via email to