[1/2] Avoid implicit floating point conversions [v2]

Message ID 20200821003539.942952-2-keithp@keithp.com
State New
Headers show
Series
  • Floating point conversion warning fixes [v2]
Related show

Commit Message

Torbjorn SVENSSON via Newlib Aug. 21, 2020, 12:35 a.m.
These were found with clang -Wdouble-promotion and show places where
floating point values were being implicitly converted between
representations. These conversions can result in unexpected use of
double precision arithmetic. Those which are intentional all have an
explicit cast added.

Signed-off-by: Keith Packard <keithp@keithp.com>


v2:
	Use clang built-in classification functions.
	Declare constants as 'float' instead of double.
---
 newlib/libc/include/math.h         |  4 ++--
 newlib/libm/common/cosf.c          |  2 +-
 newlib/libm/common/exp.c           |  4 ++--
 newlib/libm/common/exp2.c          |  4 ++--
 newlib/libm/common/log.c           |  2 +-
 newlib/libm/common/log2.c          |  2 +-
 newlib/libm/common/nexttowardf.c   |  6 +++---
 newlib/libm/common/pow.c           |  6 +++---
 newlib/libm/common/sf_logb.c       |  2 +-
 newlib/libm/common/sf_pow.c        |  2 +-
 newlib/libm/common/sincosf.c       |  2 +-
 newlib/libm/common/sinf.c          |  2 +-
 newlib/libm/common/sqrtl.c         |  6 +++---
 newlib/libm/complex/cacos.c        |  4 ++--
 newlib/libm/complex/cacosh.c       |  2 +-
 newlib/libm/complex/cacoshl.c      |  2 +-
 newlib/libm/complex/cacosl.c       |  2 +-
 newlib/libm/complex/casin.c        | 14 +++++++-------
 newlib/libm/complex/casinh.c       |  2 +-
 newlib/libm/complex/casinhl.c      |  2 +-
 newlib/libm/complex/casinl.c       | 14 +++++++-------
 newlib/libm/complex/catan.c        |  4 ++--
 newlib/libm/complex/catanh.c       |  2 +-
 newlib/libm/complex/catanhl.c      |  2 +-
 newlib/libm/complex/catanl.c       |  4 ++--
 newlib/libm/complex/ccos.c         |  2 +-
 newlib/libm/complex/ccosh.c        |  2 +-
 newlib/libm/complex/ccoshl.c       |  2 +-
 newlib/libm/complex/ccosl.c        |  2 +-
 newlib/libm/complex/cephes_subrf.c |  4 ++--
 newlib/libm/complex/cexp.c         |  2 +-
 newlib/libm/complex/cexpl.c        |  2 +-
 newlib/libm/complex/clog.c         |  2 +-
 newlib/libm/complex/clog10.c       |  2 +-
 newlib/libm/complex/clogl.c        |  2 +-
 newlib/libm/complex/cpow.c         |  4 ++--
 newlib/libm/complex/cpowl.c        |  4 ++--
 newlib/libm/complex/cproj.c        |  6 +++---
 newlib/libm/complex/cprojl.c       |  2 +-
 newlib/libm/complex/csin.c         |  2 +-
 newlib/libm/complex/csinh.c        |  2 +-
 newlib/libm/complex/csinhl.c       |  2 +-
 newlib/libm/complex/csinl.c        |  2 +-
 newlib/libm/complex/csqrt.c        | 16 ++++++++--------
 newlib/libm/complex/csqrtl.c       |  2 +-
 newlib/libm/complex/ctan.c         |  4 ++--
 newlib/libm/complex/ctanh.c        |  2 +-
 newlib/libm/complex/ctanhl.c       |  2 +-
 newlib/libm/complex/ctanl.c        |  4 ++--
 newlib/libm/math/wf_scalb.c        |  4 ++--
 50 files changed, 89 insertions(+), 89 deletions(-)

-- 
2.28.0

Comments

Torbjorn SVENSSON via Newlib Aug. 24, 2020, 9:58 a.m. | #1
On Aug 20 17:35, Keith Packard via Newlib wrote:
> These were found with clang -Wdouble-promotion and show places where

> floating point values were being implicitly converted between

> representations. These conversions can result in unexpected use of

> double precision arithmetic. Those which are intentional all have an

> explicit cast added.

> [...]

> diff --git a/newlib/libm/common/exp.c b/newlib/libm/common/exp.c

> index 12c08c992..f3e95c6f5 100644

> --- a/newlib/libm/common/exp.c

> +++ b/newlib/libm/common/exp.c

> @@ -114,9 +114,9 @@ exp (double x)

>  	return WANT_ROUNDING ? 1.0 + x : 1.0;

>        if (abstop >= top12 (1024.0))

