diff mbox series

Fix convert.c ICEs on invalid builtin calls (PR c/89520)

Message ID 20190227224043.GZ7611@tucnak
State New
Headers show
Series Fix convert.c ICEs on invalid builtin calls (PR c/89520) | expand

Commit Message

Jakub Jelinek Feb. 27, 2019, 10:40 p.m. UTC
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  <jakub@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.


	Jakub

Comments

Joseph Myers Feb. 28, 2019, 12:20 a.m. UTC | #1
On Wed, 27 Feb 2019, Jakub Jelinek wrote:

> 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?

OK.
diff mbox series

Patch

--- 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)