about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2014-12-17 16:34:41 -0500
committerRich Felker <dalias@aerifal.cx>2014-12-17 16:43:09 -0500
commit5ff2a118c64224789b7286830912425e58831b2b (patch)
tree9d017e79d086e49919b728a18a2fabcffb43e78d
parenta414e8374dfe32f5efd35a49592698f89878de1f (diff)
downloadmusl-5ff2a118c64224789b7286830912425e58831b2b.tar.gz
musl-5ff2a118c64224789b7286830912425e58831b2b.tar.xz
musl-5ff2a118c64224789b7286830912425e58831b2b.zip
fix definition of CMPLX macros in complex.h to work in constant expressions
based on patches by Jens Gustedt. these macros need to be usable in
static initializers, and the old definitions were not.

there is no portable way to provide correct definitions for these
macros unless the compiler supports pure imaginary types. a portable
definition is provided for this case even though there are presently
no compilers that can use it. gcc and compatible compilers provide a
builtin function that can be used, but clang fails to support this and
instead requires a construct which is a constraint violation and which
is only a constant expression as a clang-specific extension.

since these macros are a namespace violation in pre-C11 profiles, and
since no known pre-C11 compilers provide any way to define them
correctly anyway, the definitions have been made conditional on C11.
-rw-r--r--include/complex.h12
1 files changed, 9 insertions, 3 deletions
diff --git a/include/complex.h b/include/complex.h
index e1af0d59..23bab7d5 100644
--- a/include/complex.h
+++ b/include/complex.h
@@ -114,12 +114,18 @@ long double creall(long double complex);
 #define cimagl(x) __CIMAG(x, long double)
 #endif
 
-#define __CMPLX(x, y, t) \
-	((union { _Complex t __z; t __xy[2]; }){.__xy = {(x),(y)}}.__z)
-
+#if __STDC_VERSION__ >= 201112L
+#if defined(_Imaginary_I)
+#define __CMPLX(x, y, t) ((t)(x) + _Imaginary_I*(t)(y)))
+#elif defined(__clang__)
+#define __CMPLX(x, y, t) (+(_Complex t){ (t)(x), (t)(y) })
+#else
+#define __CMPLX(x, y, t) (__builtin_complex((t)(x), (t)(y)))
+#endif
 #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
 }