Date: Mon, 16 Jun 1997 19:36:20 +0200 (MEST) From: arnej@mail.math.ntnu.no To: FreeBSD-gnats-submit@FreeBSD.ORG Subject: bin/3884: stdarg.h fails for data types < 4 bytes Message-ID: <199706161736.TAA15725@frida.math.ntnu.no> Resent-Message-ID: <199706161740.KAA18177@hub.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 3884 >Category: bin >Synopsis: stdarg.h fails for data types < 4 bytes >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Mon Jun 16 10:40:01 PDT 1997 >Last-Modified: >Originator: Arne Henrik Juul >Organization: Norwegian University of Technology and Science >Release: FreeBSD 2.2-STABLE i386 >Environment: 2.2 branch and -current. >Description: The standard include file <stdarg.h> #defines va_arg to make an explicit abort() when asked to get an argument with sizeof(type) < sizeof(int). Probably stdarg.h should follow the conventions of the C compiler instead. >How-To-Repeat: Inspect <stdarg.h>, or compile and run the following test program, gotten from c-torture. #include <stdarg.h> struct tiny { short c; }; f (int n, ...) { struct tiny x; int i; va_list ap; va_start (ap,n); for (i = 0; i < n; i++) { x = va_arg (ap,struct tiny); if (x.c != i + 10) abort(); } { long x = va_arg (ap, long); if (x != 123) abort(); } va_end (ap); } main () { struct tiny x[3]; x[0].c = 10; x[1].c = 11; x[2].c = 12; f (3, x[0], x[1], x[2], (long) 123); exit(0); } >Fix: Apply following patch: --- /usr/src/sys/i386/include/stdarg.h Wed Apr 2 14:31:20 1997 +++ ./stdarg.h Mon Jun 16 19:16:48 1997 @@ -39,13 +39,13 @@ typedef char *va_list; +#define __va_promote(type) \ + (((sizeof(type) + sizeof(int) - 1) / sizeof(int)) * sizeof(int)) + #ifdef __GNUC__ #define va_start(AP, LASTARG) \ (AP = ((va_list) __builtin_next_arg (LASTARG))) #else -#define __va_promote(type) \ - (((sizeof(type) + sizeof(int) - 1) / sizeof(int)) * sizeof(int)) - #define va_start(ap, last) \ (ap = ((va_list)&(last) + __va_promote(last))) #endif @@ -55,8 +55,7 @@ ((type *)(ap += sizeof(type)))[-1] #else #define va_arg(ap, type) \ - ((type *)(ap += sizeof(type) < sizeof(int) ? \ - (abort(), 0) : sizeof(type)))[-1] + (*((type *)(ap += __va_promote(type), ap - __va_promote(type)))) #endif #define va_end(ap) >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199706161736.TAA15725>