(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
analyzer/
leak-4.c
       1  /* Various tests of memory leak detection.  */
       2  
       3  #include <stdlib.h>
       4  
       5  /* Example of an leak due to incomplete cleanup when freeing a struct.  */
       6  
       7  struct s1
       8  {
       9    void *ptr;
      10  };
      11  
      12  void test_1 (void)
      13  {
      14    struct s1 *a = malloc (sizeof (struct s1));
      15    if (!a)
      16      return;
      17    a->ptr = malloc (1024); /* { dg-message "allocated here" } */
      18    free (a); /* { dg-warning "leak of '<unknown>'" } */
      19    /* TODO: we should print "a->ptr' here, rather than '<unknown>'
      20       (PR analyzer/99771).  */
      21  }
      22  
      23  
      24  /* Examples involving arrays.  */
      25  
      26  struct s2
      27  {
      28    void *m_arr[10];
      29  };
      30  
      31  void test_2a (void)
      32  {
      33    struct s2 arr[5];
      34    arr[3].m_arr[4] = malloc (1024); /* { dg-message "allocated here" } */
      35  } /* { dg-warning "leak of 'arr\\\[3\\\].m_arr\\\[4\\\]'" } */
      36  
      37  void test_2b (int i)
      38  {
      39    struct s2 arr[5];
      40    arr[3].m_arr[i] = malloc (1024); /* { dg-message "allocated here" } */
      41  } /* { dg-warning "leak of 'arr\\\[3\\\].m_arr\\\[i\\\]'" } */
      42  
      43  void test_2c (int i)
      44  {
      45    struct s2 arr[5];
      46    arr[i].m_arr[4] = malloc (1024); /* { dg-message "allocated here" } */
      47  } /* { dg-warning "leak of 'arr\\\[i\\\].m_arr\\\[4\\\]'" } */
      48  
      49  void test_2d (int i, int j)
      50  {
      51    struct s2 arr[5];
      52    arr[i].m_arr[j] = malloc (1024); /* { dg-message "allocated here" } */
      53  } /* { dg-warning "leak of 'arr\\\[i\\\].m_arr\\\[j\\\]'" } */
      54  
      55  
      56  /* Example involving fields.  */
      57  
      58  struct s3
      59  {
      60    struct s3 *m_left;
      61    struct s3 *m_right;  
      62  };
      63  
      64  void test_3 (void)
      65  {
      66    struct s3 *a = malloc (sizeof (struct s3));
      67    a->m_right = malloc (sizeof (struct s3)); /* { dg-warning "dereference of possibly-NULL 'a'" } */
      68    a->m_right->m_left = malloc (sizeof (struct s3)); /* { dg-warning "dereference of possibly-NULL '\\*a.m_right'" } */
      69  } /* { dg-warning "leak of 'a'" "leak of a" } */
      70  /* { dg-warning "leak of '<unknown>'" "leak of unknown" { target *-*-* } .-1 } */
      71  /* TODO: rather than '<unknown>', we should print 'a->m_right'
      72     and 'a->m_right->m_left' (PR analyzer/99771).  */
      73  
      74  
      75  /* Example involving faking inheritance via casts.  */
      76  
      77  struct s4_base
      78  {
      79    int m_placeholder;
      80  };
      81  
      82  struct s4_sub
      83  {
      84    void *m_buffer;
      85  };
      86  
      87  static struct s4_sub *
      88  make_s4_sub (void)
      89  {
      90    struct s4_sub *sub = malloc (sizeof (struct s4_sub)); /* { dg-message "allocated here" } */
      91    if (!sub)
      92      return NULL;
      93    sub->m_buffer = malloc (1024); /* { dg-message "allocated here" } */
      94    return sub;
      95  }
      96  
      97  void test_4 (void)
      98  {
      99    struct s4_base *base = (struct s4_base *)make_s4_sub ();
     100  } /* { dg-warning "leak of 'base'" "leak of base" } */
     101  /* { dg-warning "leak of '<unknown>'" "leak of sub buffer" { target *-*-* } .-1 } */
     102  /* TODO: rather than 'unknown', we should print something
     103     like '((struct s4_sub *)base)->m_buffer' (PR analyzer/99771).  */