>  	{

> -	  if (asuint64 (x) == asuint64 (-INFINITY))

> +	  if (asuint64 (x) == asuint64 ((double) -INFINITY))

>  	    return 0.0;

> -	  if (abstop >= top12 (INFINITY))

> +	  if (abstop >= top12 ((double) INFINITY))


Not taking implicit compiler optimisations into account, wouldn't it
make more sense to avoid the conversion altogether, using
__builtin_inf() in these places?


Thanks,
Corinna
Torbjorn SVENSSON via Newlib Aug. 24, 2020, 3:33 p.m. | #2
Corinna Vinschen via Newlib <newlib@sourceware.org> writes:

> Not taking implicit compiler optimisations into account, wouldn't it

> make more sense to avoid the conversion altogether, using

> __builtin_inf() in these places?


Yeah, could do that instead. I think it's mostly a matter of what looks
better -- using the "standard" value of INFINITY and casting or using a
compiler internal value without. I think it'll confuse an equal number
of people either way.

Any preferences?

-- 
-keith
Torbjorn SVENSSON via Newlib Aug. 25, 2020, 11:10 a.m. | #3
On Aug 24 08:33, Keith Packard via Newlib wrote:
> Corinna Vinschen via Newlib <newlib@sourceware.org> writes:

> 

> > Not taking implicit compiler optimisations into account, wouldn't it

> > make more sense to avoid the conversion altogether, using

> > __builtin_inf() in these places?

> 

> Yeah, could do that instead. I think it's mostly a matter of what looks

> better -- using the "standard" value of INFINITY and casting or using a

> compiler internal value without. I think it'll confuse an equal number

> of people either way.

> 

> Any preferences?


__builtin_inf(), or a sufficiently expressive macro.  It's pretty
unfortunate that POSIX defines INFINITY and NAN as float, rather than
providing type-matching macros as in HUGE_VALF - HUGE_VAL - HUGE_VALL.

Something like #define _INF (__builtin_inf()) comes to mind.


Corinna
Thomas Wucher Aug. 25, 2020, 1:37 p.m. | #4
On 24.08.20 08:33, Keith Packard via Newlib wrote:
> Corinna Vinschen via Newlib <newlib@sourceware.org> writes:

>

> > Not taking implicit compiler optimisations into account, wouldn't it

> > make more sense to avoid the conversion altogether, using

> > __builtin_inf() in these places?

>

> Yeah, could do that instead. I think it's mostly a matter of what looks

> better -- using the "standard" value of INFINITY and casting or using a

> compiler internal value without. I think it'll confuse an equal number

> of people either way.

>

> Any preferences?


We would prefer the use of the standard C/Posix macros. This way the exact
inf/nan return value can be controlled at a central point in the library
and does not depend on a specific compiler implementation of the
builtins.

This ensures reproducible results across different compilers.

>

> --

> -keith


Regards
Thomas

Patch

diff --git a/newlib/libc/include/math.h b/newlib/libc/include/math.h
index 5e6155cc4..3399d3649 100644
--- a/newlib/libc/include/math.h
+++ b/newlib/libc/include/math.h
@@ -12,7 +12,7 @@  _BEGIN_STD_C
 /* Natural log of 2 */
 #define _M_LN2        0.693147180559945309417
 
-#if __GNUC_PREREQ (3, 3)
+#if __GNUC_PREREQ (3, 3) || defined(__clang__)
  /* gcc >= 3.3 implicitly defines builtins for HUGE_VALx values.  */
 
 # ifndef HUGE_VAL
@@ -217,7 +217,7 @@  extern int __signbitd (double x);
  *       taking double arguments still exist for compatibility purposes
  *       (prototypes for them are earlier in this header).  */
 
-#if __GNUC_PREREQ (4, 4)
+#if __GNUC_PREREQ (4, 4) || defined(__clang__)
   #define fpclassify(__x) (__builtin_fpclassify (FP_NAN, FP_INFINITE, \
 						 FP_NORMAL, FP_SUBNORMAL, \
 						 FP_ZERO, __x))
