Bladeren bron

protect against long double type mismatches (mainly powerpc for now)

check in configure to be polite (failing early if we're going to fail)
and in vfprintf.c since that is the point at which a mismatching type
would be extremely dangerous.
Rich Felker 11 jaren geleden
bovenliggende
commit
86cc54b577
2 gewijzigde bestanden met toevoegingen van 28 en 0 verwijderingen
  1. 21 0
      configure
  2. 7 0
      src/stdio/vfprintf.c

+ 21 - 0
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

+ 7 - 0
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];