(root)/
gcc-13.2.0/
gcc/
testsuite/
c-c++-common/
Wuse-after-free-2.c
       1  /* Verify that accessing freed objects by built-in functions is diagnosed.
       2     { dg-do compile }
       3     { dg-options "-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  EXTERN_C void free (void*);
      14  EXTERN_C void* realloc (void*, size_t);
      15  
      16  EXTERN_C void* memcpy (void*, const void*, size_t);
      17  EXTERN_C char* strcpy (char*, const char*);
      18  EXTERN_C size_t strlen (const char*);
      19  
      20  
      21  void sink (void*, ...);
      22  
      23  struct Member { char *p; char a[4]; };
      24  
      25  int nowarn_strcpy_memptr (struct Member *p)
      26  {
      27    char *q = strcpy (p->p, p->a);
      28    free (p);
      29    return *q;
      30  }
      31  
      32  int nowarn_strlen_memptr (struct Member *p)
      33  {
      34    const char *q = p->p;
      35  
      36    free (p);
      37  
      38    return strlen (q);
      39  }
      40  
      41  int warn_strlen_memptr (struct Member *p)
      42  {
      43    free (p);                   // { dg-message "call to '\(void \)?free\(\\(void\\*\\)\)?'" "note" }
      44    return strlen (p->p);       // { dg-warning "-Wuse-after-free" }
      45  }
      46  
      47  int warn_strlen_memarray (struct Member *p)
      48  {
      49    {
      50      free (p);
      51      return strlen (p->a);     // { dg-warning "-Wuse-after-free" }
      52    }
      53  
      54    {
      55      char *q = p->a;
      56  
      57      free (p);
      58      return strlen (q);        // { dg-warning "-Wuse-after-free" "pr??????" { xfail *-*-* } }
      59    }
      60  }
      61  
      62  void* nowarn_realloc_success (void *p)
      63  {
      64    void *q = realloc (p, 7);
      65    if (!q)
      66      /* When realloc fails the original pointer remains valid.  */
      67      return p;
      68  
      69    return q;
      70  }
      71  
      72  void* nowarn_realloc_equal (void *p, int *moved)
      73  {
      74    void *q = realloc (p, 7);
      75    /* Verify that equality is not diagnosed at the default level
      76       (it is diagnosed at level 3).  */
      77    *moved = !(p == q);
      78    return q;
      79  }
      80  
      81  void* nowarn_realloc_unequal (void *p, int *moved)
      82  {
      83    void *q = realloc (p, 7);
      84    /* Verify that inequality is not diagnosed at the default level
      85       (it is diagnosed at level 3).  */
      86    *moved = p != q;
      87    return q;
      88  }
      89  
      90  void* warn_realloc_relational (void *p, int *rel)
      91  {
      92    void *q = realloc (p, 7);       // { dg-message "call to '\(void\\* \)?realloc\(\\(void\\*, size_t\\)\)?'" "note" }
      93    /* Verify that all relational expressions are diagnosed at the default
      94       level.  */
      95    rel[0] = (char*)p < (char*)q;  // { dg-warning "-Wuse-after-free" }
      96    rel[1] = (char*)p <= (char*)q; // { dg-warning "-Wuse-after-free" }
      97    rel[2] = (char*)p >= (char*)q; // { dg-warning "-Wuse-after-free" }
      98    rel[3] = (char*)p > (char*)q;  // { dg-warning "-Wuse-after-free" }
      99    return q;
     100  }
     101  
     102  void* warn_realloc_unchecked (void *p, int *moved)
     103  {
     104    void *q = realloc (p, 7);       // { dg-message "call to '\(void\\* \)?realloc\(\\(void\\*, size_t\\)\)?'" "note" }
     105    /* Use subtraction rather than inequality to trigger the warning
     106       at the default level (equality is diagnosed only at level 3).  */
     107    *moved = (char*)p - (char*)q;   // { dg-warning "-Wuse-after-free" }
     108    return q;
     109  }
     110  
     111  void* nowarn_realloc_unchecked_copy (void *p1, void *p2, const void *s,
     112  				     int n, int *x)
     113  {
     114    void *p3 = memcpy (p1, s, n);
     115    void *p4 = realloc (p2, 7);
     116    *x = p3 != p4;
     117    return p4;
     118  }
     119  
     120  void* warn_realloc_unchecked_copy (void *p, const void *s, int n, int *moved)
     121  {
     122    void *p2 = memcpy (p, s, n);
     123    void *q = realloc (p, 7);       // { dg-message "call to '\(void\\* \)?realloc\(\\(void\\*, size_t\\)\)?'" "note" }
     124    *moved = (char*)p2 - (char*)q;  // { dg-warning "-Wuse-after-free" }
     125    return q;
     126  }
     127  
     128  void* warn_realloc_failed (void *p, int *moved)
     129  {
     130    void *q = realloc (p, 7);           // { dg-message "call to '\(void\\* \)?realloc\(\\(void\\*, size_t\\)\)?'" "note" }
     131    if (q)
     132      {
     133        /* When realloc succeeds the original pointer is invalid.  */
     134        *moved = (char*)p - (char*)q;   // { dg-warning "-Wuse-after-free" }
     135        return q;
     136      }
     137  
     138    return p;
     139  }
     140  
     141  extern void *evp;
     142  
     143  void* warn_realloc_extern (void *p, int *moved)
     144  {
     145    evp = realloc (p, 7);
     146    if (evp)
     147      {
     148        /* When realloc succeeds the original pointer is invalid.  */
     149        *moved = (char*)p - (char*)evp;   // { dg-warning "-Wuse-after-free" "escaped" }
     150        return evp;
     151      }
     152  
     153    return p;                   // { dg-bogus "-Wuse-after-free" "safe use after realloc failure" { xfail *-*-* } }
     154  }
     155  
     156  struct A { void *p, *q; int moved; };
     157  
     158  void* warn_realloc_arg (struct A *p)
     159  {
     160    p->q = realloc (p->p, 7);
     161    if (p->q)
     162      {
     163        /* When realloc succeeds the original pointer is invalid.  */
     164        p->moved = p->p != p->q;  // { dg-warning "-Wuse-after-free" "escaped" { xfail *-*-* } }
     165        return p->q;
     166      }
     167  
     168    return p->p;
     169  }