diff --git a/newlib/libm/common/cosf.c b/newlib/libm/common/cosf.c
index 1fafcbc24..7f59adf13 100644
--- a/newlib/libm/common/cosf.c
+++ b/newlib/libm/common/cosf.c
@@ -41,7 +41,7 @@ 
 float
 cosf (float y)
 {
-  double x = y;
+  double x = (double) y;
   double s;
   int n;
   const sincos_t *p = &__sincosf_table[0];
diff --git a/newlib/libm/common/exp.c b/newlib/libm/common/exp.c
index 12c08c992..f3e95c6f5 100644
--- a/newlib/libm/common/exp.c
+++ b/newlib/libm/common/exp.c
@@ -114,9 +114,9 @@  exp (double x)
 	return WANT_ROUNDING ? 1.0 + x : 1.0;
       if (abstop >= top12 (1024.0))
 	{
-	  if (asuint64 (x) == asuint64 (-INFINITY))
+	  if (asuint64 (x) == asuint64 ((double) -INFINITY))
 	    return 0.0;
-	  if (abstop >= top12 (INFINITY))
+	  if (abstop >= top12 ((double) INFINITY))
 	    return 1.0 + x;
 	  if (asuint64 (x) >> 63)
 	    return __math_uflow (0);
diff --git a/newlib/libm/common/exp2.c b/newlib/libm/common/exp2.c
index becee94d7..e21ef6a44 100644
--- a/newlib/libm/common/exp2.c
+++ b/newlib/libm/common/exp2.c
@@ -112,9 +112,9 @@  exp2 (double x)
 	return WANT_ROUNDING ? 1.0 + x : 1.0;
       if (abstop >= top12 (1024.0))
 	{
-	  if (asuint64 (x) == asuint64 (-INFINITY))
+	  if (asuint64 (x) == asuint64 ((double) -INFINITY))
 	    return 0.0;
-	  if (abstop >= top12 (INFINITY))
+	  if (abstop >= top12 ((double) INFINITY))
 	    return 1.0 + x;
 	  if (!(asuint64 (x) >> 63))
 	    return __math_oflow (0);
diff --git a/newlib/libm/common/log.c b/newlib/libm/common/log.c
index 18c05ff3c..46de2dacb 100644
--- a/newlib/libm/common/log.c
+++ b/newlib/libm/common/log.c
@@ -124,7 +124,7 @@  log (double x)
       /* x < 0x1p-1022 or inf or nan.  */
       if (ix * 2 == 0)
 	return __math_divzero (1);
-      if (ix == asuint64 (INFINITY)) /* log(inf) == inf.  */
+      if (ix == asuint64 ((double) INFINITY)) /* log(inf) == inf.  */
 	return x;
       if ((top & 0x8000) || (top & 0x7ff0) == 0x7ff0)
 	return __math_invalid (x);
diff --git a/newlib/libm/common/log2.c b/newlib/libm/common/log2.c
index e48c16cf8..d10e2847b 100644
--- a/newlib/libm/common/log2.c
+++ b/newlib/libm/common/log2.c
@@ -100,7 +100,7 @@  double
       /* x < 0x1p-1022 or inf or nan.  */
       if (ix * 2 == 0)
 	return __math_divzero (1);
-      if (ix == asuint64 (INFINITY)) /* log(inf) == inf.  */
+      if (ix == asuint64 ((double) INFINITY)) /* log(inf) == inf.  */
 	return x;
       if ((top & 0x8000) || (top & 0x7ff0) == 0x7ff0)
 	return __math_invalid (x);
diff --git a/newlib/libm/common/nexttowardf.c b/newlib/libm/common/nexttowardf.c
index e2a1d90e6..616247e9d 100644
--- a/newlib/libm/common/nexttowardf.c
+++ b/newlib/libm/common/nexttowardf.c
@@ -42,15 +42,15 @@  nexttowardf (float x, long double y)
   uint32_t e;
 
   if (isnan(x) || isnan(y))
-    return x + y;
-  if (x == y)
+    return (long double) x + y;
+  if ((long double) x == y)
     return y;
   ux.value = x;
   if (x == 0) {
     ux.bits = 1;
     if (signbit(y))
       ux.bits |= 0x80000000;
-  } else if (x < y) {
+  } else if ((long double) x < y) {
     if (signbit(x))
       ux.bits--;
     else
diff --git a/newlib/libm/common/pow.c b/newlib/libm/common/pow.c
index ff37716c5..a95de465c 100644
--- a/newlib/libm/common/pow.c
+++ b/newlib/libm/common/pow.c
@@ -289,7 +289,7 @@  checkint (uint64_t iy)
 static inline int
 zeroinfnan (uint64_t i)
 {
-  return 2 * i - 1 >= 2 * asuint64 (INFINITY) - 1;
+  return 2 * i - 1 >= 2 * asuint64 ((double) INFINITY) - 1;
 }
 
 double
@@ -316,8 +316,8 @@  pow (double x, double y)
 	    return issignaling_inline (x) ? x + y : 1.0;
 	  if (ix == asuint64 (1.0))
 	    return issignaling_inline (y) ? x + y : 1.0;
-	  if (2 * ix > 2 * asuint64 (INFINITY)
-	      || 2 * iy > 2 * asuint64 (INFINITY))
+	  if (2 * ix > 2 * asuint64 ((double) INFINITY)
+	      || 2 * iy > 2 * asuint64 ((double) INFINITY))
 	    return x + y;
 	  if (2 * ix == 2 * asuint64 (1.0))
 	    return 1.0;
diff --git a/newlib/libm/common/sf_logb.c b/newlib/libm/common/sf_logb.c
index 75336a1e0..8319a47ff 100644
--- a/newlib/libm/common/sf_logb.c
+++ b/newlib/libm/common/sf_logb.c
@@ -36,7 +36,7 @@  float x;
 		float  xx;
 		/* arg==0:  return -inf and raise divide-by-zero exception */
 		SET_FLOAT_WORD(xx,hx);	/* +0.0 */
-		return -1./xx;	/* logbf(0) = -inf */
+		return -1.f/xx;	/* logbf(0) = -inf */
 		}
 	if(FLT_UWORD_IS_SUBNORMAL(hx)) {
 	    for (ix = -126,hx<<=8; hx>0; hx<<=1) ix -=1;
diff --git a/newlib/libm/common/sf_pow.c b/newlib/libm/common/sf_pow.c
index 2946c611b..1820cc868 100644
--- a/newlib/libm/common/sf_pow.c
+++ b/newlib/libm/common/sf_pow.c
@@ -213,7 +213,7 @@  powf (float x, float y)
 	}
     }
   double_t logx = log2_inline (ix);
-  double_t ylogx = y * logx; /* Note: cannot overflow, y is single prec.  */
+  double_t ylogx = (double) y * logx; /* Note: cannot overflow, y is single prec.  */
   if (__builtin_expect ((asuint64 (ylogx) >> 47 & 0xffff)
 			  >= asuint64 (126.0 * POWF_SCALE) >> 47,
 			0))
diff --git a/newlib/libm/common/sincosf.c b/newlib/libm/common/sincosf.c
index 5053baf26..538cc5673 100644
--- a/newlib/libm/common/sincosf.c
+++ b/newlib/libm/common/sincosf.c
@@ -41,7 +41,7 @@ 
 void
 sincosf (float y, float *sinp, float *cosp)
 {
-  double x = y;
+  double x = (double) y;
   double s;
   int n;
   const sincos_t *p = &__sincosf_table[0];
diff --git a/newlib/libm/common/sinf.c b/newlib/libm/common/sinf.c
index 8cb77ef81..4f4e6d3ae 100644
--- a/newlib/libm/common/sinf.c
+++ b/newlib/libm/common/sinf.c
@@ -40,7 +40,7 @@ 
 float
 sinf (float y)
 {
-  double x = y;
+  double x = (double) y;
   double s;
   int n;
   const sincos_t *p = &__sincosf_table[0];
diff --git a/newlib/libm/common/sqrtl.c b/newlib/libm/common/sqrtl.c
index 9976f35e7..e58255724 100644
--- a/newlib/libm/common/sqrtl.c
+++ b/newlib/libm/common/sqrtl.c
@@ -143,7 +143,7 @@  sqrtl (long double x)
   if (ux.extu_ext.ext_exp == 0)
     {
       /* Adjust subnormal numbers.  */
-      ux.extu_ld *= 0x1.0p514;
+      ux.extu_ld *= 0x1.0p514l;
       k = -514;
     }
   else
@@ -167,10 +167,10 @@  sqrtl (long double x)
   /* Newton's iteration.
      Split ux.extu_ld into a high and low part to achieve additional precision.  */
 
-  xn = sqrt ((double) ux.extu_ld);	/* 53-bit estimate of sqrtl(x).  */
+  xn = (long double) sqrt ((double) ux.extu_ld);	/* 53-bit estimate of sqrtl(x).  */
 
 #if LDBL_MANT_DIG > 100
-  xn = (xn + (ux.extu_ld / xn)) * 0.5;	/* 106-bit estimate.  */
+  xn = (xn + (ux.extu_ld / xn)) * 0.5l;	/* 106-bit estimate.  */
 #endif
 
   lo = ux.extu_ld;
diff --git a/newlib/libm/complex/cacos.c b/newlib/libm/complex/cacos.c
index 2b0b82a56..900e50944 100644
--- a/newlib/libm/complex/cacos.c
+++ b/newlib/libm/complex/cacos.c
@@ -87,13 +87,13 @@  cacos(double complex z)
 	   a hopefully temporary workaround. */
 #if 0
 	w = casin(z);
-	w = (M_PI_2 - creal(w)) - cimag(w) * I;
+	w = (M_PI_2 - creal(w)) - cimag(w) * (double complex) (double complex) I;
 #else
 	double complex tmp0, tmp1;
 
 	tmp0 = casin(z);
 	tmp1 = M_PI_2 - creal(tmp0);
-	w = tmp1 - (cimag(tmp0) * I);
+	w = tmp1 - (cimag(tmp0) * (double complex) (double complex) I);
 #endif
 	return w;
 }
diff --git a/newlib/libm/complex/cacosh.c b/newlib/libm/complex/cacosh.c
index 857b5c3a0..164538663 100644
--- a/newlib/libm/complex/cacosh.c
+++ b/newlib/libm/complex/cacosh.c
@@ -85,7 +85,7 @@  cacosh(double complex z)
 	double complex w;
 
 #if 0 /* does not give the principal value */
-	w = I * cacos(z);
+	w = (double complex) I * cacos(z);
 #else
 	w = clog(z + csqrt(z + 1) * csqrt(z - 1));
 #endif
diff --git a/newlib/libm/complex/cacoshl.c b/newlib/libm/complex/cacoshl.c
index 4e4e006b9..b8c7c4e4b 100644
--- a/newlib/libm/complex/cacoshl.c
+++ b/newlib/libm/complex/cacoshl.c
@@ -37,7 +37,7 @@  cacoshl(long double complex z)
 	long double complex w;
 
 #if 0 /* does not give the principal value */
-	w = I * cacosl(z);
+	w = (double complex) I * cacosl(z);
 #else
 	w = clogl(z + csqrtl(z + 1) * csqrtl(z - 1));
 #endif
diff --git a/newlib/libm/complex/cacosl.c b/newlib/libm/complex/cacosl.c
index 6a05c8cb7..3d6489f87 100644
--- a/newlib/libm/complex/cacosl.c
+++ b/newlib/libm/complex/cacosl.c
@@ -39,7 +39,7 @@  cacosl(long double complex z)
 	long double complex w;
 
 	w = casinl(z);
-	w = (M_PI_2L - creall(w)) - cimagl(w) * I;
+	w = (M_PI_2L - creall(w)) - cimagl(w) * (double complex) I;
 	return w;
 }
 
diff --git a/newlib/libm/complex/casin.c b/newlib/libm/complex/casin.c
index ced10531e..a1e3a0734 100644
--- a/newlib/libm/complex/casin.c
+++ b/newlib/libm/complex/casin.c
@@ -95,12 +95,12 @@  casin(double complex z)
 #if 0 /* MD: test is incorrect, casin(>1) is defined */
 	if (y == 0.0) {
 		if (fabs(x) > 1.0) {
-			w = M_PI_2 + 0.0 * I;
+			w = M_PI_2 + 0.0 * (double complex) I;
 #if 0
 			mtherr ("casin", DOMAIN);
 #endif
 		} else {
-			w = asin(x) + 0.0 * I;
+			w = asin(x) + 0.0 * (double complex) I;
 		}
 		return w;
 	}
@@ -147,19 +147,19 @@  return;
 */
 
 
-	ca = x + y * I;
-	ct = ca * I;
+	ca = x + y * (double complex) I;
+	ct = ca * (double complex) I;
 	/* sqrt( 1 - z*z) */
 	/* cmul( &ca, &ca, &zz ) */
 	/*x * x  -  y * y */
-	zz = (x - y) * (x + y) + (2.0 * x * y) * I;
+	zz = (x - y) * (x + y) + (2.0 * x * y) * (double complex) I;
 
-	zz = 1.0 - creal(zz) - cimag(zz) * I;
+	zz = 1.0 - creal(zz) - cimag(zz) * (double complex) I;
 	z2 = csqrt(zz);
 
 	zz = ct + z2;
 	zz = clog(zz);
 	/* multiply by 1/i = -i */
-	w = zz * (-1.0 * I);
+	w = zz * (-1.0 * (double complex) I);
 	return w;
 }
diff --git a/newlib/libm/complex/casinh.c b/newlib/libm/complex/casinh.c
index b4326b933..6573be64e 100644
--- a/newlib/libm/complex/casinh.c
+++ b/newlib/libm/complex/casinh.c
@@ -92,6 +92,6 @@  casinh(double complex z)
 {
 	double complex w;
 
-	w = -1.0 * I * casin(z * I);
+	w = -1.0 * (double complex) I * casin(z * (double complex) I);
 	return w;
 }
diff --git a/newlib/libm/complex/casinhl.c b/newlib/libm/complex/casinhl.c
index 2864791ea..44c2bdc01 100644
--- a/newlib/libm/complex/casinhl.c
+++ b/newlib/libm/complex/casinhl.c
@@ -36,6 +36,6 @@  casinhl(long double complex z)
 {
 	long double complex w;
 
-	w = -1.0L * I * casinl(z * I);
+	w = -1.0L * (double complex) I * casinl(z * (double complex) I);
 	return w;
 }
diff --git a/newlib/libm/complex/casinl.c b/newlib/libm/complex/casinl.c
index 488488974..b073b5e3c 100644
--- a/newlib/libm/complex/casinl.c
+++ b/newlib/libm/complex/casinl.c
@@ -49,12 +49,12 @@  casinl(long double complex z)
 #if 0 /* MD: test is incorrect, casin(>1) is defined */
 	if (y == 0.0L) {
 		if (fabsl(x) > 1.0L) {
-			w = M_PI_2L + 0.0L * I;
+			w = M_PI_2L + 0.0L * (double complex) I;
 #if 0
 			mtherr ("casinl", DOMAIN);
 #endif
 		} else {
-			w = asinl(x) + 0.0L * I;
+			w = asinl(x) + 0.0L * (double complex) I;
 		}
 		return w;
 	}
@@ -101,20 +101,20 @@  return;
 */
 
 
-	ca = x + y * I;
-	ct = ca * I;
+	ca = x + y * (double complex) I;
+	ct = ca * (double complex) I;
 	/* sqrtl( 1 - z*z) */
 	/* cmull( &ca, &ca, &zz ) */
 	/*x * x  -  y * y */
-	zz = (x - y) * (x + y) + (2.0L * x * y) * I;
+	zz = (x - y) * (x + y) + (2.0L * x * y) * (double complex) I;
 
-	zz = 1.0L - creall(zz) - cimagl(zz) * I;
+	zz = 1.0L - creall(zz) - cimagl(zz) * (double complex) I;
 	z2 = csqrtl(zz);
 
 	zz = ct + z2;
 	zz = clogl(zz);
 	/* multiply by 1/i = -i */
-	w = zz * (-1.0L * I);
+	w = zz * (-1.0L * (double complex) I);
 	return w;
 }
 
