Line data Source code
1 : /* Functions to enable and disable individual warnings on an expression
2 : and statement basis.
3 : Copyright (C) 2021-2026 Free Software Foundation, Inc.
4 : Contributed by Martin Sebor <msebor@redhat.com>
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 "cgraph.h"
29 : #include "hash-map.h"
30 : #include "gcc-diagnostic-spec.h"
31 : #include "pretty-print.h"
32 : #include "options.h"
33 :
34 : /* Initialize *THIS from warning option OPT. */
35 :
36 516769555 : nowarn_spec_t::nowarn_spec_t (opt_code opt)
37 : {
38 : /* Create a very simple mapping based on testing and experience.
39 : It should become more refined with time. */
40 516769555 : switch (opt)
41 : {
42 61878 : case no_warning:
43 61878 : m_bits = 0;
44 61878 : break;
45 :
46 26352304 : case all_warnings:
47 26352304 : m_bits = -1;
48 26352304 : break;
49 :
50 : /* Flow-sensitive warnings about pointer problems issued by both
51 : front ends and the middle end. */
52 308590 : case OPT_Waddress:
53 308590 : case OPT_Wnonnull:
54 308590 : m_bits = NW_NONNULL;
55 308590 : break;
56 :
57 : /* Flow-sensitive warnings about arithmetic overflow issued by both
58 : front ends and the middle end. */
59 7803198 : case OPT_Woverflow:
60 7803198 : case OPT_Wshift_count_negative:
61 7803198 : case OPT_Wshift_count_overflow:
62 7803198 : case OPT_Wstrict_overflow:
63 7803198 : m_bits = NW_VFLOW;
64 7803198 : break;
65 :
66 : /* Lexical warnings issued by front ends. */
67 136109021 : case OPT_Wabi:
68 136109021 : case OPT_Wlogical_op:
69 136109021 : case OPT_Wparentheses:
70 136109021 : case OPT_Wreturn_type:
71 136109021 : case OPT_Wsizeof_array_div:
72 136109021 : case OPT_Wstrict_aliasing:
73 136109021 : case OPT_Wunused:
74 136109021 : case OPT_Wunused_function:
75 136109021 : case OPT_Wunused_but_set_variable_:
76 136109021 : case OPT_Wunused_variable:
77 136109021 : case OPT_Wunused_but_set_parameter_:
78 136109021 : m_bits = NW_LEXICAL;
79 136109021 : break;
80 :
81 : /* Access warning group. */
82 754073 : case OPT_Warray_bounds_:
83 754073 : case OPT_Wformat_overflow_:
84 754073 : case OPT_Wformat_truncation_:
85 754073 : case OPT_Wrestrict:
86 754073 : case OPT_Wsizeof_pointer_memaccess:
87 754073 : case OPT_Wstrict_aliasing_:
88 754073 : case OPT_Wstringop_overflow_:
89 754073 : case OPT_Wstringop_overread:
90 754073 : case OPT_Wstringop_truncation:
91 754073 : m_bits = NW_ACCESS;
92 754073 : break;
93 :
94 : /* Initialization warning group. */
95 1944651 : case OPT_Winit_self:
96 1944651 : case OPT_Wuninitialized:
97 1944651 : case OPT_Wmaybe_uninitialized:
98 1944651 : m_bits = NW_UNINIT;
99 1944651 : break;
100 :
101 851734 : case OPT_Wdangling_pointer_:
102 851734 : case OPT_Wreturn_local_addr:
103 851734 : case OPT_Wuse_after_free:
104 851734 : case OPT_Wuse_after_free_:
105 851734 : m_bits = NW_DANGLING;
106 851734 : break;
107 :
108 339804694 : case OPT_Wpessimizing_move:
109 339804694 : case OPT_Wredundant_move:
110 339804694 : m_bits = NW_REDUNDANT;
111 339804694 : break;
112 :
113 2779412 : default:
114 : /* A catchall group for everything else. */
115 2779412 : m_bits = NW_OTHER;
116 : }
117 516769555 : }
118 :
119 : /* A mapping from a 'location_t' to the warning spec set for it. */
120 :
121 : GTY(()) nowarn_map_t *nowarn_map;
122 :
123 : /* Return the no-warning disposition for location LOC and option OPT
124 : or for all/any otions by default. */
125 :
126 : bool
127 133930 : warning_suppressed_at (location_t loc, opt_code opt /* = all_warnings */)
128 : {
129 133930 : gcc_checking_assert (!RESERVED_LOCATION_P (loc));
130 :
131 133930 : if (!nowarn_map)
132 : return false;
133 :
134 133751 : if (const nowarn_spec_t* const pspec = nowarn_map->get (loc))
135 : {
136 24041 : const nowarn_spec_t optspec (opt);
137 24041 : return *pspec & optspec;
138 : }
139 :
140 : return false;
141 : }
142 :
143 : /* Change the supression of warnings for location LOC.
144 : OPT controls which warnings are affected.
145 : The wildcard OPT of -1 controls all warnings.
146 : If SUPP is true (the default), enable the suppression of the warnings.
147 : If SUPP is false, disable the suppression of the warnings. */
148 :
149 : bool
150 381806696 : suppress_warning_at (location_t loc, opt_code opt /* = all_warnings */,
151 : bool supp /* = true */)
152 : {
153 381806696 : gcc_checking_assert (!RESERVED_LOCATION_P (loc));
154 :
155 381868574 : const nowarn_spec_t optspec (supp ? opt : opt_code ());
156 :
157 381806696 : if (nowarn_spec_t *pspec = nowarn_map ? nowarn_map->get (loc) : nullptr)
158 : {
159 108674982 : if (supp)
160 : {
161 108672009 : *pspec |= optspec;
162 108672009 : return true;
163 : }
164 :
165 2973 : *pspec &= optspec;
166 2973 : if (*pspec)
167 : return true;
168 :
169 2973 : nowarn_map->remove (loc);
170 2973 : return false;
171 : }
172 :
173 273131714 : if (!supp || opt == no_warning)
174 : return false;
175 :
176 273072809 : if (!nowarn_map)
177 181895 : nowarn_map = nowarn_map_t::create_ggc (32);
178 :
179 273072809 : nowarn_map->put (loc, optspec);
180 273072809 : return true;
181 : }
182 :
183 : /* Change the warning disposition for LOC to match OPTSPEC. */
184 :
185 : void
186 474394 : put_warning_spec_at (location_t loc, unsigned bits)
187 : {
188 474394 : gcc_checking_assert (!RESERVED_LOCATION_P (loc));
189 :
190 474394 : nowarn_spec_t optspec = nowarn_spec_t::from_bits (bits);
191 474394 : if (!optspec)
192 : {
193 198106 : if (nowarn_map)
194 197976 : nowarn_map->remove (loc);
195 : }
196 : else
197 : {
198 276288 : if (!nowarn_map)
199 206 : nowarn_map = nowarn_map_t::create_ggc (32);
200 276288 : nowarn_map->put (loc, optspec);
201 : }
202 474394 : }
203 :
204 : /* Copy the no-warning disposition from one location to another. */
205 :
206 : void
207 240006473 : copy_warning (location_t to, location_t from)
208 : {
209 240006473 : if (!nowarn_map)
210 : return;
211 :
212 226944513 : nowarn_spec_t *from_spec;
213 226944513 : if (RESERVED_LOCATION_P (from))
214 : from_spec = nullptr;
215 : else
216 206172558 : from_spec = nowarn_map->get (from);
217 226944513 : if (RESERVED_LOCATION_P (to))
218 : /* We cannot set no-warning dispositions for 'to', so we have no chance but
219 : lose those potentially set for 'from'. */
220 : ;
221 : else
222 : {
223 206782780 : if (from_spec)
224 : {
225 60054471 : nowarn_spec_t tem = *from_spec;
226 60054471 : nowarn_map->put (to, tem);
227 : }
228 : else
229 146728309 : nowarn_map->remove (to);
230 : }
231 : }
|