(root)/
gcc-13.2.0/
gcc/
testsuite/
c-c++-common/
Wuse-after-free-3.c
       1  /* Exercise -Wuse-after-free with user-defined deallocators.
       2     { dg-do compile }
       3     { dg-options "-O0 -Wall" } */
       4  
       5  typedef __SIZE_TYPE__ size_t;
       6  
       7  #if __cplusplus
       8  #  define EXTERN_C extern "C"
       9  #else
      10  #  define EXTERN_C extern
      11  #endif
      12  
      13  #define A(...) __attribute__ ((malloc (__VA_ARGS__)))
      14  
      15  EXTERN_C void free (void *);
      16  EXTERN_C void* realloc (void *, size_t);
      17  
      18  typedef struct List { struct List *next; } List;
      19  
      20  // User-defined allocator/deallocator just like like realloc and free.
      21  extern                     void  list_free (List *);
      22  extern                     List* list_realloc (size_t, List *);
      23  extern A (list_realloc, 2) List* list_realloc (size_t, List *);
      24  extern A (list_free, 1)    List* list_realloc (size_t, List *);
      25  
      26  
      27  void sink (void *);
      28  
      29  extern int ei;
      30  extern List *elp, *elpa[];
      31  
      32  void nowarn_list_free (struct List *lp)
      33  {
      34    {
      35      list_free (lp);
      36      lp = 0;
      37      sink (lp);
      38    }
      39    {
      40      list_free (elp);
      41      elp = 0;
      42      sink (elp);
      43    }
      44    {
      45      list_free (elpa[0]);
      46      elpa[0] = 0;
      47      sink (elpa[0]);
      48    }
      49    {
      50      void *vp = elpa[0];
      51      list_free (elpa[0]);
      52      sink (vp);
      53    }
      54    {
      55      List *p = elpa[1];
      56      if (ei & 1)
      57        list_free (p);
      58      if (ei & 2)
      59        sink (p);
      60    }
      61    {
      62      struct List *next = lp->next;
      63      list_free (lp);
      64      list_free (next);
      65    }
      66  }
      67  
      68  
      69  void nowarn_list_free_list (List *head)
      70  {
      71    for (List *p = head, *q; p; p = q)
      72      {
      73        q = p->next;
      74        list_free (p);
      75      }
      76  }
      77  
      78  void warn_list_free_list (List *head)
      79  {
      80    List *p = head;
      81    for (; p; p = p->next)      // { dg-warning "\\\[-Wuse-after-free" }
      82      list_free (p);            // { dg-message "call to '\(void \)?list_free\(\\(List\\*\\)\)?'" "note" }
      83  }