1  #include <stdio.h>
       2  #include <stdlib.h>
       3  
       4  extern void do_stuff (void);
       5  
       6  int test (const char *filename, int flag)
       7  {
       8    FILE *f;
       9    int *p, *q;
      10    int i;
      11  
      12    p = (int *)malloc (sizeof (int)); /* { dg-line malloc_of_p } */
      13    if (!p) /* { dg-line test_of_p } */
      14      {
      15        free (p);
      16        return -1;
      17      }
      18  
      19    q = (int *)malloc (sizeof (int)); /* { dg-line malloc_of_q } */
      20    if (!q) /* { dg-line test_of_q } */
      21      {
      22        free (p); /* { dg-line first_free_of_p } */
      23        /* oops: forgot the "return" here, so it falls through.  */
      24      }
      25  
      26    do_stuff ();
      27  
      28    free (p); /* { dg-line second_free_of_p } */
      29    free (q);
      30    return 0;
      31  
      32    /* { dg-warning "double-'free' of 'p'" "warning" { target *-*-* } second_free_of_p } */
      33    /* { dg-message "\\(1\\) allocated here" "event 1" { target *-*-* } malloc_of_p } */
      34    /* { dg-message "\\(2\\) assuming 'p' is non-NULL" "event 2" { target *-*-* } test_of_p } */
      35    /* { dg-message "\\(3\\) following 'false' branch \\(when 'p' is non-NULL\\)\\.\\.\\." "event 3" { target *-*-* } test_of_p } */
      36    /* { dg-message "\\(4\\) \\.\\.\\.to here" "event 4" { target *-*-* } malloc_of_q } */
      37    /* { dg-message "\\(5\\) following 'true' branch \\(when 'q' is NULL\\)\\.\\.\\." "event 5" { target *-*-* } test_of_q } */
      38    /* { dg-message "\\(6\\) \\.\\.\\.to here" "event 6" { target *-*-* } first_free_of_p } */
      39    /* { dg-message "\\(7\\) first 'free' here" "event 7" { target *-*-* } first_free_of_p } */
      40    /* { dg-message "\\(8\\) second 'free' here; first 'free' was at \\(7\\)" "event 8" { target *-*-* } second_free_of_p } */
      41  
      42    /* We don't care about the state changes to q.  */
      43  }