modernc.org/ccgo/v3@v3.16.14/lib/testdata/gcc-9.1.0/gcc/testsuite/gcc.c-torture/execute/va-arg-21.c (about)

     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  
    16  static void __attribute__ ((__format__ (__printf__, 1, 2)))
    17  doit (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  
    44  int main()
    45  {
    46    doit ("%s", "hello world\n");
    47    exit (0);
    48  }