diff -Naurd mpfr-4.1.0-a/PATCHES mpfr-4.1.0-b/PATCHES --- mpfr-4.1.0-a/PATCHES 2021-03-09 13:55:43.183158946 +0000 +++ mpfr-4.1.0-b/PATCHES 2021-03-09 13:55:43.223158508 +0000 @@ -0,0 +1 @@ +macros diff -Naurd mpfr-4.1.0-a/VERSION mpfr-4.1.0-b/VERSION --- mpfr-4.1.0-a/VERSION 2021-02-17 17:25:46.440981068 +0000 +++ mpfr-4.1.0-b/VERSION 2021-03-09 13:55:43.223158508 +0000 @@ -1 +1 @@ -4.1.0-p9 +4.1.0-p10 diff -Naurd mpfr-4.1.0-a/doc/mpfr.info mpfr-4.1.0-b/doc/mpfr.info --- mpfr-4.1.0-a/doc/mpfr.info 2020-07-10 11:59:13.000000000 +0000 +++ mpfr-4.1.0-b/doc/mpfr.info 2021-03-09 13:55:51.167071327 +0000 @@ -3217,7 +3217,11 @@ Each function in this interface is also implemented as a macro for efficiency reasons: for example ‘mpfr_custom_init (s, p)’ uses the -macro, while ‘(mpfr_custom_init) (s, p)’ uses the function. +macro, while ‘(mpfr_custom_init) (s, p)’ uses the function. Note that +the macro may evaluate arguments multiple times (or none). Moreover, +macros implementing functions with the ‘void’ return type may not be +used in contexts where an expression is expected, e.g., inside +‘for(...)’ or before a comma operator. Note 1: MPFR functions may still initialize temporary floating-point numbers using ‘mpfr_init’ and similar functions. See Custom Allocation @@ -4579,13 +4583,13 @@ (line 115) * mpfr_csch: Transcendental Functions. (line 180) -* mpfr_custom_get_exp: Custom Interface. (line 76) -* mpfr_custom_get_kind: Custom Interface. (line 66) -* mpfr_custom_get_significand: Custom Interface. (line 71) -* mpfr_custom_get_size: Custom Interface. (line 37) -* mpfr_custom_init: Custom Interface. (line 41) -* mpfr_custom_init_set: Custom Interface. (line 48) -* mpfr_custom_move: Custom Interface. (line 85) +* mpfr_custom_get_exp: Custom Interface. (line 80) +* mpfr_custom_get_kind: Custom Interface. (line 70) +* mpfr_custom_get_significand: Custom Interface. (line 75) +* mpfr_custom_get_size: Custom Interface. (line 41) +* mpfr_custom_init: Custom Interface. (line 45) +* mpfr_custom_init_set: Custom Interface. (line 52) +* mpfr_custom_move: Custom Interface. (line 89) * MPFR_DECL_INIT: Initialization Functions. (line 77) * mpfr_digamma: Transcendental Functions. @@ -5165,19 +5169,19 @@ Node: Memory Handling Functions155904 Node: Compatibility with MPF157792 Node: Custom Interface160961 -Node: Internals165592 -Node: API Compatibility167136 -Node: Type and Macro Changes169084 -Node: Added Functions172267 -Node: Changed Functions177074 -Node: Removed Functions184433 -Node: Other Changes185163 -Node: MPFR and the IEEE 754 Standard186864 -Node: Contributors189481 -Node: References192620 -Node: GNU Free Documentation License194501 -Node: Concept Index217095 -Node: Function and Type Index223168 +Node: Internals165852 +Node: API Compatibility167396 +Node: Type and Macro Changes169344 +Node: Added Functions172527 +Node: Changed Functions177334 +Node: Removed Functions184693 +Node: Other Changes185423 +Node: MPFR and the IEEE 754 Standard187124 +Node: Contributors189741 +Node: References192880 +Node: GNU Free Documentation License194761 +Node: Concept Index217355 +Node: Function and Type Index223428  End Tag Table diff -Naurd mpfr-4.1.0-a/doc/mpfr.texi mpfr-4.1.0-b/doc/mpfr.texi --- mpfr-4.1.0-a/doc/mpfr.texi 2020-07-10 11:52:33.000000000 +0000 +++ mpfr-4.1.0-b/doc/mpfr.texi 2021-03-09 13:55:43.211158639 +0000 @@ -3817,6 +3817,12 @@ Each function in this interface is also implemented as a macro for efficiency reasons: for example @code{mpfr_custom_init (s, p)} uses the macro, while @code{(mpfr_custom_init) (s, p)} uses the function. +Note that the macro may evaluate arguments multiple times (or none). +Moreover, macros implementing functions with the @code{void} return type +may not be used in contexts where an expression is expected, e.g., inside +@code{for(...)} or before a comma operator. +@c These limitations with macros cannot be avoided in a C90 compatible way. +@c In the future, inline functions could be used. Note 1: MPFR functions may still initialize temporary floating-point numbers using @code{mpfr_init} and similar functions. See Custom Allocation (GNU MP)@. diff -Naurd mpfr-4.1.0-a/src/mpfr.h mpfr-4.1.0-b/src/mpfr.h --- mpfr-4.1.0-a/src/mpfr.h 2021-02-17 17:25:46.436981105 +0000 +++ mpfr-4.1.0-b/src/mpfr.h 2021-03-09 13:55:43.223158508 +0000 @@ -27,7 +27,7 @@ #define MPFR_VERSION_MAJOR 4 #define MPFR_VERSION_MINOR 1 #define MPFR_VERSION_PATCHLEVEL 0 -#define MPFR_VERSION_STRING "4.1.0-p9" +#define MPFR_VERSION_STRING "4.1.0-p10" /* User macros: MPFR_USE_FILE: Define it to make MPFR define functions dealing @@ -833,23 +833,39 @@ even if it produces faster and smaller code. */ #ifndef MPFR_USE_NO_MACRO -/* Inlining these functions is both faster and smaller */ -#define mpfr_nan_p(_x) ((_x)->_mpfr_exp == __MPFR_EXP_NAN) -#define mpfr_inf_p(_x) ((_x)->_mpfr_exp == __MPFR_EXP_INF) -#define mpfr_zero_p(_x) ((_x)->_mpfr_exp == __MPFR_EXP_ZERO) -#define mpfr_regular_p(_x) ((_x)->_mpfr_exp > __MPFR_EXP_INF) +/* In the implementation of these macros, we need to make sure that the + arguments are evaluated one time exactly and that type conversion is + done as it would be with a function. Tests should be added to ensure + that. + Note that the macros for the custom interface are not concerned; the + MPFR manual has been clarified. */ + +/* Prevent x from being used as an lvalue. + Thanks to Wojtek Lerch and Tim Rentsch for the idea. */ +#define MPFR_VALUE_OF(x) (0 ? (x) : (x)) + +/* The following macro converts the argument to mpfr_srcptr, as in type + conversion for function parameters. But it will detect disallowed + implicit conversions, e.g. when the argument has an integer type. */ +#define MPFR_SRCPTR(x) ((mpfr_srcptr) (0 ? (x) : (mpfr_srcptr) (x))) +#define MPFR_GET_SIGN(_x) MPFR_VALUE_OF(MPFR_SIGN(MPFR_SRCPTR(_x))) + +#define mpfr_nan_p(_x) (MPFR_SRCPTR(_x)->_mpfr_exp == __MPFR_EXP_NAN) +#define mpfr_inf_p(_x) (MPFR_SRCPTR(_x)->_mpfr_exp == __MPFR_EXP_INF) +#define mpfr_zero_p(_x) (MPFR_SRCPTR(_x)->_mpfr_exp == __MPFR_EXP_ZERO) +#define mpfr_regular_p(_x) (MPFR_SRCPTR(_x)->_mpfr_exp > __MPFR_EXP_INF) + +/* mpfr_sgn is documented as a macro, thus the following code is fine. + But it would be safer to regard it as a function in some future + MPFR version. */ #define mpfr_sgn(_x) \ ((_x)->_mpfr_exp < __MPFR_EXP_INF ? \ (mpfr_nan_p (_x) ? mpfr_set_erangeflag () : (mpfr_void) 0), 0 : \ MPFR_SIGN (_x)) -/* Prevent them from using as lvalues */ -#define MPFR_VALUE_OF(x) (0 ? (x) : (x)) -#define mpfr_get_prec(_x) MPFR_VALUE_OF((_x)->_mpfr_prec) -#define mpfr_get_exp(_x) MPFR_VALUE_OF((_x)->_mpfr_exp) -/* Note 1: If need be, the MPFR_VALUE_OF can be used for other expressions - (of any type). Thanks to Wojtek Lerch and Tim Rentsch for the idea. - Note 2: Defining mpfr_get_exp() as a macro has the effect to disable +#define mpfr_get_prec(_x) MPFR_VALUE_OF(MPFR_SRCPTR(_x)->_mpfr_prec) +#define mpfr_get_exp(_x) MPFR_VALUE_OF(MPFR_SRCPTR(_x)->_mpfr_exp) +/* Note: Defining mpfr_get_exp() as a macro has the effect to disable the check that the argument is a pure FP number (done in the function); this increases the risk of undetected error and makes debugging more complex. Is it really worth in practice? (Potential FIXME) */ @@ -861,11 +877,17 @@ #define mpfr_cmp_ui(b,i) mpfr_cmp_ui_2exp((b),(i),0) #define mpfr_cmp_si(b,i) mpfr_cmp_si_2exp((b),(i),0) -#define mpfr_set(a,b,r) mpfr_set4(a,b,r,MPFR_SIGN(b)) +#if __GNUC__ > 2 || __GNUC_MINOR__ >= 95 +#define mpfr_set(a,b,r) \ + __extension__ ({ \ + mpfr_srcptr _p = (b); \ + mpfr_set4(a,_p,r,MPFR_SIGN(_p)); \ + }) +#endif #define mpfr_abs(a,b,r) mpfr_set4(a,b,r,1) -#define mpfr_copysign(a,b,c,r) mpfr_set4(a,b,r,MPFR_SIGN(c)) +#define mpfr_copysign(a,b,c,r) mpfr_set4(a,b,r,MPFR_GET_SIGN(c)) #define mpfr_setsign(a,b,s,r) mpfr_set4(a,b,r,(s) ? -1 : 1) -#define mpfr_signbit(x) (MPFR_SIGN(x) < 0) +#define mpfr_signbit(x) (MPFR_GET_SIGN(x) < 0) #define mpfr_cmp(b, c) mpfr_cmp3(b, c, 1) #define mpfr_mul_2exp(y,x,n,r) mpfr_mul_2ui((y),(x),(n),(r)) #define mpfr_div_2exp(y,x,n,r) mpfr_div_2ui((y),(x),(n),(r)) diff -Naurd mpfr-4.1.0-a/src/ubf.c mpfr-4.1.0-b/src/ubf.c --- mpfr-4.1.0-a/src/ubf.c 2020-02-12 01:38:57.000000000 +0000 +++ mpfr-4.1.0-b/src/ubf.c 2021-03-09 13:55:43.211158639 +0000 @@ -78,7 +78,7 @@ mpfr_get_prec (b), mpfr_log_prec, b, mpfr_get_prec (c), mpfr_log_prec, c), ("a[%Pu]=%.*Rg", - mpfr_get_prec (a), mpfr_log_prec, a)); + mpfr_get_prec ((mpfr_ptr) a), mpfr_log_prec, a)); MPFR_ASSERTD ((mpfr_ptr) a != b); MPFR_ASSERTD ((mpfr_ptr) a != c); diff -Naurd mpfr-4.1.0-a/src/version.c mpfr-4.1.0-b/src/version.c --- mpfr-4.1.0-a/src/version.c 2021-02-17 17:25:46.440981068 +0000 +++ mpfr-4.1.0-b/src/version.c 2021-03-09 13:55:43.223158508 +0000 @@ -25,5 +25,5 @@ const char * mpfr_get_version (void) { - return "4.1.0-p9"; + return "4.1.0-p10"; } diff -Naurd mpfr-4.1.0-a/tests/mpfr-test.h mpfr-4.1.0-b/tests/mpfr-test.h --- mpfr-4.1.0-a/tests/mpfr-test.h 2021-02-17 17:25:46.424981219 +0000 +++ mpfr-4.1.0-b/tests/mpfr-test.h 2021-03-09 13:55:43.211158639 +0000 @@ -92,6 +92,32 @@ #define STRINGIZE(S) #S #define MAKE_STR(S) STRINGIZE(S) +/* In C (but not C++), mpfr_ptr and mpfr_srcptr arguments can be provided + in a different pointer type, such as void *. For functions implemented + as macros, the type conversion for the function parameters will not be + done by the compiler, which means potential bugs in these implementations + if we forget to take these unusual cases into account. So we need to test + such arguments, in order to make sure that the arguments are converted to + the expected type when needed. + + However, at least when the function is not implemented as a macro (which + is the case when MPFR_USE_NO_MACRO is defined), such tests with void * + arguments are not valid in C++; therefore, we will not do the cast to + void * if the __cplusplus macro is defined. And with GCC compilers (and + compatible), we will ignore the -Wc++-compat option around these tests. + + Note: in the future, inline functions could be used instead of macros, + and such tests would become useless (except to detect compiler bugs). +*/ +#if defined (__cplusplus) +#define VOIDP_CAST(X) (X) +#else +#define VOIDP_CAST(X) ((void *) (X)) +#if defined (__GNUC__) +#define IGNORE_CPP_COMPAT +#endif +#endif + #if defined (__cplusplus) extern "C" { #endif diff -Naurd mpfr-4.1.0-a/tests/tcopysign.c mpfr-4.1.0-b/tests/tcopysign.c --- mpfr-4.1.0-a/tests/tcopysign.c 2020-01-08 18:11:13.000000000 +0000 +++ mpfr-4.1.0-b/tests/tcopysign.c 2021-03-09 13:55:43.211158639 +0000 @@ -26,26 +26,72 @@ copysign_variant (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode, int k) { + mpfr_srcptr p; + int a = 0, b = 0, c = 0; + + /* invalid sign, to test that the sign is always correctly set */ + MPFR_SIGN (z) = 0; + + if (k >= 8) + { + MPFR_ASSERTN (MPFR_PREC (z) >= MPFR_PREC (x)); + mpfr_set (z, x, MPFR_RNDN); + p = z; + k -= 8; + } + else + p = x; + mpfr_clear_flags (); switch (k) { case 0: - mpfr_copysign (z, x, y, MPFR_RNDN); + mpfr_copysign (z, p, y, rnd_mode); return; case 1: - (mpfr_copysign) (z, x, y, MPFR_RNDN); + (mpfr_copysign) (z, p, y, rnd_mode); return; case 2: - mpfr_setsign (z, x, mpfr_signbit (y), MPFR_RNDN); +#ifdef IGNORE_CPP_COMPAT +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++-compat" +#endif + mpfr_copysign ((a++, VOIDP_CAST(z)), + (b++, VOIDP_CAST(p)), + (c++, VOIDP_CAST(y)), rnd_mode); +#ifdef IGNORE_CPP_COMPAT +#pragma GCC diagnostic pop +#endif + MPFR_ASSERTN (a == 1); + MPFR_ASSERTN (b == 1); + MPFR_ASSERTN (c == 1); return; case 3: - mpfr_setsign (z, x, (mpfr_signbit) (y), MPFR_RNDN); + mpfr_setsign (z, p, mpfr_signbit (y), rnd_mode); return; case 4: - (mpfr_setsign) (z, x, mpfr_signbit (y), MPFR_RNDN); + mpfr_setsign (z, p, (mpfr_signbit) (y), rnd_mode); return; case 5: - (mpfr_setsign) (z, x, (mpfr_signbit) (y), MPFR_RNDN); + (mpfr_setsign) (z, p, mpfr_signbit (y), rnd_mode); + return; + case 6: + (mpfr_setsign) (z, p, (mpfr_signbit) (y), rnd_mode); + return; + case 7: +#ifdef IGNORE_CPP_COMPAT +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++-compat" +#endif + mpfr_setsign ((a++, VOIDP_CAST(z)), + (b++, VOIDP_CAST(p)), + mpfr_signbit ((c++, VOIDP_CAST(y))), rnd_mode); +#ifdef IGNORE_CPP_COMPAT +#pragma GCC diagnostic pop +#endif + MPFR_ASSERTN (a == 1); + MPFR_ASSERTN (b == 1); + MPFR_ASSERTN (c == 1); return; } } @@ -64,7 +110,7 @@ for (i = 0; i <= 1; i++) for (j = 0; j <= 1; j++) - for (k = 0; k <= 5; k++) + for (k = 0; k < 16; k++) { mpfr_set_nan (x); i ? MPFR_SET_NEG (x) : MPFR_SET_POS (x); diff -Naurd mpfr-4.1.0-a/tests/texceptions.c mpfr-4.1.0-b/tests/texceptions.c --- mpfr-4.1.0-a/tests/texceptions.c 2020-01-08 18:11:13.000000000 +0000 +++ mpfr-4.1.0-b/tests/texceptions.c 2021-03-09 13:55:43.211158639 +0000 @@ -103,10 +103,26 @@ check_get_prec (void) { mpfr_t x; + int i = 0; mpfr_init2 (x, 17); - if (mpfr_get_prec (x) != 17 || (mpfr_get_prec)(x) != 17) + + if (mpfr_get_prec (x) != 17 || (mpfr_get_prec) (x) != 17) PRINT_ERROR ("mpfr_get_prec"); + +#ifdef IGNORE_CPP_COMPAT +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++-compat" +#endif + + if (mpfr_get_prec ((i++, VOIDP_CAST(x))) != 17) + PRINT_ERROR ("mpfr_get_prec (2)"); + +#ifdef IGNORE_CPP_COMPAT +#pragma GCC diagnostic pop +#endif + + MPFR_ASSERTN (i == 1); mpfr_clear (x); } diff -Naurd mpfr-4.1.0-a/tests/tisnan.c mpfr-4.1.0-b/tests/tisnan.c --- mpfr-4.1.0-a/tests/tisnan.c 2020-01-08 18:11:13.000000000 +0000 +++ mpfr-4.1.0-b/tests/tisnan.c 2021-03-09 13:55:43.211158639 +0000 @@ -27,180 +27,235 @@ main (void) { mpfr_t x; + int i = 0, j = 0; + + /* We need to check that when the function is implemented by a macro, + it behaves correctly. */ +#define ARG (i++, VOIDP_CAST(x)) +#define CHECK MPFR_ASSERTN (i == ++j) tests_start_mpfr (); mpfr_init (x); +#if 0 + /* The following should yield a compilation error when the functions + are implemented as macros. Change 0 to 1 above in order to test. */ + (void) (mpfr_nan_p (1L)); + (void) (mpfr_inf_p (1L)); + (void) (mpfr_number_p (1L)); + (void) (mpfr_zero_p (1L)); + (void) (mpfr_regular_p (1L)); +#endif + +#ifdef IGNORE_CPP_COMPAT +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++-compat" +#endif + /* check +infinity gives non-zero for mpfr_inf_p only */ mpfr_set_ui (x, 1L, MPFR_RNDZ); mpfr_div_ui (x, x, 0L, MPFR_RNDZ); - if (mpfr_nan_p (x) || (mpfr_nan_p) (x) ) + if (mpfr_nan_p (x) || (mpfr_nan_p) (x) || mpfr_nan_p (ARG)) { printf ("Error: mpfr_nan_p(+Inf) gives non-zero\n"); exit (1); } - if (mpfr_inf_p (x) == 0) + CHECK; + if (!mpfr_inf_p (x) || !(mpfr_inf_p) (x) || !mpfr_inf_p (ARG)) { printf ("Error: mpfr_inf_p(+Inf) gives zero\n"); exit (1); } - if (mpfr_number_p (x) || (mpfr_number_p) (x) ) + CHECK; + if (mpfr_number_p (x) || (mpfr_number_p) (x) || mpfr_number_p (ARG)) { printf ("Error: mpfr_number_p(+Inf) gives non-zero\n"); exit (1); } - if (mpfr_zero_p (x) || (mpfr_zero_p) (x) ) + CHECK; + if (mpfr_zero_p (x) || (mpfr_zero_p) (x) || mpfr_zero_p (ARG)) { printf ("Error: mpfr_zero_p(+Inf) gives non-zero\n"); exit (1); } - if (mpfr_regular_p (x) || (mpfr_regular_p) (x) ) + CHECK; + if (mpfr_regular_p (x) || (mpfr_regular_p) (x) || mpfr_regular_p (ARG)) { printf ("Error: mpfr_regular_p(+Inf) gives non-zero\n"); exit (1); } + CHECK; /* same for -Inf */ mpfr_neg (x, x, MPFR_RNDN); - if (mpfr_nan_p (x) || (mpfr_nan_p(x))) + if (mpfr_nan_p (x) || (mpfr_nan_p) (x) || mpfr_nan_p (ARG)) { printf ("Error: mpfr_nan_p(-Inf) gives non-zero\n"); exit (1); } - if (mpfr_inf_p (x) == 0) + CHECK; + if (!mpfr_inf_p (x) || !(mpfr_inf_p) (x) || !mpfr_inf_p (ARG)) { printf ("Error: mpfr_inf_p(-Inf) gives zero\n"); exit (1); } - if (mpfr_number_p (x) || (mpfr_number_p)(x) ) + CHECK; + if (mpfr_number_p (x) || (mpfr_number_p) (x) || mpfr_number_p (ARG)) { printf ("Error: mpfr_number_p(-Inf) gives non-zero\n"); exit (1); } - if (mpfr_zero_p (x) || (mpfr_zero_p)(x) ) + CHECK; + if (mpfr_zero_p (x) || (mpfr_zero_p) (x) || mpfr_zero_p (ARG)) { printf ("Error: mpfr_zero_p(-Inf) gives non-zero\n"); exit (1); } - if (mpfr_regular_p (x) || (mpfr_regular_p) (x) ) + CHECK; + if (mpfr_regular_p (x) || (mpfr_regular_p) (x) || mpfr_regular_p (ARG)) { printf ("Error: mpfr_regular_p(-Inf) gives non-zero\n"); exit (1); } + CHECK; /* same for NaN */ mpfr_sub (x, x, x, MPFR_RNDN); - if (mpfr_nan_p (x) == 0) + if (!mpfr_nan_p (x) || !(mpfr_nan_p) (x) || !mpfr_nan_p (ARG)) { printf ("Error: mpfr_nan_p(NaN) gives zero\n"); exit (1); } - if (mpfr_inf_p (x) || (mpfr_inf_p)(x) ) + CHECK; + if (mpfr_inf_p (x) || (mpfr_inf_p) (x) || mpfr_inf_p (ARG)) { printf ("Error: mpfr_inf_p(NaN) gives non-zero\n"); exit (1); } - if (mpfr_number_p (x) || (mpfr_number_p) (x) ) + CHECK; + if (mpfr_number_p (x) || (mpfr_number_p) (x) || mpfr_number_p (ARG)) { printf ("Error: mpfr_number_p(NaN) gives non-zero\n"); exit (1); } - if (mpfr_zero_p (x) || (mpfr_zero_p)(x) ) + CHECK; + if (mpfr_zero_p (x) || (mpfr_zero_p) (x) || mpfr_zero_p (ARG)) { printf ("Error: mpfr_number_p(NaN) gives non-zero\n"); exit (1); } - if (mpfr_regular_p (x) || (mpfr_regular_p) (x) ) + CHECK; + if (mpfr_regular_p (x) || (mpfr_regular_p) (x) || mpfr_regular_p (ARG)) { printf ("Error: mpfr_regular_p(NaN) gives non-zero\n"); exit (1); } + CHECK; /* same for a regular number */ mpfr_set_ui (x, 1, MPFR_RNDN); - if (mpfr_nan_p (x) || (mpfr_nan_p)(x)) + if (mpfr_nan_p (x) || (mpfr_nan_p) (x) || mpfr_nan_p (ARG)) { printf ("Error: mpfr_nan_p(1) gives non-zero\n"); exit (1); } - if (mpfr_inf_p (x) || (mpfr_inf_p)(x) ) + CHECK; + if (mpfr_inf_p (x) || (mpfr_inf_p) (x) || mpfr_inf_p (ARG)) { printf ("Error: mpfr_inf_p(1) gives non-zero\n"); exit (1); } - if (mpfr_number_p (x) == 0) + CHECK; + if (!mpfr_number_p (x) || !(mpfr_number_p) (x) || !mpfr_number_p (ARG)) { printf ("Error: mpfr_number_p(1) gives zero\n"); exit (1); } - if (mpfr_zero_p (x) || (mpfr_zero_p) (x) ) + CHECK; + if (mpfr_zero_p (x) || (mpfr_zero_p) (x) || mpfr_zero_p (ARG)) { printf ("Error: mpfr_zero_p(1) gives non-zero\n"); exit (1); } - if (mpfr_regular_p (x) == 0 || (mpfr_regular_p) (x) == 0) + CHECK; + if (!mpfr_regular_p (x) || !(mpfr_regular_p) (x) || !mpfr_regular_p (ARG)) { printf ("Error: mpfr_regular_p(1) gives zero\n"); exit (1); } + CHECK; /* Same for +0 */ mpfr_set_ui (x, 0, MPFR_RNDN); - if (mpfr_nan_p (x) || (mpfr_nan_p)(x)) + if (mpfr_nan_p (x) || (mpfr_nan_p) (x) || mpfr_nan_p (ARG)) { printf ("Error: mpfr_nan_p(+0) gives non-zero\n"); exit (1); } - if (mpfr_inf_p (x) || (mpfr_inf_p)(x) ) + CHECK; + if (mpfr_inf_p (x) || (mpfr_inf_p) (x) || mpfr_inf_p (ARG)) { printf ("Error: mpfr_inf_p(+0) gives non-zero\n"); exit (1); } - if (mpfr_number_p (x) == 0) + CHECK; + if (!mpfr_number_p (x) || !(mpfr_number_p) (x) || !mpfr_number_p (ARG)) { printf ("Error: mpfr_number_p(+0) gives zero\n"); exit (1); } - if (mpfr_zero_p (x) == 0 ) + CHECK; + if (!mpfr_zero_p (x) || !(mpfr_zero_p) (x) || !mpfr_zero_p (ARG)) { printf ("Error: mpfr_zero_p(+0) gives zero\n"); exit (1); } - if (mpfr_regular_p (x) || (mpfr_regular_p) (x) ) + CHECK; + if (mpfr_regular_p (x) || (mpfr_regular_p) (x) || mpfr_regular_p (ARG)) { printf ("Error: mpfr_regular_p(+0) gives non-zero\n"); exit (1); } + CHECK; /* Same for -0 */ mpfr_set_ui (x, 0, MPFR_RNDN); mpfr_neg (x, x, MPFR_RNDN); - if (mpfr_nan_p (x) || (mpfr_nan_p)(x)) + if (mpfr_nan_p (x) || (mpfr_nan_p) (x) || mpfr_nan_p (ARG)) { printf ("Error: mpfr_nan_p(-0) gives non-zero\n"); exit (1); } - if (mpfr_inf_p (x) || (mpfr_inf_p)(x) ) + CHECK; + if (mpfr_inf_p (x) || (mpfr_inf_p) (x) || mpfr_inf_p (ARG)) { printf ("Error: mpfr_inf_p(-0) gives non-zero\n"); exit (1); } - if (mpfr_number_p (x) == 0) + CHECK; + if (!mpfr_number_p (x) || !(mpfr_number_p) (x) || !mpfr_number_p (ARG)) { printf ("Error: mpfr_number_p(-0) gives zero\n"); exit (1); } - if (mpfr_zero_p (x) == 0 ) + CHECK; + if (!mpfr_zero_p (x) || !(mpfr_zero_p) (x) || !mpfr_zero_p (ARG)) { printf ("Error: mpfr_zero_p(-0) gives zero\n"); exit (1); } - if (mpfr_regular_p (x) || (mpfr_regular_p) (x) ) + CHECK; + if (mpfr_regular_p (x) || (mpfr_regular_p) (x) || mpfr_regular_p (ARG)) { printf ("Error: mpfr_regular_p(-0) gives non-zero\n"); exit (1); } + CHECK; + +#ifdef IGNORE_CPP_COMPAT +#pragma GCC diagnostic pop +#endif mpfr_clear (x); diff -Naurd mpfr-4.1.0-a/tests/tset.c mpfr-4.1.0-b/tests/tset.c --- mpfr-4.1.0-a/tests/tset.c 2020-01-08 18:11:13.000000000 +0000 +++ mpfr-4.1.0-b/tests/tset.c 2021-03-09 13:55:43.207158683 +0000 @@ -207,7 +207,7 @@ static void check_ternary_value (void) { - int p, q, rnd; + int k, p, q, rnd; int inexact, cmp; mpfr_t x, y; @@ -226,28 +226,45 @@ { if (rnd == MPFR_RNDF) /* the test below makes no sense */ continue; - inexact = mpfr_set (y, x, (mpfr_rnd_t) rnd); - cmp = mpfr_cmp (y, x); - if (((inexact == 0) && (cmp != 0)) || - ((inexact > 0) && (cmp <= 0)) || - ((inexact < 0) && (cmp >= 0))) - { - printf ("Wrong ternary value in mpfr_set for %s: expected" - " %d, got %d\n", - mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), cmp, - inexact); - exit (1); - } - /* Test mpfr_set function too */ - inexact = (mpfr_set) (y, x, (mpfr_rnd_t) rnd); - cmp = mpfr_cmp (y, x); - if (((inexact == 0) && (cmp != 0)) || - ((inexact > 0) && (cmp <= 0)) || - ((inexact < 0) && (cmp >= 0))) + for (k = 0; k < 3; k++) { - printf ("Wrong ternary value in mpfr_set(2): expected %d," - " got %d\n", cmp, inexact); - exit (1); + int a = 0, b = 0, c = 0; + + switch (k) + { + case 0: + inexact = mpfr_set (y, x, (mpfr_rnd_t) rnd); + break; + case 1: + inexact = (mpfr_set) (y, x, (mpfr_rnd_t) rnd); + break; + case 2: +#ifdef IGNORE_CPP_COMPAT +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++-compat" +#endif + inexact = mpfr_set ((a++, VOIDP_CAST(y)), + (b++, VOIDP_CAST(x)), + (c++, (mpfr_rnd_t) rnd)); +#ifdef IGNORE_CPP_COMPAT +#pragma GCC diagnostic pop +#endif + MPFR_ASSERTN (a == 1); + MPFR_ASSERTN (b == 1); + MPFR_ASSERTN (c == 1); + break; + } + cmp = mpfr_cmp (y, x); + if (((inexact == 0) && (cmp != 0)) || + ((inexact > 0) && (cmp <= 0)) || + ((inexact < 0) && (cmp >= 0))) + { + printf ("Wrong ternary value in mpfr_set for %s (%d):" + " expected %d, got %d\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), + k, cmp, inexact); + exit (1); + } } } } diff -Naurd mpfr-4.1.0-a/tests/tset_exp.c mpfr-4.1.0-b/tests/tset_exp.c --- mpfr-4.1.0-a/tests/tset_exp.c 2020-01-08 18:11:13.000000000 +0000 +++ mpfr-4.1.0-b/tests/tset_exp.c 2021-03-09 13:55:43.211158639 +0000 @@ -28,6 +28,7 @@ mpfr_t x; int ret; mpfr_exp_t emin, emax, e; + int i = 0; tests_start_mpfr (); @@ -63,6 +64,17 @@ e = (mpfr_get_exp) (x); MPFR_ASSERTN (e == emin); +#ifdef IGNORE_CPP_COMPAT +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++-compat" +#endif + e = mpfr_get_exp ((i++, VOIDP_CAST(x))); +#ifdef IGNORE_CPP_COMPAT +#pragma GCC diagnostic pop +#endif + MPFR_ASSERTN (e == emin); + MPFR_ASSERTN (i == 1); + ret = mpfr_set_exp (x, -1); MPFR_ASSERTN (ret == 0 && mpfr_cmp_ui_2exp (x, 1, -2) == 0);