(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
analyzer/
malloc-paths-9.c
       1  /* { dg-additional-options "-fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */
       2  /* { dg-enable-nn-line-numbers "" } */
       3  
       4  #include <stdlib.h>
       5  
       6  void test_1 (void)
       7  {
       8    void *ptr = malloc (1024);
       9    free (ptr);
      10    free (ptr); /* { dg-warning "double-'free' of 'ptr'"  } */
      11  }
      12  /* { dg-begin-multiline-output "" }
      13     NN |   free (ptr);
      14        |   ^~~~~~~~~~
      15    'test_1': events 1-3
      16      |
      17      |   NN |   void *ptr = malloc (1024);
      18      |      |               ^~~~~~~~~~~~~
      19      |      |               |
      20      |      |               (1) allocated here
      21      |   NN |   free (ptr);
      22      |      |   ~~~~~~~~~~   
      23      |      |   |
      24      |      |   (2) first 'free' here
      25      |   NN |   free (ptr);
      26      |      |   ~~~~~~~~~~   
      27      |      |   |
      28      |      |   (3) second 'free' here; first 'free' was at (2)
      29      |
      30     { dg-end-multiline-output "" } */
      31  
      32  void test_2 (int x, int y)
      33  {
      34    void *ptr = malloc (1024);
      35    if (x)
      36      free (ptr);
      37    if (y)
      38      free (ptr); /* { dg-warning "double-'free' of 'ptr'"  } */
      39  } /* { dg-warning "leak of 'ptr'"  } */
      40  
      41  /* "double-'free' of 'ptr'".  */
      42  /* { dg-begin-multiline-output "" }
      43     NN |     free (ptr);
      44        |     ^~~~~~~~~~
      45    'test_2': events 1-7
      46      |
      47      |   NN |   void *ptr = malloc (1024);
      48      |      |               ^~~~~~~~~~~~~
      49      |      |               |
      50      |      |               (1) allocated here
      51      |   NN |   if (x)
      52      |      |      ~         
      53      |      |      |
      54      |      |      (2) following 'true' branch (when 'x != 0')...
      55      |   NN |     free (ptr);
      56      |      |     ~~~~~~~~~~ 
      57      |      |     |
      58      |      |     (3) ...to here
      59      |      |     (4) first 'free' here
      60      |   NN |   if (y)
      61      |      |      ~         
      62      |      |      |
      63      |      |      (5) following 'true' branch (when 'y != 0')...
      64      |   NN |     free (ptr);
      65      |      |     ~~~~~~~~~~ 
      66      |      |     |
      67      |      |     (6) ...to here
      68      |      |     (7) second 'free' here; first 'free' was at (4)
      69      |
      70     { dg-end-multiline-output "" } */
      71  
      72  /* "leak of 'ptr'.  */
      73  /* { dg-begin-multiline-output "" }
      74     NN | }
      75        | ^
      76    'test_2': events 1-6
      77      |
      78      |   NN |   void *ptr = malloc (1024);
      79      |      |               ^~~~~~~~~~~~~
      80      |      |               |
      81      |      |               (1) allocated here
      82      |   NN |   if (x)
      83      |      |      ~         
      84      |      |      |
      85      |      |      (2) following 'false' branch (when 'x == 0')...
      86      |   NN |     free (ptr);
      87      |   NN |   if (y)
      88      |      |      ~         
      89      |      |      |
      90      |      |      (3) ...to here
      91      |      |      (4) following 'false' branch (when 'y == 0')...
      92      |   NN |     free (ptr);
      93      |   NN | }
      94      |      | ~              
      95      |      | |
      96      |      | (5) ...to here
      97      |      | (6) 'ptr' leaks here; was allocated at (1)
      98      |
      99     { dg-end-multiline-output "" } */
     100  
     101  int test_3 (int x, int y)
     102  {
     103    int *ptr = (int *)malloc (sizeof (int));
     104    *ptr = 42; /* { dg-warning "dereference of possibly-NULL 'ptr'" } */
     105    if (x)
     106      free (ptr);
     107  
     108    *ptr = 19; /* { dg-warning "use after 'free' of 'ptr'" } */
     109    // TODO: two warnings here:  one is from sm-malloc, the other from region model
     110  
     111    if (y)
     112      free (ptr); /* No double-'free' warning: we've already attempted
     113  		   to dereference it above.  */
     114    return *ptr; /* { dg-warning "use after 'free' of 'ptr'" "use-after-free" } */
     115    /* { dg-warning "leak of 'ptr'" "leak" { target *-*-* } .-1 } */
     116  }
     117  
     118  /* "dereference of possibly-NULL 'ptr'".  */
     119  /* { dg-begin-multiline-output "" }
     120     NN |   *ptr = 42;
     121        |   ~~~~~^~~~
     122    'test_3': events 1-2
     123      |
     124      |   NN |   int *ptr = (int *)malloc (sizeof (int));
     125      |      |                     ^~~~~~~~~~~~~~~~~~~~~
     126      |      |                     |
     127      |      |                     (1) this call could return NULL
     128      |   NN |   *ptr = 42;
     129      |      |   ~~~~~~~~~          
     130      |      |        |
     131      |      |        (2) 'ptr' could be NULL: unchecked value from (1)
     132      |
     133     { dg-end-multiline-output "" } */
     134  
     135  /* "use after 'free' of 'ptr'".  */
     136  /* { dg-begin-multiline-output "" }
     137     NN |   *ptr = 19;
     138        |   ~~~~~^~~~
     139    'test_3': events 1-6
     140      |
     141      |   NN |   int *ptr = (int *)malloc (sizeof (int));
     142      |      |                     ^~~~~~~~~~~~~~~~~~~~~
     143      |      |                     |
     144      |      |                     (1) allocated here
     145      |   NN |   *ptr = 42;
     146      |      |   ~~~~~~~~~          
     147      |      |        |
     148      |      |        (2) assuming 'ptr' is non-NULL
     149      |   NN |   if (x)
     150      |      |      ~               
     151      |      |      |
     152      |      |      (3) following 'true' branch (when 'x != 0')...
     153      |   NN |     free (ptr);
     154      |      |     ~~~~~~~~~~       
     155      |      |     |
     156      |      |     (4) ...to here
     157      |      |     (5) freed here
     158      |   NN | 
     159      |   NN |   *ptr = 19;
     160      |      |   ~~~~~~~~~          
     161      |      |        |
     162      |      |        (6) use after 'free' of 'ptr'; freed at (5)
     163      |
     164     { dg-end-multiline-output "" } */
     165  
     166  /* "use after 'free' of 'ptr'".  */
     167  /* { dg-begin-multiline-output "" }
     168     NN |   return *ptr;
     169        |          ^~~~
     170    'test_3': events 1-8
     171      |
     172      |   NN |   int *ptr = (int *)malloc (sizeof (int));
     173      |      |                     ^~~~~~~~~~~~~~~~~~~~~
     174      |      |                     |
     175      |      |                     (1) allocated here
     176      |   NN |   *ptr = 42;
     177      |      |   ~~~~~~~~~          
     178      |      |        |
     179      |      |        (2) assuming 'ptr' is non-NULL
     180      |   NN |   if (x)
     181      |      |      ~               
     182      |      |      |
     183      |      |      (3) following 'false' branch (when 'x == 0')...
     184      |......
     185      |   NN |   *ptr = 19;
     186      |      |   ~~~~~~~~~          
     187      |      |        |
     188      |      |        (4) ...to here
     189      |......
     190      |   NN |   if (y)
     191      |      |      ~               
     192      |      |      |
     193      |      |      (5) following 'true' branch (when 'y != 0')...
     194      |   NN |     free (ptr);
     195      |      |     ~~~~~~~~~~       
     196      |      |     |
     197      |      |     (6) ...to here
     198      |      |     (7) freed here
     199      |   NN |      
     200      |   NN |   return *ptr;
     201      |      |          ~~~~        
     202      |      |          |
     203      |      |          (8) use after 'free' of 'ptr'; freed at (7)
     204      |
     205     { dg-end-multiline-output "" } */
     206  
     207  /* "leak of 'ptr'".  */
     208  /* { dg-begin-multiline-output "" }
     209     NN |   return *ptr;
     210        |          ^~~~
     211    'test_3': events 1-7
     212      |
     213      |   NN |   int *ptr = (int *)malloc (sizeof (int));
     214      |      |                     ^~~~~~~~~~~~~~~~~~~~~
     215      |      |                     |
     216      |      |                     (1) allocated here
     217      |   NN |   *ptr = 42;
     218      |      |   ~~~~~~~~~          
     219      |      |        |
     220      |      |        (2) assuming 'ptr' is non-NULL
     221      |   NN |   if (x)
     222      |      |      ~               
     223      |      |      |
     224      |      |      (3) following 'false' branch (when 'x == 0')...
     225      |......
     226      |   NN |   *ptr = 19;
     227      |      |   ~~~~~~~~~          
     228      |      |        |
     229      |      |        (4) ...to here
     230      |......
     231      |   NN |   if (y)
     232      |      |      ~               
     233      |      |      |
     234      |      |      (5) following 'false' branch (when 'y == 0')...
     235      |......
     236      |   NN |   return *ptr;
     237      |      |          ~~~~        
     238      |      |          |
     239      |      |          (6) ...to here
     240      |      |          (7) 'ptr' leaks here; was allocated at (1)
     241      |
     242     { dg-end-multiline-output "" } */