xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/analyzer/sm-malloc.dot (revision 0a3071956a3a9fdebdbf7f338cf2d439b45fc728)
1/* An overview of the state machine from sm-malloc.cc.
2   Copyright (C) 2019-2020 Free Software Foundation, Inc.
3   Contributed by David Malcolm <dmalcolm@redhat.com>.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it
8under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GCC is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along 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
23digraph "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}
90