On Mon, 13 May 2002, Poul-Henning Kamp wrote:

> GCC 3.1 whines about these two instances of va_arg() and generates
> code which calls "int 5" if they are executed.
>
> This workaround works for me, but I don't know if this is the
> correct fix so I won't commit it.

I just committed a correct fix (essentially s/u_short/int/).

About the bug:

            i = va_arg(ap, u_short);

has always given undefined behaviour.  gcc now detects this at compile
time.  Whoever changed gcc to do this must feel as strongly as me about
this error since they made it a fatal runtime error :-).  4.4BSD-Lite
also attempted to detect this error and make it fatal except in the
kernel.  From the i386 stdarg.h:

#ifdef KERNEL
#define va_arg(ap, type) \
        ((type *)(ap += sizeof(type)))[-1]
#else
#define va_arg(ap, type) \
        ((type *)(ap += sizeof(type) < sizeof(int) ? \
                (abort(), 0) : sizeof(type)))[-1]
#endif

but it is not really possible to do this without using a compiler
builtin, and the above code was changed in FreeBSD after a PR or two
about it.  The most obvious bug in it is that va_arg() is specified
to work on structs, and the size of a struct may be smaller than
sizeof(int).

I first noticed the 4.4BSDLite2 code when every single test prorgam
in NIST-PCTS (NIST POSIX Conformance Test Suite) aborted in it.  The
NIST sources perpetrate va_arg(ap, char) and va_arg(ap, foo_t) (where
foo_t _might_ be a sub-integer type) in a central place.  Fixing bugs
in the test suite is not permitted for attaining conformance, so
FreeBSD is again 100% POSIX-non-conformant according to NIST-PCTS :-).

Bruce


To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to