]>
Commit | Line | Data |
---|---|---|
7036e9ef MS |
1 | /* Functions to enable and disable individual warnings on an expression |
2 | and statement basis. | |
3 | ||
7adcbafe | 4 | Copyright (C) 2021-2022 Free Software Foundation, Inc. |
7036e9ef MS |
5 | |
6 | This file is part of GCC. | |
7 | ||
8 | GCC is free software; you can redistribute it and/or modify it under | |
9 | the terms of the GNU General Public License as published by the Free | |
10 | Software Foundation; either version 3, or (at your option) any later | |
11 | version. | |
12 | ||
13 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
14 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 | for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
19 | along with GCC; see the file COPYING3. If not see | |
20 | <http://www.gnu.org/licenses/>. */ | |
21 | ||
22 | #include "config.h" | |
23 | #include "system.h" | |
24 | #include "coretypes.h" | |
25 | #include "backend.h" | |
26 | #include "bitmap.h" | |
27 | #include "tree.h" | |
28 | #include "gimple.h" | |
29 | #include "cgraph.h" | |
30 | #include "hash-map.h" | |
31 | #include "diagnostic-spec.h" | |
32 | ||
33 | /* Return the no-warning bit for EXPR. */ | |
34 | ||
35 | static inline bool | |
36 | get_no_warning_bit (const_tree expr) | |
37 | { | |
38 | return expr->base.nowarning_flag; | |
39 | } | |
40 | ||
41 | /* Return the no-warning bit for statement STMT. */ | |
42 | ||
43 | static inline bool | |
44 | get_no_warning_bit (const gimple *stmt) | |
45 | { | |
46 | return stmt->no_warning; | |
47 | } | |
48 | ||
49 | /* Set the no-warning bit for EXPR to VALUE. */ | |
50 | ||
51 | static inline void | |
52 | set_no_warning_bit (tree expr, bool value) | |
53 | { | |
54 | expr->base.nowarning_flag = value; | |
55 | } | |
56 | ||
57 | /* Set the no-warning bit for statement STMT to VALUE. */ | |
58 | ||
59 | static inline void | |
60 | set_no_warning_bit (gimple *stmt, bool value) | |
61 | { | |
62 | stmt->no_warning = value; | |
63 | } | |
64 | ||
19853922 | 65 | /* Return EXPR location or 'UNKNOWN_LOCATION'. */ |
7036e9ef | 66 | |
19853922 TS |
67 | static inline location_t |
68 | get_location (const_tree expr) | |
7036e9ef MS |
69 | { |
70 | if (DECL_P (expr)) | |
71 | return DECL_SOURCE_LOCATION (expr); | |
72 | if (EXPR_P (expr)) | |
73 | return EXPR_LOCATION (expr); | |
19853922 | 74 | return UNKNOWN_LOCATION; |
7036e9ef MS |
75 | } |
76 | ||
19853922 | 77 | /* Return STMT location (may be 'UNKNOWN_LOCATION'). */ |
7036e9ef | 78 | |
19853922 TS |
79 | static inline location_t |
80 | get_location (const gimple *stmt) | |
7036e9ef MS |
81 | { |
82 | return gimple_location (stmt); | |
83 | } | |
84 | ||
85 | /* Return the no-warning bitmap for decl/expression EXPR. */ | |
86 | ||
87 | static nowarn_spec_t * | |
88 | get_nowarn_spec (const_tree expr) | |
89 | { | |
19853922 | 90 | const location_t loc = get_location (expr); |
7036e9ef | 91 | |
6c79057f | 92 | if (RESERVED_LOCATION_P (loc)) |
7036e9ef MS |
93 | return NULL; |
94 | ||
19853922 TS |
95 | if (!get_no_warning_bit (expr)) |
96 | return NULL; | |
97 | ||
98 | return nowarn_map ? nowarn_map->get (loc) : NULL; | |
7036e9ef MS |
99 | } |
100 | ||
873b36af | 101 | /* Return the no-warning bitmap for statement STMT. */ |
7036e9ef MS |
102 | |
103 | static nowarn_spec_t * | |
104 | get_nowarn_spec (const gimple *stmt) | |
105 | { | |
19853922 | 106 | const location_t loc = get_location (stmt); |
7036e9ef | 107 | |
6c79057f TS |
108 | if (RESERVED_LOCATION_P (loc)) |
109 | return NULL; | |
110 | ||
7036e9ef MS |
111 | if (!get_no_warning_bit (stmt)) |
112 | return NULL; | |
113 | ||
19853922 | 114 | return nowarn_map ? nowarn_map->get (loc) : NULL; |
7036e9ef MS |
115 | } |
116 | ||
117 | /* Return true if warning OPT is suppressed for decl/expression EXPR. | |
118 | By default tests the disposition for any warning. */ | |
119 | ||
120 | bool | |
121 | warning_suppressed_p (const_tree expr, opt_code opt /* = all_warnings */) | |
122 | { | |
123 | const nowarn_spec_t *spec = get_nowarn_spec (expr); | |
124 | ||
125 | if (!spec) | |
126 | return get_no_warning_bit (expr); | |
127 | ||
128 | const nowarn_spec_t optspec (opt); | |
129 | bool dis = *spec & optspec; | |
130 | gcc_assert (get_no_warning_bit (expr) || !dis); | |
131 | return dis; | |
132 | } | |
133 | ||
134 | /* Return true if warning OPT is suppressed for statement STMT. | |
135 | By default tests the disposition for any warning. */ | |
136 | ||
137 | bool | |
138 | warning_suppressed_p (const gimple *stmt, opt_code opt /* = all_warnings */) | |
139 | { | |
140 | const nowarn_spec_t *spec = get_nowarn_spec (stmt); | |
141 | ||
142 | if (!spec) | |
143 | /* Fall back on the single no-warning bit. */ | |
144 | return get_no_warning_bit (stmt); | |
145 | ||
146 | const nowarn_spec_t optspec (opt); | |
147 | bool dis = *spec & optspec; | |
148 | gcc_assert (get_no_warning_bit (stmt) || !dis); | |
149 | return dis; | |
150 | } | |
151 | ||
152 | /* Enable, or by default disable, a warning for the expression. | |
153 | The wildcard OPT of -1 controls all warnings. */ | |
154 | ||
155 | void | |
156 | suppress_warning (tree expr, opt_code opt /* = all_warnings */, | |
157 | bool supp /* = true */) | |
158 | { | |
159 | if (opt == no_warning) | |
160 | return; | |
161 | ||
19853922 | 162 | const location_t loc = get_location (expr); |
7036e9ef | 163 | |
6c79057f TS |
164 | if (!RESERVED_LOCATION_P (loc)) |
165 | supp = suppress_warning_at (loc, opt, supp) || supp; | |
7036e9ef MS |
166 | set_no_warning_bit (expr, supp); |
167 | } | |
168 | ||
169 | /* Enable, or by default disable, a warning for the statement STMT. | |
170 | The wildcard OPT of -1 controls all warnings. */ | |
171 | ||
172 | void | |
173 | suppress_warning (gimple *stmt, opt_code opt /* = all_warnings */, | |
174 | bool supp /* = true */) | |
175 | { | |
176 | if (opt == no_warning) | |
177 | return; | |
178 | ||
19853922 | 179 | const location_t loc = get_location (stmt); |
7036e9ef | 180 | |
6c79057f TS |
181 | if (!RESERVED_LOCATION_P (loc)) |
182 | supp = suppress_warning_at (loc, opt, supp) || supp; | |
7036e9ef MS |
183 | set_no_warning_bit (stmt, supp); |
184 | } | |
185 | ||
186 | /* Copy the warning disposition mapping between an expression and/or | |
187 | a statement. */ | |
188 | ||
189 | template <class ToType, class FromType> | |
190 | void copy_warning (ToType to, FromType from) | |
191 | { | |
19853922 | 192 | const location_t to_loc = get_location (to); |
7036e9ef | 193 | |
be667628 | 194 | const bool supp = get_no_warning_bit (from); |
7036e9ef | 195 | |
6c79057f TS |
196 | nowarn_spec_t *from_spec = get_nowarn_spec (from); |
197 | if (RESERVED_LOCATION_P (to_loc)) | |
198 | /* We cannot set no-warning dispositions for 'to', so we have no chance but | |
199 | lose those potentially set for 'from'. */ | |
200 | ; | |
7036e9ef MS |
201 | else |
202 | { | |
6c79057f TS |
203 | if (from_spec) |
204 | { | |
205 | /* If there's an entry in the map the no-warning bit must be set. */ | |
206 | gcc_assert (supp); | |
207 | ||
208 | gcc_checking_assert (nowarn_map); | |
1374d4b9 RB |
209 | nowarn_spec_t tem = *from_spec; |
210 | nowarn_map->put (to_loc, tem); | |
6c79057f | 211 | } |
be667628 | 212 | else if (supp) |
6c79057f TS |
213 | { |
214 | if (nowarn_map) | |
215 | nowarn_map->remove (to_loc); | |
216 | } | |
7036e9ef | 217 | } |
6c79057f TS |
218 | |
219 | /* The no-warning bit might be set even if the map has not been consulted, or | |
220 | otherwise if there's no entry in the map. */ | |
221 | set_no_warning_bit (to, supp); | |
7036e9ef MS |
222 | } |
223 | ||
224 | /* Copy the warning disposition mapping from one expression to another. */ | |
225 | ||
226 | void | |
227 | copy_warning (tree to, const_tree from) | |
228 | { | |
be667628 EB |
229 | if (to == from) |
230 | return; | |
7036e9ef MS |
231 | copy_warning<tree, const_tree>(to, from); |
232 | } | |
233 | ||
234 | /* Copy the warning disposition mapping from a statement to an expression. */ | |
235 | ||
236 | void | |
237 | copy_warning (tree to, const gimple *from) | |
238 | { | |
239 | copy_warning<tree, const gimple *>(to, from); | |
240 | } | |
241 | ||
242 | /* Copy the warning disposition mapping from an expression to a statement. */ | |
243 | ||
244 | void | |
245 | copy_warning (gimple *to, const_tree from) | |
246 | { | |
247 | copy_warning<gimple *, const_tree>(to, from); | |
248 | } | |
249 | ||
250 | /* Copy the warning disposition mapping from one statement to another. */ | |
251 | ||
252 | void | |
253 | copy_warning (gimple *to, const gimple *from) | |
254 | { | |
be667628 EB |
255 | if (to == from) |
256 | return; | |
7036e9ef MS |
257 | copy_warning<gimple *, const gimple *>(to, from); |
258 | } |