Fix variable argument list traversal for doubles.

* 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.
This commit is contained in:
Danny Milosavljevic 2019-08-27 04:04:56 +02:00 committed by Jan Nieuwenhuizen
parent 58fb0cf764
commit 4c77c2c9ca
No known key found for this signature in database
GPG key ID: F3C1A0D9C1D65273
3 changed files with 4 additions and 2 deletions

View file

@ -34,6 +34,8 @@
typedef char *va_list; typedef char *va_list;
#define va_start(ap, last) (void)((ap) = (char*)(&(last) + 1)) #define va_start(ap, last) (void)((ap) = (char*)(&(last) + 1))
#define va_arg(ap, type) (type)(((long*)((ap) = ((ap) + sizeof (void*))))[-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_end(ap) (void)((ap) = 0)
#define va_copy(dest, src) dest = src #define va_copy(dest, src) dest = src

View file

@ -188,7 +188,7 @@ vfprintf (FILE * f, char const *format, va_list ap)
case 'g': case 'g':
case 'G': case 'G':
{ {
double d = va_arg (ap, double); double d = va_arg8 (ap, double);
char *s = dtoab (d, 10, 1); char *s = dtoab (d, 10, 1);
if (c == 'E' || c == 'G') if (c == 'E' || c == 'G')
strupr (s); strupr (s);

View file

@ -204,7 +204,7 @@ vsnprintf (char *str, size_t size, char const *format, va_list ap)
case 'g': case 'g':
case 'G': case 'G':
{ {
double d = va_arg (ap, double); double d = va_arg8 (ap, double);
char *s = dtoab (d, 10, 1); char *s = dtoab (d, 10, 1);
if (c == 'E' || c == 'G') if (c == 'E' || c == 'G')
strupr (s); strupr (s);