about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2013-04-03 16:51:46 +0000
committerJoseph Myers <joseph@codesourcery.com>2013-04-03 16:51:46 +0000
commit05e166c887612250d461b5fe7c0f0064cd1a0c41 (patch)
tree9cb5d95b1af53bfc90b7bf1bf0a6772336df00d3
parent5b535ac41945fa369a5f641acdeb0d7eadf4668e (diff)
downloadglibc-05e166c887612250d461b5fe7c0f0064cd1a0c41.tar.gz
glibc-05e166c887612250d461b5fe7c0f0064cd1a0c41.tar.xz
glibc-05e166c887612250d461b5fe7c0f0064cd1a0c41.zip
Fix missing underflow from cexp (bug 14478).
-rw-r--r--ChangeLog9
-rw-r--r--NEWS8
-rw-r--r--math/libm-test.inc3
-rw-r--r--math/s_cexp.c12
-rw-r--r--math/s_cexpf.c12
-rw-r--r--math/s_cexpl.c12
6 files changed, 52 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index deebea49f1..8d2602b639 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2013-04-03  Joseph Myers  <joseph@codesourcery.com>
+
+	[BZ #14478]
+	* math/s_cexp.c (__cexp): Ensure underflow exception occurs for
+	underflowed result.
+	* math/s_cexpf.c (__cexpf): Likewise.
+	* math/s_cexpl.c (__cexpl): Likewise.
+	* math/libm-test.inc (cexp_test): Add more tests.
+
 2013-04-03  Andreas Schwab  <schwab@suse.de>
 
 	[BZ #15330]
diff --git a/NEWS b/NEWS
index 513c185b7f..e28b2874b7 100644
--- a/NEWS
+++ b/NEWS
@@ -10,10 +10,10 @@ Version 2.18
 * The following bugs are resolved with this release:
 
   10357, 11120, 11561, 12723, 13550, 13889, 13951, 14142, 14176, 14200,
-  14317, 14327, 14496, 14812, 14920, 14964, 14981, 14982, 14985, 14994,
-  14996, 15003, 15006, 15020, 15023, 15036, 15054, 15055, 15062, 15078,
-  15160, 15214, 15232, 15234, 15283, 15285, 15287, 15304, 15305, 15307,
-  15327, 15330.
+  14317, 14327, 14478, 14496, 14812, 14920, 14964, 14981, 14982, 14985,
+  14994, 14996, 15003, 15006, 15020, 15023, 15036, 15054, 15055, 15062,
+  15078, 15160, 15214, 15232, 15234, 15283, 15285, 15287, 15304, 15305,
+  15307, 15327, 15330.
 
 * CVE-2013-0242 Buffer overrun in regexp matcher has been fixed (Bugzilla
   #15078).
diff --git a/math/libm-test.inc b/math/libm-test.inc
index c9ed719d18..08c80fad42 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -4794,6 +4794,9 @@ cexp_test (void)
   TEST_c_c (cexp, 1e6, min_value, plus_infty, plus_infty, OVERFLOW_EXCEPTION);
   TEST_c_c (cexp, 1e6, -min_value, plus_infty, minus_infty, OVERFLOW_EXCEPTION);
 
+  TEST_c_c (cexp, min_value, min_subnorm_value, 1.0, min_subnorm_value, UNDERFLOW_EXCEPTION);
+  TEST_c_c (cexp, min_value, -min_subnorm_value, 1.0, -min_subnorm_value, UNDERFLOW_EXCEPTION);
+
   END (cexp, complex);
 }
 
diff --git a/math/s_cexp.c b/math/s_cexp.c
index 36157ff61b..655e4e8dee 100644
--- a/math/s_cexp.c
+++ b/math/s_cexp.c
@@ -74,6 +74,18 @@ __cexp (__complex__ double x)
 	      __real__ retval = exp_val * cosix;
 	      __imag__ retval = exp_val * sinix;
 	    }
+	  if (fabs (__real__ retval) < DBL_MIN)
+	    {
+	      volatile double force_underflow
+		= __real__ retval * __real__ retval;
+	      (void) force_underflow;
+	    }
+	  if (fabs (__imag__ retval) < DBL_MIN)
+	    {
+	      volatile double force_underflow
+		= __imag__ retval * __imag__ retval;
+	      (void) force_underflow;
+	    }
 	}
       else
 	{
diff --git a/math/s_cexpf.c b/math/s_cexpf.c
index 364be8ac31..fa942d34f7 100644
--- a/math/s_cexpf.c
+++ b/math/s_cexpf.c
@@ -74,6 +74,18 @@ __cexpf (__complex__ float x)
 	      __real__ retval = exp_val * cosix;
 	      __imag__ retval = exp_val * sinix;
 	    }
+	  if (fabsf (__real__ retval) < FLT_MIN)
+	    {
+	      volatile float force_underflow
+		= __real__ retval * __real__ retval;
+	      (void) force_underflow;
+	    }
+	  if (fabsf (__imag__ retval) < FLT_MIN)
+	    {
+	      volatile float force_underflow
+		= __imag__ retval * __imag__ retval;
+	      (void) force_underflow;
+	    }
 	}
       else
 	{
diff --git a/math/s_cexpl.c b/math/s_cexpl.c
index 1bfce78aeb..d827bc3de4 100644
--- a/math/s_cexpl.c
+++ b/math/s_cexpl.c
@@ -74,6 +74,18 @@ __cexpl (__complex__ long double x)
 	      __real__ retval = exp_val * cosix;
 	      __imag__ retval = exp_val * sinix;
 	    }
+	  if (fabsl (__real__ retval) < LDBL_MIN)
+	    {
+	      volatile long double force_underflow
+		= __real__ retval * __real__ retval;
+	      (void) force_underflow;
+	    }
+	  if (fabsl (__imag__ retval) < LDBL_MIN)
+	    {
+	      volatile long double force_underflow
+		= __imag__ retval * __imag__ retval;
+	      (void) force_underflow;
+	    }
 	}
       else
 	{