1/* Copyright (C) 2000 Free Software Foundation. 2 3 If the argument to va_end() has side effects, test whether side 4 effects from that argument are honored. 5 6 Written by Kaveh R. Ghazi, 10/31/2000. */ 7 8#include <stdarg.h> 9#include <stdio.h> 10#include <stdlib.h> 11 12#ifndef __GNUC__ 13#define __attribute__(x) 14#endif 15 16static void __attribute__ ((__format__ (__printf__, 1, 2))) 17doit (const char *s, ...) 18{ 19 va_list *ap_array[3], **ap_ptr = ap_array; 20 21 ap_array[0] = malloc (sizeof(va_list)); 22 ap_array[1] = NULL; 23 ap_array[2] = malloc (sizeof(va_list)); 24 25 va_start (*ap_array[0], s); 26 vprintf (s, **ap_ptr); 27 /* Increment the va_list pointer once. */ 28 va_end (**ap_ptr++); 29 30 /* Increment the va_list pointer a second time. */ 31 ap_ptr++; 32 33 va_start (*ap_array[2], s); 34 /* If we failed to increment ap_ptr twice, then the parameter passed 35 in here will dereference NULL and should cause a crash. */ 36 vprintf (s, **ap_ptr); 37 va_end (**ap_ptr); 38 39 /* Just in case, If *ap_ptr is NULL abort anyway. */ 40 if (*ap_ptr == 0) 41 abort(); 42} 43 44int main() 45{ 46 doit ("%s", "hello world\n"); 47 exit (0); 48} 49