From owner-freebsd-bugs Thu May 17 5:34:19 2001 Delivered-To: freebsd-bugs@freebsd.org Received: from core.inf.ethz.ch (core.inf.ethz.ch [129.132.178.196]) by hub.freebsd.org (Postfix) with ESMTP id 9EAC837B440 for ; Thu, 17 May 2001 05:34:09 -0700 (PDT) (envelope-from cartho@silmaril.org) Received: from lillian-ics.inf.ethz.ch (root@lillian-ics.inf.ethz.ch [129.132.134.2]) by core.inf.ethz.ch (8.9.3/8.9.3) with ESMTP id OAA27721; Thu, 17 May 2001 14:34:04 +0200 (MET DST) Received: from silmaril.org (babylon8.inf.ethz.ch [129.132.134.131]) by lillian-ics.inf.ethz.ch (8.9.3/8.9.3) with ESMTP id OAA04001; Thu, 17 May 2001 14:34:06 +0200 (MET DST) Message-ID: <3B03C53C.349F9491@silmaril.org> Date: Thu, 17 May 2001 14:34:04 +0200 From: Cyrille Artho Organization: ETH Zurich X-Mailer: Mozilla 4.76 [en] (X11; U; Linux 2.2.19pre17 i686) X-Accept-Language: en MIME-Version: 1.0 To: bugs@freebsd.org Cc: Ernst de Haan Subject: Insufficient type casts in stdargs.h Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org Hi, in FreeBSD 4.3's stdargs.h, the macro va_arg does not contain enough type casts. As a result, gcc 2.95.3 rejects using va_arg with void* arguments. The GNU stdargs.h contains extra type casts, allowing this. I rewrote the BSD to include extra type casts, fixing now problems with void* va_arg arguments: Original macro in /usr/include/stdarg.h, line 53: #define va_arg(ap, type) \ (*(type *)((ap) += __va_size(type), (ap) - __va_size(type))) My suggestion: #define va_arg(ap, type) \ (*(type *)((ap) = (type *)((char *)ap + __va_size(type)), \ (type *)(((char *)ap) - __va_size(type)))) This adds three extra type casts, two intermediate ones to char* and one more to type*. Moreover, I had to write out the += operator as it is not allowed with void* anymore. Please review this patch carefully, as it is a critical header file, and not very easy to read - so I could have made an error, or there may be a better way to fix the problem. Originally, this compiler problem was discovered by Ernst de Haan, when he tried to compile my Java program checker Jlint (http://artho.com/jlint/). I include the full information about the line of code that did not compile below: Original source code: parameter[n_parameters++] = va_arg(ap, void*); ------------------------------------------------------------------------- Linux little endian systems: #define va_arg(AP, TYPE) \ (AP = (__gnuc_va_list) ((char *) (AP) + __va_rounded_size (TYPE)), \ *((TYPE *) (void *) ((char *) (AP) - __va_rounded_size (TYPE)))) Expanded source code: parameter[n_parameters++] = ( ap = (__gnuc_va_list) ((char *) ( ap ) + (((sizeof ( void* ) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) ), *(( void* *) (void *) ((char *) ( ap ) - (((sizeof ( void* ) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) ))) ; ------------------------------------------------------------------------- FreeBSD: #define va_arg(ap, type) \ (*(type *)((ap) += __va_size(type), (ap) - __va_size(type))) Expanded source code: parameter[n_parameters++] = (*( void* *)(( ap ) += (((sizeof( void* ) + sizeof(int) - 1) / sizeof(int)) * sizeof(int)) , ( ap ) - (((sizeof( void* ) + sizeof(int) - 1) / sizeof(int)) * sizeof(int)) )) jlint.cc:141: ANSI C++ forbids using pointer of type `void *' in arithmetic jlint.cc:141: ANSI C++ forbids using pointer of type `void *' in arithmetic Provisional fix: #define va_arg(ap, type) \ (*(type *)((ap) = (type *)((char *)ap + __va_size(type)), \ (type *)(((char *)ap) - __va_size(type)))) -- Regards, Cyrille Artho - http://artho.com/ - Tel. +41 - [0]1 - 632 09 88 If you go on with this nuclear arms race, all you are going to do is make the rubble bounce. -- Winston Churchill To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message