Skip to content

Commit 5f00a02

Browse files
committed
gh-70450: Fix MSVC /fp:strict builds
Replace floating-point expressions that MSVC rejects in static initializers under strict semantics. Initialize cmath NaN table entries once because NAN is not a constant expression in MSVC C mode.
1 parent 8b048eb commit 5f00a02

4 files changed

Lines changed: 48 additions & 7 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix the Windows build when using the MSVC ``/fp:strict`` option.

Modules/cmathmodule.c

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "Python.h"
1010
#include "pycore_complexobject.h" // _Py_c_neg()
11+
#include "pycore_lock.h" // _PyOnceFlag_CallOnce()
1112
#include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR
1213
/* we need DBL_MAX, DBL_MIN, DBL_EPSILON, DBL_MANT_DIG and FLT_RADIX from
1314
float.h. We assume that FLT_RADIX is either 2 or 16. */
@@ -147,11 +148,11 @@ special_type(double d)
147148
}
148149

149150
#define P Py_MATH_PI
150-
#define P14 0.25*Py_MATH_PI
151-
#define P12 0.5*Py_MATH_PI
152-
#define P34 0.75*Py_MATH_PI
151+
#define P14 0.78539816339744830962
152+
#define P12 1.57079632679489661923
153+
#define P34 2.35619449019234492885
153154
#define INF INFINITY
154-
#define N Py_NAN
155+
#define N 9.5426319407711027e33 /* finite placeholder for NaN */
155156
#define U -9.5426319407711027e33 /* unlikely value, used as placeholder */
156157

157158
/* First, the C functions that do the real work. Each of the c_*
@@ -1230,6 +1231,41 @@ PyDoc_STRVAR(module_doc,
12301231
"This module provides access to mathematical functions for complex\n"
12311232
"numbers.");
12321233

1234+
static _PyOnceFlag special_values_init_once = {0};
1235+
1236+
static int
1237+
init_special_values(void *Py_UNUSED(arg))
1238+
{
1239+
Py_complex *tables[] = {
1240+
acos_special_values[0],
1241+
acosh_special_values[0],
1242+
asinh_special_values[0],
1243+
atanh_special_values[0],
1244+
cosh_special_values[0],
1245+
exp_special_values[0],
1246+
log_special_values[0],
1247+
sinh_special_values[0],
1248+
sqrt_special_values[0],
1249+
tanh_special_values[0],
1250+
rect_special_values[0],
1251+
};
1252+
1253+
/* MSVC with /fp:strict does not treat NAN as a constant expression.
1254+
Replace its finite placeholders once all static initialization is
1255+
complete. */
1256+
for (size_t i = 0; i < Py_ARRAY_LENGTH(tables); i++) {
1257+
for (size_t j = 0; j < 7 * 7; j++) {
1258+
if (tables[i][j].real == N) {
1259+
tables[i][j].real = Py_NAN;
1260+
}
1261+
if (tables[i][j].imag == N) {
1262+
tables[i][j].imag = Py_NAN;
1263+
}
1264+
}
1265+
}
1266+
return 0;
1267+
}
1268+
12331269
static PyMethodDef cmath_methods[] = {
12341270
CMATH_ACOS_METHODDEF
12351271
CMATH_ACOSH_METHODDEF
@@ -1260,6 +1296,10 @@ static PyMethodDef cmath_methods[] = {
12601296
static int
12611297
cmath_exec(PyObject *mod)
12621298
{
1299+
/* init cannot fail */
1300+
(void)_PyOnceFlag_CallOnce(
1301+
&special_values_init_once, init_special_values, NULL);
1302+
12631303
if (PyModule_Add(mod, "pi", PyFloat_FromDouble(Py_MATH_PI)) < 0) {
12641304
return -1;
12651305
}

Modules/mathmodule.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2610,8 +2610,8 @@ math_pow_impl(PyObject *module, double x, double y)
26102610
}
26112611

26122612

2613-
static const double degToRad = Py_MATH_PI / 180.0;
2614-
static const double radToDeg = 180.0 / Py_MATH_PI;
2613+
static const double degToRad = 0.017453292519943295769236907684886;
2614+
static const double radToDeg = 57.295779513082320876798154814105;
26152615

26162616
/*[clinic input]
26172617
math.degrees

Python/dtoa.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1108,7 +1108,7 @@ tens[] = {
11081108
static const double
11091109
bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
11101110
static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
1111-
9007199254740992.*9007199254740992.e-256
1111+
8.112963841460668e-225
11121112
/* = 2^106 * 1e-256 */
11131113
};
11141114
/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */

0 commit comments

Comments
 (0)