diff --git a/newlib/libm/complex/catan.c b/newlib/libm/complex/catan.c
index 77510ec2f..3b8040e7e 100644
--- a/newlib/libm/complex/catan.c
+++ b/newlib/libm/complex/catan.c
@@ -118,13 +118,13 @@  catan(double complex z)
 
 	t = y + 1.0;
 	a = (x2 + (t * t))/a;
-	w = w + (0.25 * log(a)) * I;
+	w = w + (0.25 * log(a)) * (double complex) I;
 	return w;
 
 ovrf:
 #if 0
 	mtherr ("catan", OVERFLOW);
 #endif
-	w = HUGE_VAL + HUGE_VAL * I;
+	w = HUGE_VAL + HUGE_VAL * (double complex) I;
 	return w;
 }
diff --git a/newlib/libm/complex/catanh.c b/newlib/libm/complex/catanh.c
index 1bb05559c..807e0e4b2 100644
--- a/newlib/libm/complex/catanh.c
+++ b/newlib/libm/complex/catanh.c
@@ -85,6 +85,6 @@  catanh(double complex z)
 {
 	double complex w;
 
-	w = -1.0 * I * catan(z * I);
+	w = -1.0 * (double complex) I * catan(z * (double complex) I);
 	return w;
 }
diff --git a/newlib/libm/complex/catanhl.c b/newlib/libm/complex/catanhl.c
index 8975fe85e..417bbc69d 100644
--- a/newlib/libm/complex/catanhl.c
+++ b/newlib/libm/complex/catanhl.c
@@ -36,6 +36,6 @@  catanhl(long double complex z)
 {
 	long double complex w;
 
-	w = -1.0L * I * catanl(z * I);
+	w = -1.0L * (double complex) I * catanl(z * (double complex) I);
 	return w;
 }
