https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88737
--- Comment #8 from Eric Gallager <egallager at gcc dot gnu.org> ---
(In reply to Neal H. Walfield from comment #0)
> I would like an attribute to indicate that ownership of an argument is moved
> to the function. That is, any subsequent accesses to the variable should be
> considered invalid, and gcc should emit a warning, if possible.
>
> Consider the following example:
>
> ```
> #include <stdlib.h>
> #include <stdio.h>
>
> int
> main(int argc, char *argv[]) {
> int *a = malloc(sizeof(int));
> *a = 1;
> printf("%d\n", *a);
> free(a);
> printf("%d\n", *a);
>
> return 0;
> }
> ```
>
> Compiling this with -Wall (using gcc 6.3.0-18+deb9u1 from Debian) does not
> emit a warning even though there is a use-after-free bug.
>
> Although freeing a variable is the most obvious example of this pattern,
> this pattern often arises when dealing with pointers.
>
> This RFE is based on my experience using Rust's lifetimes, which prevent
> this type of error in Rust.
I tested this with David Malcolm's static analyzer branch on Godbolt and it
catches it: https://godbolt.org/z/LWzGA5
Output:
<source>: In function 'main':
<source>:7:6: warning: dereference of possibly-NULL 'a' [CWE-690]
[-Wanalyzer-possible-null-dereference]
7 | *a = 1;
| ~~~^~~
'main': events 1-2
|
| 6 | int *a = malloc(sizeof(int));
| | ^~~~~~~~~~~~~~~~~~~
| | |
| | (1) this call could return NULL
| 7 | *a = 1;
| | ~~~~~~
| | |
| | (2) 'a' could be NULL: unchecked value from (1)
|
<source>:10:3: warning: use after 'free' of 'a' [CWE-416]
[-Wanalyzer-use-after-free]
10 | printf("%d\n", *a);
| ^~~~~~~~~~~~~~~~~~
'main': events 1-4
|
| 6 | int *a = malloc(sizeof(int));
| | ^~~~~~~~~~~~~~~~~~~
| | |
| | (1) allocated here
| 7 | *a = 1;
| | ~~~~~~
| | |
| | (2) assuming 'a' is non-NULL
| 8 | printf("%d\n", *a);
| | ~~~~~~~~~~~~~~~~~~
| | |
| | (3) freed here
| 9 | free(a);
| 10 | printf("%d\n", *a);
| | ~~~~~~~~~~~~~~~~~~
| | |
| | (4) use after 'free' of 'a'; freed at (3)
|
<source>:10:3: warning: use after 'free' of 'a' [CWE-416]
[-Wanalyzer-use-after-free]
10 | printf("%d\n", *a);
| ^~~~~~~~~~~~~~~~~~
'main': event 1
|
|
Compiler returned: 0