From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/6634 Path: news.gmane.org!not-for-mail From: Jens Gustedt Newsgroups: gmane.linux.lib.musl.general Subject: [PATCH 1/4] the CMPLX macros must be usable in initializations of static variables Date: Wed, 26 Nov 2014 14:07:55 +0100 Message-ID: <1417007215.28402.107.camel@eris.loria.fr> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Transfer-Encoding: 7bit X-Trace: ger.gmane.org 1417007298 11888 80.91.229.3 (26 Nov 2014 13:08:18 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Wed, 26 Nov 2014 13:08:18 +0000 (UTC) To: musl@lists.openwall.com Original-X-From: musl-return-6647-gllmg-musl=m.gmane.org@lists.openwall.com Wed Nov 26 14:08:12 2014 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by plane.gmane.org with smtp (Exim 4.69) (envelope-from ) id 1XtcKJ-0001h7-A0 for gllmg-musl@m.gmane.org; Wed, 26 Nov 2014 14:08:11 +0100 Original-Received: (qmail 30151 invoked by uid 550); 26 Nov 2014 13:08:10 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: Original-Received: (qmail 30134 invoked from network); 26 Nov 2014 13:08:09 -0000 X-IronPort-AV: E=Sophos;i="5.07,462,1413237600"; d="scan'208";a="109685730" Resent-From: Jens Gustedt Resent-To: musl@lists.openwall.com X-Mailer: Evolution 3.4.4-3 Xref: news.gmane.org gmane.linux.lib.musl.general:6634 Archived-At: Because of some boundary cases for infinities and negative zeros, doing this properly is only possible with either support for _Imaginary or some compiler magic. For the moment, we only know such magic for clang and gcc. There it is only available for newer compilers. Therefore we make the CMPLX macros only available when in C11 mode (or actually even in C1X mode). Internally for the compilation of the complex functions of the math library we use such a macro, but that doesn't have the constraint of being usable for static initializations. So if we are not in C11, we provide such a macro as __CMPLX_NC in complex.h and map the CMPLX macros internally to that. As an effect this reverts commit faea4c9937d36b17e53fdc7d5a254d7e936e1755. --- include/complex.h | 30 ++++++++++++++++++++++++++++-- src/internal/libm.h | 8 ++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/include/complex.h b/include/complex.h index 13a45c5..e88cf13 100644 --- a/include/complex.h +++ b/include/complex.h @@ -112,12 +112,38 @@ long double creall(long double complex); #define cimagf(x) __CIMAG(x, float) #define cimagl(x) __CIMAG(x, long double) -#define __CMPLX(x, y, t) \ - ((union { _Complex t __z; t __xy[2]; }){.__xy = {(x),(y)}}.__z) +#ifdef _Imaginary_I +# define __CMPLX(x, y, t) ((t)(x) + _Imaginary_I*(t)(y)) +#else +# define __CMPLX_I(x, y, t) ((t)(x) + _Complex_I*(t)(y)) +#endif + +#ifndef __CMPLX +# if defined(__clang__) + /* Clang allows initializer lists for complex numbers and compound + literals for the initialization of static variables. */ +# define __CMPLX(x, y, t) (+(_Complex t){ (x), (y) }) +# elif 100*__GNUC__+__GNUC_MINOR__ >= 407 +# define __CMPLX(x, y, t) __builtin_complex((t)(x), (t)(y)) +# endif +#endif +#ifndef __CMPLX +# if __STDC_VERSION__ >= 201000L +# warning for this compiler, macros CMPLX, CMPLXF and CMPLXL are not standard +# warning conforming for infinities and signed zeros +# define __CMPLX(x, y, t) __CMPLX_I(x, y, t) +# endif +# define __CMPLX_NC(x, y, t) (+(union { _Complex t __z; t __xy[2]; }){.__xy = {(x),(y)}}.__z) +#else +# define __CMPLX_NC(x, y, t) __CMPLX(x, y, t) +#endif + +#if __STDC_VERSION__ >= 201000L #define CMPLX(x, y) __CMPLX(x, y, double) #define CMPLXF(x, y) __CMPLX(x, y, float) #define CMPLXL(x, y) __CMPLX(x, y, long double) +#endif #ifdef __cplusplus } diff --git a/src/internal/libm.h b/src/internal/libm.h index ebcd784..f916e2e 100644 --- a/src/internal/libm.h +++ b/src/internal/libm.h @@ -155,4 +155,12 @@ long double __tanl(long double, long double, int); long double __polevll(long double, const long double *, int); long double __p1evll(long double, const long double *, int); +/* complex */ + +#ifndef CMPLX +#define CMPLX(x, y) __CMPLX_NC(x, y, double) +#define CMPLXF(x, y) __CMPLX_NC(x, y, float) +#define CMPLXL(x, y) __CMPLX_NC(x, y, long double) +#endif + #endif -- 1.9.1