diff --git a/newlib/libm/complex/catanl.c b/newlib/libm/complex/catanl.c
index ee2a25930..3e696d8cb 100644
--- a/newlib/libm/complex/catanl.c
+++ b/newlib/libm/complex/catanl.c
@@ -64,14 +64,14 @@  catanl(long double complex z)
 
 	t = y + 1.0L;
 	a = (x2 + (t * t))/a;
-	w = w + (0.25L * logl(a)) * I;
+	w = w + (0.25L * logl(a)) * (double complex) I;
 	return w;
 
 ovrf:
 #if 0
 	mtherr ("catanl", OVERFLOW);
 #endif
-	w = HUGE_VALL + HUGE_VALL * I;
+	w = HUGE_VALL + HUGE_VALL * (double complex) I;
 	return w;
 }
 
diff --git a/newlib/libm/complex/ccos.c b/newlib/libm/complex/ccos.c
index 516632e56..1021445c1 100644
--- a/newlib/libm/complex/ccos.c
+++ b/newlib/libm/complex/ccos.c
@@ -76,6 +76,6 @@  ccos(double complex z)
 	double ch, sh;
 
 	_cchsh(cimag(z), &ch, &sh);
-	w = cos(creal(z)) * ch - (sin(creal(z)) * sh) * I;
+	w = cos(creal(z)) * ch - (sin(creal(z)) * sh) * (double complex) I;
 	return w;
 }
diff --git a/newlib/libm/complex/ccosh.c b/newlib/libm/complex/ccosh.c
index 818acc853..f60f2d0b9 100644
--- a/newlib/libm/complex/ccosh.c
+++ b/newlib/libm/complex/ccosh.c
@@ -76,6 +76,6 @@  ccosh(double complex z)
 
 	x = creal(z);
 	y = cimag(z);
-	w = cosh(x) * cos(y) + (sinh(x) * sin(y)) * I;
+	w = cosh(x) * cos(y) + (sinh(x) * sin(y)) * (double complex) I;
 	return w;
 }
diff --git a/newlib/libm/complex/ccoshl.c b/newlib/libm/complex/ccoshl.c
index f59fadf7a..b8b47f6df 100644
--- a/newlib/libm/complex/ccoshl.c
+++ b/newlib/libm/complex/ccoshl.c
@@ -40,6 +40,6 @@  ccoshl(long double complex z)
 
 	x = creall(z);
 	y = cimagl(z);
