(root)/
gcc-13.2.0/
gcc/
testsuite/
c-c++-common/
Wuse-after-free-4.c
       1  /* Verify -Wuse-after-free=1 triggers only for unconditional uses and
       2     not for equality expressions.
       3     { dg-do compile }
       4     { dg-options "-O0 -Wall -Wuse-after-free=1" } */
       5  
       6  #if __cplusplus
       7  #  define EXTERN_C extern "C"
       8  #else
       9  #  define EXTERN_C extern
      10  #endif
      11  
      12  EXTERN_C void free (void*);
      13  
      14  void sink (void*);
      15  
      16  
      17  void warn_double_free (void *p)
      18  {
      19    free (p);
      20    free (p);         // { dg-warning "pointer 'p' used" }
      21  }
      22  
      23  void nowarn_cond_double_free (void *p, int c)
      24  {
      25    free (p);
      26    if (c)
      27      free (p);
      28  }
      29  
      30  void warn_call_after_free (void *p)
      31  {
      32    free (p);
      33    sink (p);         // { dg-warning "pointer 'p' used" }
      34  }
      35  
      36  void nowarn_cond_call_after_free (void *p, int c)
      37  {
      38    free (p);
      39    if (c)
      40      sink (p);
      41  }
      42  
      43  void* warn_return_after_free (void *p)
      44  {
      45    free (p);
      46    return p;         // { dg-warning "pointer 'p' used" }
      47  }
      48  
      49  void* nowarn_cond_return_after_free (void *p, int c)
      50  {
      51    free (p);
      52    if (c)
      53      return p;
      54    return 0;
      55  }
      56  
      57  void warn_relational_after_free (char *p, char *q[])
      58  {
      59    free (p);
      60  
      61    int a[] =
      62      {
      63       p < q[0],      // { dg-warning "pointer 'p' used" }
      64       p <= q[1],     // { dg-warning "pointer 'p' used" }
      65       p > q[2],      // { dg-warning "pointer 'p' used" }
      66       p >= q[3],     // { dg-warning "pointer 'p' used" }
      67       p == q[4],
      68       p != q[5]
      69      };
      70  
      71    sink (a);
      72  }
      73  
      74  void nowarn_cond_relational_after_free (char *p, char *q[], int c)
      75  {
      76    free (p);
      77  
      78    int a[] =
      79      {
      80       c ? p < q[0] : q[0][0],
      81       c ? p <= q[1] : q[1][1],
      82       c ? p > q[2] : q[2][2],
      83       c ? p >= q[3] : q[3][3],
      84       c ? p == q[4] : q[4][4],
      85       c ? p != q[5] : q[5][5],
      86      };
      87  
      88    sink (a);
      89  }
      90  
      91  
      92  // Verify no warning for the example in the manual.
      93  
      94  struct A { int refcount; void *data; };
      95  
      96  void release (struct A *p)
      97  {
      98    int refcount = --p->refcount;
      99    free (p);
     100    if (refcount == 0)
     101      free (p->data);   // no warning at level 1
     102  }