Skip site navigation (1)Skip section navigation (2)
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>