-	w = coshl(x) * cosl(y) + (sinhl(x) * sinl(y)) * I;
+	w = coshl(x) * cosl(y) + (sinhl(x) * sinl(y)) * (double complex) I;
 	return w;
 }
diff --git a/newlib/libm/complex/ccosl.c b/newlib/libm/complex/ccosl.c
index c310f4024..424c00ea6 100644
--- a/newlib/libm/complex/ccosl.c
+++ b/newlib/libm/complex/ccosl.c
@@ -40,6 +40,6 @@  ccosl(long double complex z)
 	long double ch, sh;
 
 	_cchshl(cimagl(z), &ch, &sh);
-	w = cosl(creall(z)) * ch - (sinl(creall(z)) * sh) * I;
+	w = cosl(creall(z)) * ch - (sinl(creall(z)) * sh) * (double complex) I;
 	return w;
 }
diff --git a/newlib/libm/complex/cephes_subrf.c b/newlib/libm/complex/cephes_subrf.c
index 4a325811f..3ed04ddb7 100644
--- a/newlib/libm/complex/cephes_subrf.c
+++ b/newlib/libm/complex/cephes_subrf.c
@@ -61,7 +61,7 @@  _cchshf(float x, float *c, float *s)
 static const double DP1 =  3.140625;
 static const double DP2 =  9.67502593994140625E-4;
 static const double DP3 =  1.509957990978376432E-7;
-#define MACHEPF 3.0e-8
+#define MACHEPF 3.0e-8f
 
 float
 _redupif(float x)
@@ -77,7 +77,7 @@  _redupif(float x)
 
 	i = t;	/* the multiple */
 	t = i;
-	t = ((x - t * DP1) - t * DP2) - t * DP3;
+	t = (((double) x - (double) t * DP1) - (double) t * DP2) - (double) t * DP3;
 	return t;
 }
 
diff --git a/newlib/libm/complex/cexp.c b/newlib/libm/complex/cexp.c
index 1c1291da2..237f9d180 100644
--- a/newlib/libm/complex/cexp.c
+++ b/newlib/libm/complex/cexp.c
@@ -77,6 +77,6 @@  cexp(double complex z)
 	x = creal(z);
 	y = cimag(z);
 	r = exp(x);
-	w = r * cos(y) + r * sin(y) * I;
+	w = r * cos(y) + r * sin(y) * (double complex) I;
 	return w;
 }
diff --git a/newlib/libm/complex/cexpl.c b/newlib/libm/complex/cexpl.c
index 8b56634ba..913282fe9 100644
--- a/newlib/libm/complex/cexpl.c
+++ b/newlib/libm/complex/cexpl.c
@@ -41,6 +41,6 @@  cexpl(long double complex z)
 	x = creall(z);
 	y = cimagl(z);
 	r = expl(x);
-	w = r * cosl(y) + r * sinl(y) * I;
+	w = r * cosl(y) + r * sinl(y) * (double complex) I;
 	return w;
 }
diff --git a/newlib/libm/complex/clog.c b/newlib/libm/complex/clog.c
index 488f3b8fe..feb845469 100644
--- a/newlib/libm/complex/clog.c
+++ b/newlib/libm/complex/clog.c
@@ -86,6 +86,6 @@  clog(double complex z)
 	rr = cabs(z);
 	p = log(rr);
 	rr = atan2(cimag(z), creal(z));
-	w = p + rr * I;
+	w = p + rr * (double complex) I;
 	return w;
 }
diff --git a/newlib/libm/complex/clog10.c b/newlib/libm/complex/clog10.c
index f6cf45396..fdf9f4e0b 100644
--- a/newlib/libm/complex/clog10.c
+++ b/newlib/libm/complex/clog10.c
@@ -41,6 +41,6 @@  clog10(double complex z)
 	rr = cabs(z);
 	p = log10(rr);
 	rr = atan2(cimag(z), creal(z)) * M_IVLN10;
-	w = p + rr * I;
+	w = p + rr * (double complex) I;
 	return w;
 }
diff --git a/newlib/libm/complex/clogl.c b/newlib/libm/complex/clogl.c
index 3644a44fc..31a92f4ba 100644
--- a/newlib/libm/complex/clogl.c
+++ b/newlib/libm/complex/clogl.c
@@ -41,6 +41,6 @@  clogl(long double complex z)
 	rr = cabsl(z);
 	p = logl(rr);
 	rr = atan2l(cimagl(z), creall(z));
-	w = p + rr * I;
+	w = p + rr * (double complex) I;
 	return w;
 }
diff --git a/newlib/libm/complex/cpow.c b/newlib/libm/complex/cpow.c
index e7c419b63..761c1be77 100644
--- a/newlib/libm/complex/cpow.c
+++ b/newlib/libm/complex/cpow.c
@@ -87,7 +87,7 @@  cpow(double complex a, double complex z)
 	y = cimag(z);
 	absa = cabs(a);
 	if (absa == 0.0) {
-		return (0.0 + 0.0 * I);
+		return (0.0 + 0.0 * (double complex) I);
 	}
 	arga = carg(a);
 	r = pow(absa, x);
@@ -96,6 +96,6 @@  cpow(double complex a, double complex z)
 		r = r * exp(-y * arga);
 		theta = theta + y * log(absa);
 	}
-	w = r * cos(theta) + (r * sin(theta)) * I;
+	w = r * cos(theta) + (r * sin(theta)) * (double complex) I;
 	return w;
 }
diff --git a/newlib/libm/complex/cpowl.c b/newlib/libm/complex/cpowl.c
index 85c2c20f2..37877c071 100644
--- a/newlib/libm/complex/cpowl.c
+++ b/newlib/libm/complex/cpowl.c
@@ -42,7 +42,7 @@  cpowl(long double complex a, long double complex z)
 	y = cimagl(z);
 	absa = cabsl(a);
 	if (absa == 0.0L) {
-		return (0.0L + 0.0L * I);
+		return (0.0L + 0.0L * (double complex) I);
 	}
 	arga = cargl(a);
 	r = powl(absa, x);
