From e1522d7bfffc3357a0e2669d2e65e65b3e192d72 Mon Sep 17 00:00:00 2001 From: kai Date: Tue, 7 Jan 2014 19:58:51 +0100 Subject: [PATCH] Fix NaN constants on ARM. The dmd source assumes x86 longdoubles which are not available on ARM (and possible other systems). This leads to an assertion error in PortInitializer. The workaround is to check for the size of longdouble. --- dmd2/root/port.c | 57 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 14 deletions(-) diff --git a/dmd2/root/port.c b/dmd2/root/port.c index f182caf1..8386b3f5 100644 --- a/dmd2/root/port.c +++ b/dmd2/root/port.c @@ -686,42 +686,71 @@ PortInitializer::PortInitializer() assert(!signbit(Port::nan)); #if IN_LLVM - union - { unsigned int ui[4]; - longdouble ld; - } ldbl_nan = + if (sizeof(double) == sizeof(longdouble)) + { + // double and longdouble are same type. + // E.g. on ARM. + Port::ldbl_nan = Port::nan; + } + else + { + union + { unsigned int ui[4]; + longdouble ld; + } ldbl_nan = #if __LITTLE_ENDIAN__ - {{ 0, 0xC0000000, 0x7FFF, 0}}; + {{ 0, 0xC0000000, 0x7FFF, 0}}; #else - {{ 0, 0x7FFF, 0xC0000000, 0}}; + {{ 0, 0x7FFF, 0xC0000000, 0}}; #endif + Port::ldbl_nan = ldbl_nan.ld; + } #else union { unsigned int ui[4]; longdouble ld; } ldbl_nan = {{ 0, 0xC0000000, 0x7FFF, 0}}; + Port::ldbl_nan = ldbl_nan.ld; #endif - Port::ldbl_nan = ldbl_nan.ld; assert(!signbit(Port::ldbl_nan)); #if IN_LLVM - union - { unsigned int ui[4]; - longdouble ld; - } snan = + if (sizeof(double) == sizeof(longdouble)) + { + // double and longdouble are same type. + // E.g. on ARM. + union + { unsigned int ui[2]; + double d; + } snan = #if __LITTLE_ENDIAN__ - {{ 0, 0xA0000000, 0x7FFF, 0 }}; + {{ 0, 0x7FFC0000 }}; #else - {{ 0, 0x7FFF, 0xA0000000, 0 }}; + {{ 0x7FFC0000, 0 }}; #endif + Port::snan = snan.d; + } + else + { + union + { unsigned int ui[4]; + longdouble ld; + } snan = + #if __LITTLE_ENDIAN__ + {{ 0, 0xA0000000, 0x7FFF, 0 }}; + #else + {{ 0, 0x7FFF, 0xA0000000, 0 }}; + #endif + Port::snan = snan.ld; + } #else union { unsigned int ui[4]; longdouble ld; } snan = {{ 0, 0xA0000000, 0x7FFF, 0 }}; -#endif Port::snan = snan.ld; +#endif #if __FreeBSD__ && __i386__ // LDBL_MAX comes out as infinity. Fix.