Branch data Line data Source code
1 : : /* Functions to enable and disable individual warnings on an expression
2 : : and statement basis.
3 : :
4 : : Copyright (C) 2021-2024 Free Software Foundation, Inc.
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 : 2715393278 : get_no_warning_bit (const_tree expr)
37 : : {
38 : 2715393278 : return expr->base.nowarning_flag;
39 : : }
40 : :
41 : : /* Return the no-warning bit for statement STMT. */
42 : :
43 : : static inline bool
44 : 1324957640 : get_no_warning_bit (const gimple *stmt)
45 : : {
46 : 1324957640 : return stmt->no_warning;
47 : : }
48 : :
49 : : /* Set the no-warning bit for EXPR to VALUE. */
50 : :
51 : : static inline void
52 : 745055306 : set_no_warning_bit (tree expr, bool value)
53 : : {
54 : 745055306 : expr->base.nowarning_flag = value;
55 : 332598370 : }
56 : :
57 : : /* Set the no-warning bit for statement STMT to VALUE. */
58 : :
59 : : static inline void
60 : 18183623 : set_no_warning_bit (gimple *stmt, bool value)
61 : : {
62 : 18183623 : stmt->no_warning = value;
63 : 125409 : }
64 : :
65 : : /* Return EXPR location or 'UNKNOWN_LOCATION'. */
66 : :
67 : : static inline location_t
68 : 2216761970 : get_location (const_tree expr)
69 : : {
70 : 2216761970 : if (DECL_P (expr))
71 : 219272475 : return DECL_SOURCE_LOCATION (expr);
72 : 1997489495 : if (EXPR_P (expr))
73 : 1942369320 : return EXPR_LOCATION (expr);
74 : : return UNKNOWN_LOCATION;
75 : : }
76 : :
77 : : /* Return STMT location (may be 'UNKNOWN_LOCATION'). */
78 : :
79 : : static inline location_t
80 : 732079706 : get_location (const gimple *stmt)
81 : : {
82 : 732079706 : return gimple_location (stmt);
83 : : }
84 : :
85 : : /* Return the no-warning bitmap for decl/expression EXPR. */
86 : :
87 : : static nowarn_spec_t *
88 : 1446025453 : get_nowarn_spec (const_tree expr)
89 : : {
90 : 1446025453 : const location_t loc = get_location (expr);
91 : :
92 : 1446025453 : if (RESERVED_LOCATION_P (loc))
93 : : return NULL;
94 : :
95 : 1247619476 : if (!get_no_warning_bit (expr))
96 : : return NULL;
97 : :
98 : 164439074 : return nowarn_map ? nowarn_map->get (loc) : NULL;
99 : : }
100 : :
101 : : /* Return the no-warning bitmap for statement STMT. */
102 : :
103 : : static nowarn_spec_t *
104 : 713896083 : get_nowarn_spec (const gimple *stmt)
105 : : {
106 : 713896083 : const location_t loc = get_location (stmt);
107 : :
108 : 713896083 : if (RESERVED_LOCATION_P (loc))
109 : : return NULL;
110 : :
111 : 611061557 : if (!get_no_warning_bit (stmt))
112 : : return NULL;
113 : :
114 : 8504496 : return nowarn_map ? nowarn_map->get (loc) : NULL;
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 : 1021162087 : warning_suppressed_p (const_tree expr, opt_code opt /* = all_warnings */)
122 : : {
123 : 1021162087 : const nowarn_spec_t *spec = get_nowarn_spec (expr);
124 : :
125 : 1021162087 : if (!spec)
126 : 918505680 : return get_no_warning_bit (expr);
127 : :
128 : 102656407 : const nowarn_spec_t optspec (opt);
129 : 102656407 : bool dis = *spec & optspec;
130 : 102656407 : 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 : 707605668 : warning_suppressed_p (const gimple *stmt, opt_code opt /* = all_warnings */)
139 : : {
140 : 707605668 : const nowarn_spec_t *spec = get_nowarn_spec (stmt);
141 : :
142 : 707605668 : if (!spec)
143 : : /* Fall back on the single no-warning bit. */
144 : 699708610 : return get_no_warning_bit (stmt);
145 : :
146 : 7897058 : const nowarn_spec_t optspec (opt);
147 : 7897058 : bool dis = *spec & optspec;
148 : 7897058 : 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 : 332598370 : suppress_warning (tree expr, opt_code opt /* = all_warnings */,
157 : : bool supp /* = true */)
158 : : {
159 : 332598370 : if (opt == no_warning)
160 : : return;
161 : :
162 : 332598370 : const location_t loc = get_location (expr);
163 : :
164 : 332598370 : if (!RESERVED_LOCATION_P (loc))
165 : 312477509 : supp = suppress_warning_at (loc, opt, supp) || supp;
166 : 332598370 : 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 : 243468 : suppress_warning (gimple *stmt, opt_code opt /* = all_warnings */,
174 : : bool supp /* = true */)
175 : : {
176 : 243468 : if (opt == no_warning)
177 : : return;
178 : :
179 : 125409 : const location_t loc = get_location (stmt);
180 : :
181 : 125409 : if (!RESERVED_LOCATION_P (loc))
182 : 125383 : supp = suppress_warning_at (loc, opt, supp) || supp;
183 : 125409 : 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 : 430515150 : void copy_warning (ToType to, FromType from)
191 : : {
192 : 430515150 : const location_t to_loc = get_location (to);
193 : :
194 : 430515150 : const bool supp = get_no_warning_bit (from);
195 : :
196 : 430515150 : nowarn_spec_t *from_spec = get_nowarn_spec (from);
197 : 430515150 : 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 : : ;
201 : : else
202 : : {
203 : 359394654 : if (from_spec)
204 : : {
205 : : /* If there's an entry in the map the no-warning bit must be set. */
206 : 48589867 : gcc_assert (supp);
207 : :
208 : 48589867 : gcc_checking_assert (nowarn_map);
209 : 48589867 : nowarn_spec_t tem = *from_spec;
210 : 48589867 : nowarn_map->put (to_loc, tem);
211 : : }
212 : 310804787 : else if (supp)
213 : : {
214 : 132847 : if (nowarn_map)
215 : 128732 : nowarn_map->remove (to_loc);
216 : : }
217 : : }
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 : 430515150 : set_no_warning_bit (to, supp);
222 : 430515150 : }
223 : :
224 : : /* Copy the warning disposition mapping from one expression to another. */
225 : :
226 : : void
227 : 1071712754 : copy_warning (tree to, const_tree from)
228 : : {
229 : 1071712754 : if (to == from)
230 : : return;
231 : 406167333 : 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 : 6289603 : copy_warning (tree to, const gimple *from)
238 : : {
239 : 6289603 : copy_warning<tree, const gimple *>(to, from);
240 : 6289603 : }
241 : :
242 : : /* Copy the warning disposition mapping from an expression to a statement. */
243 : :
244 : : void
245 : 18057402 : copy_warning (gimple *to, const_tree from)
246 : : {
247 : 18057402 : copy_warning<gimple *, const_tree>(to, from);
248 : 18057402 : }
249 : :
250 : : /* Copy the warning disposition mapping from one statement to another. */
251 : :
252 : : void
253 : 812 : copy_warning (gimple *to, const gimple *from)
254 : : {
255 : 812 : if (to == from)
256 : : return;
257 : 812 : copy_warning<gimple *, const gimple *>(to, from);
258 : : }
259 : :
260 : : /* Whether the tree might have a warning spec. */
261 : :
262 : 25049254 : bool has_warning_spec (const_tree t)
263 : : {
264 : 25049254 : const location_t loc = get_location (t);
265 : 25049254 : return !RESERVED_LOCATION_P (loc) && get_no_warning_bit (t);
266 : : }
267 : :
268 : : /* Retrieve warning dispostion bitmap for tree streaming. */
269 : :
270 : : unsigned
271 : 638631 : get_warning_spec (const_tree t)
272 : : {
273 : 638631 : const nowarn_spec_t *spec = get_nowarn_spec (t);
274 : 638631 : return spec ? *spec : 0;
275 : : }
276 : :
277 : : /* Write warning disposition bitmap for streamed-in tree. */
278 : :
279 : : void
280 : 631957 : put_warning_spec (tree t, unsigned bits)
281 : : {
282 : 631957 : const location_t loc = get_location (t);
283 : 631957 : put_warning_spec_at (loc, bits);
284 : 631957 : }
|