blob: a3cacc07fab5e9a607bab3c358f4bc26ea17ffbd [file] [log] [blame]
/* { dg-additional-options "-fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */
/* { dg-enable-nn-line-numbers "" } */
#include <stdlib.h>
void test_1 (void)
{
void *ptr = malloc (1024);
free (ptr);
free (ptr); /* { dg-warning "double-'free' of 'ptr'" } */
}
/* { dg-begin-multiline-output "" }
NN | free (ptr);
| ^~~~~~~~~~
'test_1': events 1-3
|
| NN | void *ptr = malloc (1024);
| | ^~~~~~~~~~~~~
| | |
| | (1) allocated here
| NN | free (ptr);
| | ~~~~~~~~~~
| | |
| | (2) first 'free' here
| NN | free (ptr);
| | ~~~~~~~~~~
| | |
| | (3) second 'free' here; first 'free' was at (2)
|
{ dg-end-multiline-output "" } */
void test_2 (int x, int y)
{
void *ptr = malloc (1024);
if (x)
free (ptr);
if (y)
free (ptr); /* { dg-warning "double-'free' of 'ptr'" } */
} /* { dg-warning "leak of 'ptr'" } */
/* "double-'free' of 'ptr'". */
/* { dg-begin-multiline-output "" }
NN | free (ptr);
| ^~~~~~~~~~
'test_2': events 1-7
|
| NN | void *ptr = malloc (1024);
| | ^~~~~~~~~~~~~
| | |
| | (1) allocated here
| NN | if (x)
| | ~
| | |
| | (2) following 'true' branch (when 'x != 0')...
| NN | free (ptr);
| | ~~~~~~~~~~
| | |
| | (3) ...to here
| | (4) first 'free' here
| NN | if (y)
| | ~
| | |
| | (5) following 'true' branch (when 'y != 0')...
| NN | free (ptr);
| | ~~~~~~~~~~
| | |
| | (6) ...to here
| | (7) second 'free' here; first 'free' was at (4)
|
{ dg-end-multiline-output "" } */
/* "leak of 'ptr'. */
/* { dg-begin-multiline-output "" }
NN | }
| ^
'test_2': events 1-6
|
| NN | void *ptr = malloc (1024);
| | ^~~~~~~~~~~~~
| | |
| | (1) allocated here
| NN | if (x)
| | ~
| | |
| | (2) following 'false' branch (when 'x == 0')...
| NN | free (ptr);
| NN | if (y)
| | ~
| | |
| | (3) ...to here
| | (4) following 'false' branch (when 'y == 0')...
| NN | free (ptr);
| NN | }
| | ~
| | |
| | (5) ...to here
| | (6) 'ptr' leaks here; was allocated at (1)
|
{ dg-end-multiline-output "" } */
int test_3 (int x, int y)
{
int *ptr = (int *)malloc (sizeof (int));
*ptr = 42; /* { dg-warning "dereference of possibly-NULL 'ptr'" } */
if (x)
free (ptr);
*ptr = 19; /* { dg-warning "use after 'free' of 'ptr'" } */
// TODO: two warnings here: one is from sm-malloc, the other from region model
if (y)
free (ptr); /* No double-'free' warning: we've already attempted
to dereference it above. */
return *ptr; /* { dg-warning "use after 'free' of 'ptr'" "use-after-free" } */
/* { dg-warning "leak of 'ptr'" "leak" { target *-*-* } .-1 } */
}
/* "dereference of possibly-NULL 'ptr'". */
/* { dg-begin-multiline-output "" }
NN | *ptr = 42;
| ~~~~~^~~~
'test_3': events 1-2
|
| NN | int *ptr = (int *)malloc (sizeof (int));
| | ^~~~~~~~~~~~~~~~~~~~~
| | |
| | (1) this call could return NULL
| NN | *ptr = 42;
| | ~~~~~~~~~
| | |
| | (2) 'ptr' could be NULL: unchecked value from (1)
|
{ dg-end-multiline-output "" } */
/* "use after 'free' of 'ptr'". */
/* { dg-begin-multiline-output "" }
NN | *ptr = 19;
| ~~~~~^~~~
'test_3': events 1-6
|
| NN | int *ptr = (int *)malloc (sizeof (int));
| | ^~~~~~~~~~~~~~~~~~~~~
| | |
| | (1) allocated here
| NN | *ptr = 42;
| | ~~~~~~~~~
| | |
| | (2) assuming 'ptr' is non-NULL
| NN | if (x)
| | ~
| | |
| | (3) following 'true' branch (when 'x != 0')...
| NN | free (ptr);
| | ~~~~~~~~~~
| | |
| | (4) ...to here
| | (5) freed here
| NN |
| NN | *ptr = 19;
| | ~~~~~~~~~
| | |
| | (6) use after 'free' of 'ptr'; freed at (5)
|
{ dg-end-multiline-output "" } */
/* "use after 'free' of 'ptr'". */
/* { dg-begin-multiline-output "" }
NN | return *ptr;
| ^~~~
'test_3': events 1-8
|
| NN | int *ptr = (int *)malloc (sizeof (int));
| | ^~~~~~~~~~~~~~~~~~~~~
| | |
| | (1) allocated here
| NN | *ptr = 42;
| | ~~~~~~~~~
| | |
| | (2) assuming 'ptr' is non-NULL
| NN | if (x)
| | ~
| | |
| | (3) following 'false' branch (when 'x == 0')...
|......
| NN | *ptr = 19;
| | ~~~~~~~~~
| | |
| | (4) ...to here
|......
| NN | if (y)
| | ~
| | |
| | (5) following 'true' branch (when 'y != 0')...
| NN | free (ptr);
| | ~~~~~~~~~~
| | |
| | (6) ...to here
| | (7) freed here
| NN |
| NN | return *ptr;
| | ~~~~
| | |
| | (8) use after 'free' of 'ptr'; freed at (7)
|
{ dg-end-multiline-output "" } */
/* "leak of 'ptr'". */
/* { dg-begin-multiline-output "" }
NN | return *ptr;
| ^~~~
'test_3': events 1-7
|
| NN | int *ptr = (int *)malloc (sizeof (int));
| | ^~~~~~~~~~~~~~~~~~~~~
| | |
| | (1) allocated here
| NN | *ptr = 42;
| | ~~~~~~~~~
| | |
| | (2) assuming 'ptr' is non-NULL
| NN | if (x)
| | ~
| | |
| | (3) following 'false' branch (when 'x == 0')...
|......
| NN | *ptr = 19;
| | ~~~~~~~~~
| | |
| | (4) ...to here
|......
| NN | if (y)
| | ~
| | |
| | (5) following 'false' branch (when 'y == 0')...
|......
| NN | return *ptr;
| | ~~~~
| | |
| | (6) ...to here
| | (7) 'ptr' leaks here; was allocated at (1)
|
{ dg-end-multiline-output "" } */