1  /* { dg-do compile } */
       2  /* { dg-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */
       3  
       4  #include <stdlib.h>
       5  
       6  void *wrapped_malloc (size_t size)
       7  {
       8    return malloc (size);
       9  }
      10  
      11  void wrapped_free (void *ptr)
      12  {
      13    free (ptr); /* { dg-warning "double-free of 'ptr' \\\[CWE-415\\]" } */
      14    /* { dg-begin-multiline-output "" }
      15     free (ptr);
      16     ^~~~~~~~~~
      17    'test': events 1-2
      18      |
      19      | {
      20      | ^
      21      | |
      22      | (1) entering 'test'
      23      |   boxed_int *obj = make_boxed_int (i);
      24      |                    ~~~~~~~~~~~~~~~~~~
      25      |                    |
      26      |                    (2) calling 'make_boxed_int'
      27      |
      28      +--> 'make_boxed_int': events 3-4
      29             |
      30             | {
      31             | ^
      32             | |
      33             | (3) entering 'make_boxed_int'
      34             |   boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int));
      35             |                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      36             |                                    |
      37             |                                    (4) calling 'wrapped_malloc'
      38             |
      39             +--> 'wrapped_malloc': events 5-6
      40                    |
      41                    | {
      42                    | ^
      43                    | |
      44                    | (5) entering 'wrapped_malloc'
      45                    |   return malloc (size);
      46                    |          ~~~~~~~~~~~~~
      47                    |          |
      48                    |          (6) calling 'malloc'
      49                    |
      50      <-------------+
      51      |
      52    'test': event 7
      53      |
      54      |   free_boxed_int (obj);
      55      |   ^~~~~~~~~~~~~~~~~~~~
      56      |   |
      57      |   (7) calling 'free_boxed_int'
      58      |
      59      +--> 'free_boxed_int': events 8-9
      60             |
      61             | {
      62             | ^
      63             | |
      64             | (8) entering 'free_boxed_int'
      65             |   wrapped_free (bi);
      66             |   ~~~~~~~~~~~~~~~~~
      67             |   |
      68             |   (9) calling 'wrapped_free'
      69             |
      70             +--> 'wrapped_free': events 10-11
      71                    |
      72                    | {
      73                    | ^
      74                    | |
      75                    | (10) entering 'wrapped_free'
      76                    |   free (ptr);
      77                    |   ~~~~~~~~~~
      78                    |   |
      79                    |   (11) calling 'free'
      80                    |
      81      <-------------+
      82      |
      83    'test': event 12
      84      |
      85      |   free_boxed_int (obj);
      86      |   ^~~~~~~~~~~~~~~~~~~~
      87      |   |
      88      |   (12) calling 'free_boxed_int'
      89      |
      90      +--> 'free_boxed_int': events 13-14
      91             |
      92             | {
      93             | ^
      94             | |
      95             | (13) entering 'free_boxed_int'
      96             |   wrapped_free (bi);
      97             |   ~~~~~~~~~~~~~~~~~
      98             |   |
      99             |   (14) calling 'wrapped_free'
     100             |
     101             +--> 'wrapped_free': events 15-16
     102                    |
     103                    | {
     104                    | ^
     105                    | |
     106                    | (15) entering 'wrapped_free'
     107                    |   free (ptr);
     108                    |   ~~~~~~~~~~
     109                    |   |
     110                    |   (16) calling 'free'
     111                    |
     112       { dg-end-multiline-output "" } */
     113  }
     114  
     115  typedef struct boxed_int
     116  {
     117    int i;
     118  } boxed_int;
     119  
     120  boxed_int *
     121  make_boxed_int (int i)
     122  {
     123    boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int));
     124    result->i = i;
     125    return result;
     126  }
     127  
     128  void
     129  free_boxed_int (boxed_int *bi)
     130  {
     131    wrapped_free (bi);
     132  }
     133  
     134  void test (int i)
     135  {
     136    boxed_int *obj = make_boxed_int (i);
     137  
     138    free_boxed_int (obj);
     139  
     140    free_boxed_int (obj);
     141  }
     142