Line data Source code
1 : /* Functions to enable and disable individual warnings on an expression
2 : and statement basis.
3 :
4 : Copyright (C) 2021-2026 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 "gcc-diagnostic-spec.h"
32 :
33 : /* Return the no-warning bit for EXPR. */
34 :
35 : static inline bool
36 2950947942 : get_no_warning_bit (const_tree expr)
37 : {
38 2950947942 : return expr->base.nowarning_flag;
39 : }
40 :
41 : /* Return the no-warning bit for statement STMT. */
42 :
43 : static inline bool
44 1504172848 : get_no_warning_bit (const gimple *stmt)
45 : {
46 1504172848 : return stmt->no_warning;
47 : }
48 :
49 : /* Set the no-warning bit for EXPR to VALUE. */
50 :
51 : static inline void
52 918253069 : set_no_warning_bit (tree expr, bool value)
53 : {
54 918253069 : expr->base.nowarning_flag = value;
55 424576743 : }
56 :
57 : /* Set the no-warning bit for statement STMT to VALUE. */
58 :
59 : static inline void
60 19395924 : set_no_warning_bit (gimple *stmt, bool value)
61 : {
62 19395924 : stmt->no_warning = value;
63 99284 : }
64 :
65 : /* Return EXPR location or 'UNKNOWN_LOCATION'. */
66 :
67 : static inline location_t
68 2514750840 : get_location (const_tree expr)
69 : {
70 2514750840 : if (DECL_P (expr))
71 215598582 : return DECL_SOURCE_LOCATION (expr);
72 2299152258 : if (EXPR_P (expr))
73 2238559602 : 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 831177415 : get_location (const gimple *stmt)
81 : {
82 831177415 : return gimple_location (stmt);
83 : }
84 :
85 : /* Return the no-warning bitmap for decl/expression EXPR. */
86 :
87 : static nowarn_spec_t *
88 1574982357 : get_nowarn_spec (const_tree expr)
89 : {
90 1574982357 : const location_t loc = get_location (expr);
91 :
92 1574982357 : if (RESERVED_LOCATION_P (loc))
93 : return NULL;
94 :
95 1357931091 : if (!get_no_warning_bit (expr))
96 : return NULL;
97 :
98 206308389 : 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 811781491 : get_nowarn_spec (const gimple *stmt)
105 : {
106 811781491 : const location_t loc = get_location (stmt);
107 :
108 811781491 : if (RESERVED_LOCATION_P (loc))
109 : return NULL;
110 :
111 692391357 : if (!get_no_warning_bit (stmt))
112 : return NULL;
113 :
114 10306143 : 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 1068003845 : warning_suppressed_p (const_tree expr, opt_code opt /* = all_warnings */)
122 : {
123 1068003845 : const nowarn_spec_t *spec = get_nowarn_spec (expr);
124 :
125 1068003845 : if (!spec)
126 942313771 : return get_no_warning_bit (expr);
127 :
128 125690074 : const nowarn_spec_t optspec (opt);
129 125690074 : bool dis = *spec & optspec;
130 125690074 : 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 805183840 : warning_suppressed_p (const gimple *stmt, opt_code opt /* = all_warnings */)
139 : {
140 805183840 : const nowarn_spec_t *spec = get_nowarn_spec (stmt);
141 :
142 805183840 : if (!spec)
143 : /* Fall back on the single no-warning bit. */
144 795456000 : return get_no_warning_bit (stmt);
145 :
146 9727840 : const nowarn_spec_t optspec (opt);
147 9727840 : bool dis = *spec & optspec;
148 9727840 : 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 424576743 : suppress_warning (tree expr, opt_code opt /* = all_warnings */,
157 : bool supp /* = true */)
158 : {
159 424576743 : if (opt == no_warning)
160 : return;
161 :
162 424576743 : const location_t loc = get_location (expr);
163 :
164 424576743 : if (!RESERVED_LOCATION_P (loc))
165 378876383 : supp = suppress_warning_at (loc, opt, supp) || supp;
166 424576743 : 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 248797 : suppress_warning (gimple *stmt, opt_code opt /* = all_warnings */,
174 : bool supp /* = true */)
175 : {
176 248797 : if (opt == no_warning)
177 : return;
178 :
179 99284 : const location_t loc = get_location (stmt);
180 :
181 99284 : if (!RESERVED_LOCATION_P (loc))
182 99262 : supp = suppress_warning_at (loc, opt, supp) || supp;
183 99284 : 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 512972966 : void copy_warning (ToType to, FromType from)
191 : {
192 512972966 : const location_t to_loc = get_location (to);
193 :
194 512972966 : const bool supp = get_no_warning_bit (from);
195 :
196 512972966 : nowarn_spec_t *from_spec = get_nowarn_spec (from);
197 512972966 : 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 428646557 : if (from_spec)
204 : {
205 : /* If there's an entry in the map the no-warning bit must be set. */
206 58379860 : gcc_assert (supp);
207 :
208 58379860 : gcc_checking_assert (nowarn_map);
209 58379860 : nowarn_spec_t tem = *from_spec;
210 58379860 : nowarn_map->put (to_loc, tem);
211 : }
212 370266697 : else if (supp)
213 : {
214 120690 : if (nowarn_map)
215 116496 : 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 512972966 : set_no_warning_bit (to, supp);
222 512972966 : }
223 :
224 : /* Copy the warning disposition mapping from one expression to another. */
225 :
226 : void
227 2177735063 : copy_warning (tree to, const_tree from)
228 : {
229 2177735063 : if (to == from)
230 : return;
231 487079493 : 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 6596833 : copy_warning (tree to, const gimple *from)
238 : {
239 6596833 : copy_warning<tree, const gimple *>(to, from);
240 6596833 : }
241 :
242 : /* Copy the warning disposition mapping from an expression to a statement. */
243 :
244 : void
245 19295822 : copy_warning (gimple *to, const_tree from)
246 : {
247 19295822 : copy_warning<gimple *, const_tree>(to, from);
248 19295822 : }
249 :
250 : /* Copy the warning disposition mapping from one statement to another. */
251 :
252 : void
253 818 : copy_warning (gimple *to, const gimple *from)
254 : {
255 818 : if (to == from)
256 : return;
257 818 : copy_warning<gimple *, const gimple *>(to, from);
258 : }
259 :
260 : /* Whether the tree might have a warning spec. */
261 :
262 21041764 : bool has_warning_spec (const_tree t)
263 : {
264 21041764 : const location_t loc = get_location (t);
265 21041764 : return !RESERVED_LOCATION_P (loc) && get_no_warning_bit (t);
266 : }
267 :
268 : /* Retrieve warning dispostion bitmap for tree streaming. */
269 :
270 : unsigned
271 603197 : get_warning_spec (const_tree t)
272 : {
273 603197 : const nowarn_spec_t *spec = get_nowarn_spec (t);
274 603197 : return spec ? *spec : 0;
275 : }
276 :
277 : /* Write warning disposition bitmap for streamed-in tree. */
278 :
279 : void
280 473650 : put_warning_spec (tree t, unsigned bits)
281 : {
282 473650 : const location_t loc = get_location (t);
283 473650 : put_warning_spec_at (loc, bits);
284 473650 : }
|