c++: only cache constexpr calls that are constant exprs
[official-gcc.git] / gcc / analyzer / sm-fd.dot
blobc07fd3b72bbe2755bd370f04f04791a6d7b58713
1 /* An overview of the state machine from sm-fd.cc.
2 Copyright (C) 2022-2023 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
5 This file is part of GCC.
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.
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.
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/>. */
21 /* Keep this in-sync with sm-fd.cc */
23 digraph "fd" {
25 /* STATES. */
27 /* Start state. */
28 start;
30 /* State for a constant file descriptor (>= 0). */
31 constant_fd;
33 /* States representing a file descriptor that hasn't yet been
34 checked for validity after opening, for three different
35 access modes. */
36 unchecked_read_write;
37 unchecked_read_only;
38 unchecked_write_only;
40 /* States for representing a file descriptor that is known to be valid (>=
41 0), for three different access modes. */
42 valid_read_write;
43 valid_read_only;
44 valid_write_only;
46 /* State for a file descriptor that is known to be invalid (< 0). */
47 invalid;
49 /* State for a file descriptor that has been closed. */
50 closed;
52 /* States for FDs relating to socket APIs. */
54 /* Result of successful "socket" with SOCK_DGRAM. */
55 new_datagram_socket;
56 /* Result of successful "socket" with SOCK_STREAM. */
57 new_stream_socket;
58 /* Result of successful "socket" with unknown type. */
59 new_unknown_socket;
61 /* The above after a successful call to "bind". */
62 bound_datagram_socket;
63 bound_stream_socket;
64 bound_unknown_socket;
66 /* A bound socket after a successful call to "listen" (stream or unknown). */
67 listening_stream_socket;
69 /* (i) the new FD as a result of a succesful call to "accept" on a
70 listening socket (via a passive open), or
71 (ii) an active socket after a successful call to "connect"
72 (via an active open). */
73 connected_stream_socket;
75 /* State for a file descriptor that we do not want to track anymore . */
76 stop;
78 /* TRANSITIONS. */
80 /* On "open". */
81 start -> unchecked_read_only [label="on 'X = open(..., O_RDONLY);'"];
82 start -> unchecked_write_only [label="on 'X = open(..., O_WRONLY);'"];
83 start -> unchecked_read_write [label="on 'X = open(..., ...);'"];
85 /* On "creat". */
86 start -> unchecked_write_only [label="on 'X = create(...);'"];
88 /* On "close". */
89 start -> closed [label="on 'close(X);'"];
90 unchecked_read_write -> closed [label="on 'close(X);'"];
91 unchecked_read_only -> closed [label="on 'close(X);'"];
92 unchecked_write_only -> closed [label="on 'close(X);'"];
93 valid_read_write -> closed [label="on 'close(X);'"];
94 valid_read_only -> closed [label="on 'close(X);'"];
95 valid_write_only -> closed [label="on 'close(X);'"];
96 constant_fd -> closed [label="on 'close(X);'"];
97 new_datagram_socket -> closed [label="on 'close(X);'"];
98 new_stream_socket -> closed [label="on 'close(X);'"];
99 new_unknown_socket -> closed [label="on 'close(X);'"];
100 bound_datagram_socket -> closed [label="on 'close(X);'"];
101 bound_stream_socket -> closed [label="on 'close(X);'"];
102 bound_unknown_socket -> closed [label="on 'close(X);'"];
103 listening_stream_socket -> closed [label="on 'close(X);'"];
104 connected_stream_socket -> closed [label="on 'close(X);'"];
105 closed -> stop [label="on 'close(X);':\nWarn('double close')"];
107 /* On "read". */
108 closed -> closed [label="on 'read(X);':\nWarn('use after close')"];
109 unchecked_read_write -> unchecked_read_write [label="on 'read(X);:\nWarn('use without check')'"];
110 unchecked_read_only -> unchecked_read_only [label="on 'read(X);:\nWarn('use without check')'"];
111 unchecked_write_only -> unchecked_write_only [label="on 'read(X);:\nWarn('use without check')'"];
112 valid_write_only -> valid_write_only [label="on 'read(X);:\nWarn('access mode mismatch')'"];
114 /* On "write". */
115 closed -> closed [label="on 'write(X);':\nWarn('use after close')"];
116 unchecked_read_write -> unchecked_read_write [label="on 'write(X);:\nWarn('use without check')'"];
117 unchecked_read_only -> unchecked_read_only [label="on 'write(X);:\nWarn('use without check')'"];
118 unchecked_write_only -> unchecked_write_only [label="on 'write(X);:\nWarn('use without check')'"];
119 valid_read_only -> valid_read_only [label="on 'write(X);:\nWarn('access mode mismatch')'"];
121 /* On "dup". */
122 closed -> closed [label="on 'dup(X);':\nWarn('use after close')"];
123 /* plus stuff for the new fd. */
125 /* On "pipe". */
126 start -> valid_read_write [label="when 'pipe()' succeeds"];
128 /* On "socket". */
129 start -> new_datagram_socket [label="when 'socket(..., SOCK_DGRAM, ...)' succeeds"];
130 start -> new_stream_socket [label="when 'socket(..., SOCK_STREAM, ...)' succeeds"];
131 start -> new_unknown_socket [label="when 'socket(..., ..., ...)' succeeds"];
133 /* On "bind". */
134 start -> bound_unknown_socket [label="when 'bind(X, ...)' succeeds"];
135 constant_fd -> bound_unknown_socket [label="when 'bind(X, ...)' succeeds"];
136 new_stream_socket -> bound_stream_socket [label="when 'bind(X, ...)' succeeds"];
137 new_datagram_socket -> bound_datagram_socket [label="when 'bind(X, ...)' succeeds"];
138 new_unknown_socket -> bound_unknown_socket [label="when 'bind(X, ...)' succeeds"];
140 /* On "listen". */
141 start -> listening_stream_socket [label="when 'listen(X, ...)' succeeds"];
142 bound_stream_socket -> listening_stream_socket [label="when 'listen(X, ...)' succeeds"];
143 bound_unknown_socket -> listening_stream_socket [label="when 'listen(X, ...)' succeeds"];
145 /* On "accept". */
146 start -> connected_stream_socket [label="when 'accept(OTHER, ...)' succeeds on a listening_stream_socket"];
147 constant_fd -> connected_stream_socket [label="when 'accept(OTHER, ...)' succeeds on a listening_stream_socket"];
149 /* On "connect". */
150 new_stream_socket -> connected_stream_socket [label="when 'connect(X, ...)' succeeds"];
151 new_datagram_socket -> new_datagram_socket [label="when 'connect(X, ...)' succeeds"];
152 new_unknown_socket -> stop [label="when 'connect(X, ...)' succeeds"];
153 start -> stop [label="when 'connect(X, ...)' succeeds"];
154 constant_fd -> stop [label="when 'connect(X, ...)' succeeds"];
156 /* on_condition. */
157 unchecked_read_write -> valid_read_write [label="on 'X >= 0'"];
158 unchecked_read_only -> valid_read_only [label="on 'X >= 0'"];
159 unchecked_write_only -> valid_write_only [label="on 'X >= 0'"];
160 unchecked_read_write -> invalid [label="on 'X < 0'"];
161 unchecked_read_only -> invalid [label="on 'X < 0'"];
162 unchecked_write_only -> invalid [label="on 'X < 0'"];
164 /* Leaks. */
165 unchecked_read_write -> stop [label="on leak:\nWarn('leak')"];
166 unchecked_read_only -> stop [label="on leak:\nWarn('leak')"];
167 unchecked_write_only -> stop [label="on leak:\nWarn('leak')"];
168 valid_read_write -> stop [label="on leak:\nWarn('leak')"];
169 valid_read_only -> stop [label="on leak:\nWarn('leak')"];
170 valid_write_only -> stop [label="on leak:\nWarn('leak')"];
171 new_datagram_socket -> stop [label="on leak:\nWarn('leak')"];
172 new_stream_socket -> stop [label="on leak:\nWarn('leak')"];
173 new_unknown_socket -> stop [label="on leak:\nWarn('leak')"];
174 bound_datagram_socket -> stop [label="on leak:\nWarn('leak')"];
175 bound_stream_socket -> stop [label="on leak:\nWarn('leak')"];
176 bound_unknown_socket -> stop [label="on leak:\nWarn('leak')"];
177 listening_stream_socket -> stop [label="on leak:\nWarn('leak')"];
178 connected_stream_socket -> stop [label="on leak:\nWarn('leak')"];