@@ -51,6 +51,6 @@  cpowl(long double complex a, long double complex z)
 		r = r * expl(-y * arga);
 		theta = theta + y * logl(absa);
 	}
-	w = r * cosl(theta) + (r * sinl(theta)) * I;
+	w = r * cosl(theta) + (r * sinl(theta)) * (double complex) I;
 	return w;
 }
diff --git a/newlib/libm/complex/cproj.c b/newlib/libm/complex/cproj.c
index 184c71699..9ea7281a4 100644
--- a/newlib/libm/complex/cproj.c
+++ b/newlib/libm/complex/cproj.c
@@ -51,7 +51,7 @@  DESCRIPTION
         to positive infinity on the real axis. If <[z]> has an infinite part,
         then <<cproj>>(<[z]>) is equivalent to
 
-                 INFINITY + I * copysign(0.0, cimag(z))
+                 INFINITY + (double complex) I * copysign(0.0, cimag(z))
 
         <<cprojf>> is identical to <<cproj>>, except that it performs
         its calculations on <<floats complex>>.
@@ -86,7 +86,7 @@  QUICKREF
  * infinite part and one NaN part) project to positive infinity on the real axis.
  * If z has an infinite part, then cproj(z) shall be equivalent to:
  *
- * INFINITY + I * copysign(0.0, cimag(z))
+ * INFINITY + (double complex) I * copysign(0.0, cimag(z))
  */
 double complex
 cproj(double complex z)
@@ -97,7 +97,7 @@  cproj(double complex z)
 #ifdef __INFINITY
 		REAL_PART(w) = __INFINITY;
 #else
-		REAL_PART(w) = INFINITY;
+		REAL_PART(w) = (double) INFINITY;
 #endif
 		IMAG_PART(w) = copysign(0.0, cimag(z));
 	}
diff --git a/newlib/libm/complex/cprojl.c b/newlib/libm/complex/cprojl.c
index e71c77353..279325aca 100644
--- a/newlib/libm/complex/cprojl.c
+++ b/newlib/libm/complex/cprojl.c
@@ -43,7 +43,7 @@  __RCSID("$NetBSD: cprojl.c,v 1.7 2014/10/10 00:48:18 christos Exp $");
  * infinite part and one NaN part) project to positive infinity on the real axis.
  * If z has an infinite part, then cproj(z) shall be equivalent to:
  *
- * INFINITY + I * copysign(0.0, cimag(z))
+ * INFINITY + (double complex) I * copysign(0.0, cimag(z))
  */
 long double complex
 cprojl(long double complex z)
diff --git a/newlib/libm/complex/csin.c b/newlib/libm/complex/csin.c
index 24702ed70..9cd0e364e 100644
--- a/newlib/libm/complex/csin.c
+++ b/newlib/libm/complex/csin.c
@@ -76,6 +76,6 @@  csin(double complex z)
 	double ch, sh;
 
 	_cchsh(cimag(z), &ch, &sh);
-	w = sin(creal(z)) * ch + (cos(creal(z)) * sh) * I;
+	w = sin(creal(z)) * ch + (cos(creal(z)) * sh) * (double complex) I;
 	return w;
 }
diff --git a/newlib/libm/complex/csinh.c b/newlib/libm/complex/csinh.c
index b3f24eec8..a716f0d57 100644
--- a/newlib/libm/complex/csinh.c
+++ b/newlib/libm/complex/csinh.c
@@ -75,6 +75,6 @@  csinh(double complex z)
 
 	x = creal(z);
 	y = cimag(z);
-	w = sinh(x) * cos(y) + (cosh(x) * sin(y)) * I;
+	w = sinh(x) * cos(y) + (cosh(x) * sin(y)) * (double complex) I;
 	return w;
 }
diff --git a/newlib/libm/complex/csinhl.c b/newlib/libm/complex/csinhl.c
index 44ed05037..1b5b5143d 100644
--- a/newlib/libm/complex/csinhl.c
+++ b/newlib/libm/complex/csinhl.c
@@ -40,6 +40,6 @@  csinhl(long double complex z)
 
 	x = creall(z);
 	y = cimagl(z);
-	w = sinhl(x) * cosl(y) + (coshl(x) * sinl(y)) * I;
+	w = sinhl(x) * cosl(y) + (coshl(x) * sinl(y)) * (double complex) I;
 	return w;
 }
diff --git a/newlib/libm/complex/csinl.c b/newlib/libm/complex/csinl.c
index 2b96c7225..382c5d047 100644
--- a/newlib/libm/complex/csinl.c
+++ b/newlib/libm/complex/csinl.c
@@ -40,6 +40,6 @@  csinl(long double complex z)
 	long double ch, sh;
 
 	_cchshl(cimagl(z), &ch, &sh);
-	w = sinl(creall(z)) * ch + (cosl(creall(z)) * sh) * I;
+	w = sinl(creall(z)) * ch + (cosl(creall(z)) * sh) * (double complex) I;
 	return w;
 }
diff --git a/newlib/libm/complex/csqrt.c b/newlib/libm/complex/csqrt.c
index aecdcb40a..da82ab6c2 100644
--- a/newlib/libm/complex/csqrt.c
+++ b/newlib/libm/complex/csqrt.c
@@ -81,14 +81,14 @@  csqrt(double complex z)
 
 	if (y == 0.0) {
 		if (x == 0.0) {
-			w = 0.0 + y * I;
+			w = 0.0 + y * (double complex) I;
 		} else {
 			r = fabs(x);
 			r = sqrt(r);
 			if (x < 0.0) {
-				w = 0.0 + r * I;
+				w = 0.0 + r * (double complex) I;
 			} else {
-				w = r + y * I;
+				w = r + y * (double complex) I;
 			}
 		}
 		return w;
@@ -97,9 +97,9 @@  csqrt(double complex z)
 		r = fabs(y);
 		r = sqrt(0.5 * r);
 		if (y > 0)
-			w = r + r * I;
+			w = r + r * (double complex) I;
 		else
-			w = r - r * I;
+			w = r - r * (double complex) I;
 		return w;
 	}
 	/* Rescale to avoid internal overflow or underflow.  */
