summaryrefslogtreecommitdiff
path: root/patches/mpfr/3.1.2/130-clang-divby0.patch
blob: 8e0cd8e04b7ed5b6b13874e90eb6ce6ff001a5e9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
diff -Naurd mpfr-3.1.2-a/PATCHES mpfr-3.1.2-b/PATCHES
--- mpfr-3.1.2-a/PATCHES	2013-10-09 13:34:21.000000000 +0000
+++ mpfr-3.1.2-b/PATCHES	2013-10-09 13:34:21.000000000 +0000
@@ -0,0 +1 @@
+clang-divby0
diff -Naurd mpfr-3.1.2-a/VERSION mpfr-3.1.2-b/VERSION
--- mpfr-3.1.2-a/VERSION	2013-09-26 10:52:52.000000000 +0000
+++ mpfr-3.1.2-b/VERSION	2013-10-09 13:34:21.000000000 +0000
@@ -1 +1 @@
-3.1.2-p2
+3.1.2-p3
diff -Naurd mpfr-3.1.2-a/src/mpfr-impl.h mpfr-3.1.2-b/src/mpfr-impl.h
--- mpfr-3.1.2-a/src/mpfr-impl.h	2013-03-13 15:37:36.000000000 +0000
+++ mpfr-3.1.2-b/src/mpfr-impl.h	2013-10-09 13:34:21.000000000 +0000
@@ -468,8 +468,16 @@
 #define MPFR_LIMBS_PER_FLT ((IEEE_FLT_MANT_DIG-1)/GMP_NUMB_BITS+1)
 
 /* Visual C++ doesn't support +1.0/0.0, -1.0/0.0 and 0.0/0.0
-   at compile time. */
-#if defined(_MSC_VER) && defined(_WIN32) && (_MSC_VER >= 1200)
+   at compile time.
+   Clang with -fsanitize=undefined is a bit similar due to a bug:
+     http://llvm.org/bugs/show_bug.cgi?id=17381
+   but even without its sanitizer, it may be better to use the
+   double_zero version until IEEE 754 division by zero is properly
+   supported:
+     http://llvm.org/bugs/show_bug.cgi?id=17000
+*/
+#if (defined(_MSC_VER) && defined(_WIN32) && (_MSC_VER >= 1200)) || \
+    defined(__clang__)
 static double double_zero = 0.0;
 # define DBL_NAN (double_zero/double_zero)
 # define DBL_POS_INF ((double) 1.0/double_zero)
@@ -501,6 +509,8 @@
    (with Xcode 2.4.1, i.e. the latest one). */
 #define LVALUE(x) (&(x) == &(x) || &(x) != &(x))
 #define DOUBLE_ISINF(x) (LVALUE(x) && ((x) > DBL_MAX || (x) < -DBL_MAX))
+/* The DOUBLE_ISNAN(x) macro is also valid on long double x
+   (assuming that the compiler isn't too broken). */
 #ifdef MPFR_NANISNAN
 /* Avoid MIPSpro / IRIX64 / gcc -ffast-math (incorrect) optimizations.
    The + must not be replaced by a ||. With gcc -ffast-math, NaN is
diff -Naurd mpfr-3.1.2-a/src/mpfr.h mpfr-3.1.2-b/src/mpfr.h
--- mpfr-3.1.2-a/src/mpfr.h	2013-09-26 10:52:52.000000000 +0000
+++ mpfr-3.1.2-b/src/mpfr.h	2013-10-09 13:34:21.000000000 +0000
@@ -27,7 +27,7 @@
 #define MPFR_VERSION_MAJOR 3
 #define MPFR_VERSION_MINOR 1
 #define MPFR_VERSION_PATCHLEVEL 2
-#define MPFR_VERSION_STRING "3.1.2-p2"
+#define MPFR_VERSION_STRING "3.1.2-p3"
 
 /* Macros dealing with MPFR VERSION */
 #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
diff -Naurd mpfr-3.1.2-a/src/version.c mpfr-3.1.2-b/src/version.c
--- mpfr-3.1.2-a/src/version.c	2013-09-26 10:52:52.000000000 +0000
+++ mpfr-3.1.2-b/src/version.c	2013-10-09 13:34:21.000000000 +0000
@@ -25,5 +25,5 @@
 const char *
 mpfr_get_version (void)
 {
-  return "3.1.2-p2";
+  return "3.1.2-p3";
 }
diff -Naurd mpfr-3.1.2-a/tests/tget_flt.c mpfr-3.1.2-b/tests/tget_flt.c
--- mpfr-3.1.2-a/tests/tget_flt.c	2013-03-13 15:37:44.000000000 +0000
+++ mpfr-3.1.2-b/tests/tget_flt.c	2013-10-09 13:34:21.000000000 +0000
@@ -28,9 +28,17 @@
 main (void)
 {
   mpfr_t x, y;
-  float f, g, infp;
+  float f, g;
   int i;
+#if !defined(MPFR_ERRDIVZERO)
+  float infp;
+#endif
+
+  tests_start_mpfr ();
 
+#if !defined(MPFR_ERRDIVZERO)
+  /* The definition of DBL_POS_INF involves a division by 0. This makes
+     "clang -O2 -fsanitize=undefined -fno-sanitize-recover" fail. */
   infp = (float) DBL_POS_INF;
   if (infp * 0.5 != infp)
     {
@@ -38,8 +46,7 @@
       fprintf (stderr, "(this is probably a compiler bug, please report)\n");
       exit (1);
     }
-
-  tests_start_mpfr ();
+#endif
 
   mpfr_init2 (x, 24);
   mpfr_init2 (y, 24);
@@ -353,6 +360,7 @@
       printf ("expected %.8e, got %.8e\n", g, f);
       exit (1);
     }
+#if !defined(MPFR_ERRDIVZERO)
   f = mpfr_get_flt (x, MPFR_RNDN); /* first round to 2^128 (even rule),
                                       thus we should get +Inf */
   g = infp;
@@ -376,6 +384,7 @@
       printf ("expected %.8e, got %.8e\n", g, f);
       exit (1);
     }
+#endif
 
   mpfr_clear (x);
   mpfr_clear (y);
diff -Naurd mpfr-3.1.2-a/tests/tset_ld.c mpfr-3.1.2-b/tests/tset_ld.c
--- mpfr-3.1.2-a/tests/tset_ld.c	2013-03-13 15:37:44.000000000 +0000
+++ mpfr-3.1.2-b/tests/tset_ld.c	2013-10-09 13:34:21.000000000 +0000
@@ -47,8 +47,11 @@
 static int
 Isnan_ld (long double d)
 {
-  double e = (double) d;
-  if (DOUBLE_ISNAN (e))
+  /* Do not convert d to double as this can give an overflow, which
+     may confuse compilers without IEEE 754 support (such as clang
+     -fsanitize=undefined), or trigger a trap if enabled.
+     The DOUBLE_ISNAN macro should work fine on long double. */
+  if (DOUBLE_ISNAN (d))
     return 1;
   LONGDOUBLE_NAN_ACTION (d, goto yes);
   return 0;