]>
Commit | Line | Data |
---|---|---|
757bf1df | 1 | /* An overview of the state machine from sm-malloc.cc. |
7adcbafe | 2 | Copyright (C) 2019-2022 Free Software Foundation, Inc. |
757bf1df DM |
3 | Contributed by David Malcolm <dmalcolm@redhat.com>. |
4 | ||
5 | This file is part of GCC. | |
6 | ||
7 | GCC is free software; you can redistribute it and/or modify it | |
8 | under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 3, or (at your option) | |
10 | any later version. | |
11 | ||
12 | GCC is distributed in the hope that it will be useful, but | |
13 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with GCC; see the file COPYING3. If not see | |
19 | <http://www.gnu.org/licenses/>. */ | |
20 | ||
21 | /* Keep this in-sync with sm-malloc.cc */ | |
22 | ||
23 | digraph "malloc" { | |
24 | ||
25 | /* STATES. */ | |
26 | ||
27 | /* Start state. */ | |
28 | start; | |
29 | ||
30 | /* State for a pointer returned from malloc that hasn't been checked for | |
31 | NULL. | |
32 | It could be a pointer to heap-allocated memory, or could be NULL. */ | |
33 | unchecked; | |
34 | ||
35 | /* State for a pointer that's known to be NULL. */ | |
36 | null; | |
37 | ||
38 | /* State for a pointer to heap-allocated memory, known to be non-NULL. */ | |
39 | nonnull; | |
40 | ||
41 | /* State for a pointer to freed memory. */ | |
42 | freed; | |
43 | ||
44 | /* State for a pointer that's known to not be on the heap (e.g. to a local | |
45 | or global). */ | |
46 | non_heap; | |
47 | ||
48 | /* Stop state, for pointers we don't want to track any more. */ | |
49 | stop; | |
50 | ||
51 | /* TRANSITIONS. */ | |
52 | ||
53 | start -> unchecked [label="on 'X=malloc(...);'"]; | |
54 | start -> unchecked [label="on 'X=calloc(...);'"]; | |
55 | ||
56 | start -> non_heap [label="on 'X=alloca(...);'"]; | |
57 | start -> non_heap [label="on 'X=__builtin_alloca(...);'"]; | |
58 | ||
59 | /* On "free". */ | |
60 | start -> freed [label="on 'free(X);'"]; | |
61 | unchecked -> freed [label="on 'free(X);'"]; | |
62 | nonnull -> freed [label="on 'free(X);'"]; | |
63 | freed -> stop [label="on 'free(X);':\n Warn('double-free')"]; | |
64 | non_heap -> stop [label="on 'free(X);':\n Warn('free of non-heap')"]; | |
65 | ||
66 | /* Handle "__attribute__((nonnull))". */ | |
67 | unchecked -> nonnull [label="on 'FN(X)' with __attribute__((nonnull)):\nWarn('possible NULL arg')"]; | |
68 | null -> stop [label="on 'FN(X)' with __attribute__((nonnull)):\nWarn('NULL arg')"]; | |
69 | ||
70 | /* is_zero_assignment. */ | |
71 | start -> null [label="on 'X = 0;'"]; | |
72 | unchecked -> null [label="on 'X = 0;'"]; | |
73 | nonnull -> null [label="on 'X = 0;'"]; | |
74 | freed -> null [label="on 'X = 0;'"]; | |
75 | ||
76 | start -> non_heap [label="on 'X = &EXPR;'"]; | |
77 | ||
78 | /* Handle dereferences. */ | |
79 | unchecked -> nonnull [label="on '*X':\nWarn('possible NULL deref')"]; | |
80 | null -> stop [label="on '*X':\nWarn('NULL deref')"]; | |
81 | freed -> stop [label="on '*X':\nWarn('use after free')"]; | |
82 | ||
83 | /* on_condition. */ | |
84 | unchecked -> nonnull [label="on 'X != 0'"]; | |
85 | unchecked -> null [label="on 'X == 0'"]; | |
86 | ||
87 | unchecked -> stop [label="on leak:\nWarn('leak')"]; | |
88 | nonnull -> stop [label="on leak:\nWarn('leak')"]; | |
89 | } |