@@ -118,7 +118,7 @@  csqrt(double complex z)
 		scale = 0.5;
 #endif
 	}
-	w = x + y * I;
+	w = x + y * (double complex) I;
 	r = cabs(w);
 	if (x > 0) {
 		t = sqrt(0.5 * r + 0.5 * x);
@@ -130,8 +130,8 @@  csqrt(double complex z)
 		r *= scale;
 	}
 	if (y < 0)
-		w = t - r * I;
+		w = t - r * (double complex) I;
 	else
-		w = t + r * I;
+		w = t + r * (double complex) I;
 	return w;
 }
diff --git a/newlib/libm/complex/csqrtl.c b/newlib/libm/complex/csqrtl.c
index c10a1264a..9b3a8d46f 100644
--- a/newlib/libm/complex/csqrtl.c
+++ b/newlib/libm/complex/csqrtl.c
@@ -47,7 +47,7 @@  __RCSID("$NetBSD: csqrtl.c,v 1.2 2014/10/11 00:43:51 christos Exp $");
 /* We risk spurious overflow for components >= LDBL_MAX / (1 + sqrt(2)). */
 #define	THRESH	(LDBL_MAX / 2.414213562373095048801688724209698L)
 
-#define cpackl(r, i) ((r) + (i) * I)
+#define cpackl(r, i) ((r) + (i) * (double complex) I)
 
 long double complex
 csqrtl(long double complex z)
diff --git a/newlib/libm/complex/ctan.c b/newlib/libm/complex/ctan.c
index 0d6074baf..3f91d69ea 100644
--- a/newlib/libm/complex/ctan.c
+++ b/newlib/libm/complex/ctan.c
@@ -82,10 +82,10 @@  ctan(double complex z)
 
 	if (d == 0.0) {
 		/* mtherr ("ctan", OVERFLOW); */
-		w = HUGE_VAL + HUGE_VAL * I;
+		w = HUGE_VAL + HUGE_VAL * (double complex) I;
 		return w;
 	}
 
-	w = sin(2.0 * creal(z)) / d + (sinh(2.0 * cimag(z)) / d) * I;
+	w = sin(2.0 * creal(z)) / d + (sinh(2.0 * cimag(z)) / d) * (double complex) I;
 	return w;
 }
diff --git a/newlib/libm/complex/ctanh.c b/newlib/libm/complex/ctanh.c
index a86e97138..2256c745a 100644
--- a/newlib/libm/complex/ctanh.c
+++ b/newlib/libm/complex/ctanh.c
@@ -77,7 +77,7 @@  ctanh(double complex z)
 	x = creal(z);
 	y = cimag(z);
 	d = cosh(2.0 * x) + cos(2.0 * y);
-	w = sinh(2.0 * x) / d  +  (sin(2.0 * y) / d) * I;
+	w = sinh(2.0 * x) / d  +  (sin(2.0 * y) / d) * (double complex) I;
 
 	return w;
 }
diff --git a/newlib/libm/complex/ctanhl.c b/newlib/libm/complex/ctanhl.c
index 1db886f63..cac206ace 100644
--- a/newlib/libm/complex/ctanhl.c
+++ b/newlib/libm/complex/ctanhl.c
@@ -41,7 +41,7 @@  ctanhl(long double complex z)
 	x = creall(z);
 	y = cimagl(z);
 	d = coshl(2.0L * x) + cosl(2.0L * y);
-	w = sinhl(2.0L * x) / d  +  (sinl(2.0L * y) / d) * I;
+	w = sinhl(2.0L * x) / d  +  (sinl(2.0L * y) / d) * (double complex) I;
 
 	return w;
 }
diff --git a/newlib/libm/complex/ctanl.c b/newlib/libm/complex/ctanl.c
index c5c887c74..ef3f60db9 100644
--- a/newlib/libm/complex/ctanl.c
+++ b/newlib/libm/complex/ctanl.c
@@ -47,10 +47,10 @@  ctanl(long double complex z)
 
 	if (d == 0.0L) {
 		/* mtherr ("ctan", OVERFLOW); */
-		w = HUGE_VALL + HUGE_VALL * I;
+		w = HUGE_VALL + HUGE_VALL * (double complex) I;
 		return w;
 	}
 
-	w = sinl(2.0L * creall(z)) / d + (sinhl(2.0L * cimagl(z)) / d) * I;
+	w = sinl(2.0L * creall(z)) / d + (sinhl(2.0L * cimagl(z)) / d) * (double complex) I;
 	return w;
 }
diff --git a/newlib/libm/math/wf_scalb.c b/newlib/libm/math/wf_scalb.c
index e87dc37dd..c90e2eb71 100644
--- a/newlib/libm/math/wf_scalb.c
+++ b/newlib/libm/math/wf_scalb.c
@@ -46,12 +46,12 @@ 
 	if(!(finitef(z)||isnan(z))&&finitef(x)) {
 	    /* scalbf overflow; */
 	    errno = ERANGE;
-	    return (x > 0.0 ? HUGE_VALF : -HUGE_VALF);
+	    return (x > 0.0f ? HUGE_VALF : -HUGE_VALF);
 	}
 	if(z==0.0f&&z!=x) {
 	    /* scalbf underflow */
 	    errno = ERANGE;
-	    return copysign(0.0,x);
+	    return copysignf(0.0f,x);
 	} 
 #ifndef _SCALB_INT
 	if(!finitef(fn)) errno = ERANGE;