(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
Wfree-nonheap-object.c
       1  /* PR ????? - No warning on attempts to access free object
       2     Verify that freeing unallocated objects referenced either directly
       3     or through pointers is diagnosed.  In most cases this doesn't require
       4     optimization.
       5     { dg-do compile }
       6     { dg-options "-Wall -Wfree-nonheap-object" }
       7     { dg-require-effective-target alloca } */
       8  
       9  typedef __INTPTR_TYPE__ intptr_t;
      10  typedef __SIZE_TYPE__   size_t;
      11  
      12  extern void free (void*);
      13  extern void* malloc (size_t);
      14  extern void* realloc (void *p, size_t);
      15  
      16  void sink (void*, ...);
      17  
      18  extern char ecarr[];
      19  extern void* eparr[];
      20  
      21  extern char *eptr;
      22  
      23  void* source (void);
      24  
      25  void nowarn_free (void *p, void **pp, size_t n, intptr_t iptr)
      26  {
      27    free (p);
      28  
      29    p = 0;
      30    free (p);
      31  
      32    p = malloc (n);
      33    sink (p);
      34    free (p);
      35  
      36    p = malloc (n);
      37    sink (p);
      38  
      39    p = realloc (p, n * 2);
      40    sink (p);
      41    free (p);
      42  
      43    free ((void*)iptr);
      44  
      45    p = source ();
      46    free (p);
      47  
      48    p = source ();
      49    p = (char*)p - 1;
      50    free (p);
      51  
      52    free (*pp);
      53  }
      54  
      55  void warn_free_extern_arr (void)
      56  {
      57    free (ecarr);               // { dg-warning "\\\[-Wfree-nonheap-object" }
      58  }
      59  
      60  void warn_free_extern_arr_offset (int i)
      61  {
      62    char *p = ecarr + i;
      63    free (p);                   // { dg-warning "\\\[-Wfree-nonheap-object" }
      64  }
      65  
      66  
      67  void warn_free_cstint (void)
      68  {
      69    void *p = (void*)1;
      70    sink (p);
      71    free (p);                   // { dg-warning "\\\[-Wfree-nonheap-object" }
      72  }
      73  
      74  
      75  void warn_free_func (void)
      76  {
      77    void *p = warn_free_func;
      78    sink (p);
      79    free (p);                   // { dg-warning "\\\[-Wfree-nonheap-object" }
      80  }
      81  
      82  
      83  void warn_free_string (int i)
      84  {
      85    {
      86      char *p = "123";
      87      sink (p);
      88      free (p);                 // { dg-warning "\\\[-Wfree-nonheap-object" }
      89    }
      90    {
      91      char *p = "234" + 1;
      92      sink (p);
      93      free (p);                 // { dg-warning "\\\[-Wfree-nonheap-object" }
      94    }
      95    {
      96      char *p = "345" + i;
      97      sink (p);
      98      free (p);                 // { dg-warning "\\\[-Wfree-nonheap-object" }
      99    }
     100  
     101    if (i >= 0)
     102      {
     103        char *p = "456" + i;
     104        sink (p);
     105        free (p);               // { dg-warning "\\\[-Wfree-nonheap-object" }
     106      }
     107  }
     108  
     109  void warn_free_local_arr (int i)
     110  {
     111    {
     112      char a[4];
     113      sink (a);
     114      free (a);                 // { dg-warning "\\\[-Wfree-nonheap-object" }
     115    }
     116    {
     117      char b[5];
     118      sink (b);
     119  
     120      char *p = b + 1;
     121      free (p);                 // { dg-warning "\\\[-Wfree-nonheap-object" }
     122    }
     123    {
     124      char c[6];
     125      sink (c);
     126  
     127      char *p = c + i;
     128      free (p);                 // { dg-warning "\\\[-Wfree-nonheap-object" }
     129    }
     130  }
     131  
     132  
     133  void warn_free_vla (int n, int i)
     134  {
     135    {
     136      int vla[n], *p = vla;
     137      sink (p);
     138      free (p);                 // { dg-warning "\\\[-Wfree-nonheap-object" }
     139    }
     140  
     141    {
     142      int vla[n + 1], *p = vla + 1;
     143      sink (p);
     144      free (p);                 // { dg-warning "\\\[-Wfree-nonheap-object" }
     145    }
     146    {
     147      int vla[n + 2], *p = vla + i;
     148      sink (p);
     149      free (p);                 // { dg-warning "\\\[-Wfree-nonheap-object" }
     150    }
     151  }
     152  
     153  
     154  void nowarn_free_extern_ptrarr (void)
     155  {
     156    free (*eparr);
     157  }
     158  
     159  void nowarn_free_extern_ptrarr_offset (int i)
     160  {
     161    char *p = eparr[i];
     162    free (p);
     163  }
     164  
     165  
     166  void warn_free_extern_ptrarr (void)
     167  {
     168    free (eparr);               // { dg-warning "\\\[-Wfree-nonheap-object" }
     169  }
     170  
     171  void warn_free_extern_ptrarr_offset (int i)
     172  {
     173    void *p = &eparr[i];
     174    free (p);                   // { dg-warning "\\\[-Wfree-nonheap-object" }
     175  }
     176  
     177  
     178  void nowarn_free_local_ptrarr (int i)
     179  {
     180    void* a[4];
     181    sink (a);
     182    free (a[0]);
     183    free (a[1]);
     184    free (a[i]);
     185  }
     186  
     187  
     188  void nowarn_free_extern_ptr (void)
     189  {
     190    free (eptr);
     191  }
     192  
     193  void nowarn_free_extern_ptr_offset (int i)
     194  {
     195    char *p = eptr + i;
     196    free (p);
     197  }
     198  
     199  void nowarn_free_parm_offset (char *p, int i)
     200  {
     201    char *q = p + i;
     202    free (q);
     203  }
     204  
     205  void nowarn_free_parm_neg_offset (char *p, int i)
     206  {
     207    if (i >= 0)
     208      i = -1;
     209  
     210    char *q = p + i;
     211    free (q);
     212  }
     213  
     214  struct Members
     215  {
     216    char a[4], *p, *q;
     217  };
     218  
     219  extern struct Members em;
     220  
     221  void nowarn_free_member_ptr (struct Members *pm, int i)
     222  {
     223    char *p = em.p;
     224    free (p);
     225    p = em.q + i;
     226    free (p);
     227  
     228    free (pm->q);
     229    p = pm->p;
     230    free (pm);
     231    free (p);
     232  }
     233  
     234  void nowarn_free_struct_cast (intptr_t *p)
     235  {
     236    struct Members *q = (struct Members*)*p;
     237    if (q->p == 0)
     238      free (q);                 // { dg-bogus "\\\[-Wfree-nonheap-object" }
     239  }
     240  
     241  
     242  void warn_free_member_array (void)
     243  {
     244    char *p = em.a;
     245    free (p);                   // { dg-warning "\\\[-Wfree-nonheap-object" }
     246  }
     247  
     248  void warn_free_member_array_off (int i)
     249  {
     250    char *p = em.a + i;
     251    free (p);                   // { dg-warning "\\\[-Wfree-nonheap-object" }
     252  }
     253  
     254  
     255  // Range information requires optimization.
     256  #pragma GCC optimize "1"
     257  
     258  void warn_free_extern_ptr_pos_offset (int i)
     259  {
     260    if (i <= 0)
     261      i = 1;
     262  
     263    char *q = eptr + i;
     264    free (q);                   // { dg-warning "\\\[-Wfree-nonheap-object" }
     265  }
     266  
     267  void warn_free_parm_pos_offset (char *p, int i)
     268  {
     269    if (i <= 0)
     270      i = 1;
     271  
     272    char *q = p + i;
     273    free (q);                   // { dg-warning "\\\[-Wfree-nonheap-object" }
     274  }