summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure21
-rw-r--r--src/stdio/vfprintf.c7
2 files changed, 28 insertions, 0 deletions
diff --git a/configure b/configure
index 1d734726..48465f7c 100755
--- a/configure
+++ b/configure
@@ -393,6 +393,27 @@ test "$ARCH" = "microblaze" && trycppif __MICROBLAZEEL__ "$t" \
test "$SUBARCH" \
&& printf "configured for %s variant: %s\n" "$ARCH" "$ARCH$SUBARCH"
+#
+# Some archs (powerpc) have different possible long double formats
+# that the compiler can be configured for. The logic for whether this
+# is supported is in bits/float.h; in general, it is not. We need to
+# check for mismatches here or code in printf, strotd, and scanf will
+# be dangerously incorrect because it depends on (1) the macros being
+# correct, and (2) IEEE semantics.
+#
+printf "checking whether compiler's long double definition matches float.h... "
+echo '#include <float.h>' > "$tmpc"
+echo '#if LDBL_MANT_DIG == 53' >> "$tmpc"
+echo 'typedef char ldcheck[9-(int)sizeof(long double)];' >> "$tmpc"
+echo '#endif' >> "$tmpc"
+if $CC $CFLAGS_C99FSE -I./arch/$ARCH -I./include $CPPFLAGS $CFLAGS \
+ -c -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
+printf "yes\n"
+else
+printf "no\n"
+fail "$0: error: unsupported long double type"
+fi
+
printf "creating config.mak... "
exec 3>&1 1>config.mak
diff --git a/src/stdio/vfprintf.c b/src/stdio/vfprintf.c
index 1e7e6a47..a2b287bd 100644
--- a/src/stdio/vfprintf.c
+++ b/src/stdio/vfprintf.c
@@ -198,6 +198,13 @@ static char *fmt_u(uintmax_t x, char *s)
return s;
}
+/* Do not override this check. The floating point printing code below
+ * depends on the float.h constants being right. If they are wrong, it
+ * may overflow the stack. */
+#if LDBL_MANT_DIG == 53
+typedef char compiler_defines_long_double_incorrectly[9-(int)sizeof(long double)];
+#endif
+
static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t)
{
uint32_t big[(LDBL_MAX_EXP+LDBL_MANT_DIG)/9+1];