Fix variable argument list traversal for doubles.
authorDanny Milosavljevic <dannym@scratchpost.org>
Tue, 27 Aug 2019 02:04:56 +0000 (04:04 +0200)
committerJan Nieuwenhuizen <janneke@gnu.org>
Tue, 27 Aug 2019 02:04:56 +0000 (04:04 +0200)
* include/stdarg.h (va_align): New macro.
(va_arg8): New macro.
* lib/stdio/vfprintf.c (vfprintf): Use it.
* lib/stdio/vsnprintf.c (vsnprintf): Use it.

include/stdarg.h
lib/stdio/vfprintf.c
lib/stdio/vsnprintf.c

index 34061d0695321ac285d24b65cb2dd91056d28619..08c5ded56d48e36f5869b9423de3d3cb958fa67f 100644 (file)
@@ -34,6 +34,8 @@
 typedef char *va_list;
 #define va_start(ap, last) (void)((ap) = (char*)(&(last) + 1))
 #define va_arg(ap, type) (type)(((long*)((ap) = ((ap) + sizeof (void*))))[-1])
+#define va_align(ap, alignment) ((((unsigned long) (unsigned char*) ap) + (alignment) - 1) &~ (alignment - 1))
+#define va_arg8(ap, type) (type)(((double*)((ap) = (va_align((ap), 8) + sizeof(double))))[-1])
 #define va_end(ap) (void)((ap) = 0)
 #define va_copy(dest, src) dest = src
 
index 979ad8df7387ea7ee7ca562475f1477ae5f16f8a..00ac49173f81ccefca448bc19af29818e7740119 100644 (file)
@@ -188,7 +188,7 @@ vfprintf (FILE * f, char const *format, va_list ap)
           case 'g':
           case 'G':
             {
-              double d = va_arg (ap, double);
+              double d = va_arg8 (ap, double);
               char *s = dtoab (d, 10, 1);
               if (c == 'E' || c == 'G')
                 strupr (s);
index a8d9624d90e88793fa3270e090726ed9392ea917..b1ed2e0a658c981a9a5ba4923b22e06d0ac1db06 100644 (file)
@@ -204,7 +204,7 @@ vsnprintf (char *str, size_t size, char const *format, va_list ap)
           case 'g':
           case 'G':
             {
-              double d = va_arg (ap, double);
+              double d = va_arg8 (ap, double);
               char *s = dtoab (d, 10, 1);
               if (c == 'E' || c == 'G')
                 strupr (s);