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 549455227 : 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 549455227 : switch (opt)
41 : {
42 61957 : case no_warning:
43 61957 : m_bits = 0;
44 61957 : break;
45 :
46 27489165 : case all_warnings:
47 27489165 : m_bits = -1;
48 27489165 : break;
49 :
50 : /* Flow-sensitive warnings about pointer problems issued by both
51 : front ends and the middle end. */
52 323970 : case OPT_Waddress:
53 323970 : case OPT_Wnonnull:
54 323970 : m_bits = NW_NONNULL;
55 323970 : break;
56 :
57 : /* Flow-sensitive warnings about arithmetic overflow issued by both
58 : front ends and the middle end. */
59 672649 : case OPT_Woverflow:
60 672649 : case OPT_Wshift_count_negative:
61 672649 : case OPT_Wshift_count_overflow:
62 672649 : m_bits = NW_VFLOW;
63 672649 : break;
64 :
65 : /* Lexical warnings issued by front ends. */
66 143123272 : case OPT_Wabi:
67 143123272 : case OPT_Wlogical_op:
68 143123272 : case OPT_Wparentheses:
69 143123272 : case OPT_Wreturn_type:
70 143123272 : case OPT_Wsizeof_array_div:
71 143123272 : case OPT_Wstrict_aliasing:
72 143123272 : case OPT_Wunused:
73 143123272 : case OPT_Wunused_function:
74 143123272 : case OPT_Wunused_but_set_variable_:
75 143123272 : case OPT_Wunused_variable:
76 143123272 : case OPT_Wunused_but_set_parameter_:
77 143123272 : m_bits = NW_LEXICAL;
78 143123272 : break;
79 :
80 : /* Access warning group. */
81 796057 : case OPT_Warray_bounds_:
82 796057 : case OPT_Wformat_overflow_:
83 796057 : case OPT_Wformat_truncation_:
84 796057 : case OPT_Wrestrict:
85 796057 : case OPT_Wsizeof_pointer_memaccess:
86 796057 : case OPT_Wstrict_aliasing_:
87 796057 : case OPT_Wstringop_overflow_:
88 796057 : case OPT_Wstringop_overread:
89 796057 : case OPT_Wstringop_truncation:
90 796057 : m_bits = NW_ACCESS;
91 796057 : break;
92 :
93 : /* Initialization warning group. */
94 2040751 : case OPT_Winit_self:
95 2040751 : case OPT_Wuninitialized:
96 2040751 : case OPT_Wmaybe_uninitialized:
97 2040751 : m_bits = NW_UNINIT;
98 2040751 : break;
99 :
100 925480 : case OPT_Wdangling_pointer_:
101 925480 : case OPT_Wreturn_local_addr:
102 925480 : case OPT_Wuse_after_free:
103 925480 : case OPT_Wuse_after_free_:
104 925480 : m_bits = NW_DANGLING;
105 925480 : break;
106 :
107 371055123 : case OPT_Wpessimizing_move:
108 371055123 : case OPT_Wredundant_move:
109 371055123 : m_bits = NW_REDUNDANT;
110 371055123 : break;
111 :
112 2966803 : default:
113 : /* A catchall group for everything else. */
114 2966803 : m_bits = NW_OTHER;
115 : }
116 549455227 : }
117 :
118 : /* A mapping from a 'location_t' to the warning spec set for it. */
119 :
120 : GTY(()) nowarn_map_t *nowarn_map;
121 :
122 : /* Return the no-warning disposition for location LOC and option OPT
123 : or for all/any options by default. */
124 :
125 : bool
126 177111 : warning_suppressed_at (location_t loc, opt_code opt /* = all_warnings */)
127 : {
128 177111 : gcc_checking_assert (!RESERVED_LOCATION_P (loc));
129 :
130 177111 : if (!nowarn_map)
131 : return false;
132 :
133 176923 : if (const nowarn_spec_t* const pspec = nowarn_map->get (loc))
134 : {
135 26466 : const nowarn_spec_t optspec (opt);
136 26466 : return *pspec & optspec;
137 : }
138 :
139 : return false;
140 : }
141 :
142 : /* Change the suppression of warnings for location LOC.
143 : OPT controls which warnings are affected.
144 : The wildcard OPT of -1 controls all warnings.
145 : If SUPP is true (the default), enable the suppression of the warnings.
146 : If SUPP is false, disable the suppression of the warnings. */
147 :
148 : bool
149 406283448 : suppress_warning_at (location_t loc, opt_code opt /* = all_warnings */,
150 : bool supp /* = true */)
151 : {
152 406283448 : gcc_checking_assert (!RESERVED_LOCATION_P (loc));
153 :
154 406345405 : const nowarn_spec_t optspec (supp ? opt : opt_code ());
155 :
156 406283448 : if (nowarn_spec_t *pspec = nowarn_map ? nowarn_map->get (loc) : nullptr)
157 : {
158 119241085 : if (supp)
159 : {
160 119238112 : *pspec |= optspec;
161 119238112 : return true;
162 : }
163 :
164 2973 : *pspec &= optspec;
165 2973 : if (*pspec)
166 : return true;
167 :
168 2973 : nowarn_map->remove (loc);
169 2973 : return false;
170 : }
171 :
172 287042363 : if (!supp || opt == no_warning)
173 : return false;
174 :
175 286983379 : if (!nowarn_map)
176 184135 : nowarn_map = nowarn_map_t::create_ggc (32);
177 :
178 286983379 : nowarn_map->put (loc, optspec);
179 286983379 : return true;
180 : }
181 :
182 : /* Change the warning disposition for LOC to match OPTSPEC. */
183 :
184 : void
185 487643 : put_warning_spec_at (location_t loc, unsigned bits)
186 : {
187 487643 : gcc_checking_assert (!RESERVED_LOCATION_P (loc));
188 :
189 487643 : nowarn_spec_t optspec = nowarn_spec_t::from_bits (bits);
190 487643 : if (!optspec)
191 : {
192 202920 : if (nowarn_map)
193 202770 : nowarn_map->remove (loc);
194 : }
195 : else
196 : {
197 284723 : if (!nowarn_map)
198 208 : nowarn_map = nowarn_map_t::create_ggc (32);
199 284723 : nowarn_map->put (loc, optspec);
200 : }
201 487643 : }
202 :
203 : /* Copy the no-warning disposition from one location to another. */
204 :
205 : void
206 249411641 : copy_warning (location_t to, location_t from)
207 : {
208 249411641 : if (!nowarn_map)
209 : return;
210 :
211 236234564 : nowarn_spec_t *from_spec;
212 236234564 : if (RESERVED_LOCATION_P (from))
213 : from_spec = nullptr;
214 : else
215 215004178 : from_spec = nowarn_map->get (from);
216 236234564 : if (RESERVED_LOCATION_P (to))
217 : /* We cannot set no-warning dispositions for 'to', so we have no chance but
218 : lose those potentially set for 'from'. */
219 : ;
220 : else
221 : {
222 215618138 : if (from_spec)
223 : {
224 63817552 : nowarn_spec_t tem = *from_spec;
225 63817552 : nowarn_map->put (to, tem);
226 : }
227 : else
228 151800586 : nowarn_map->remove (to);
229 : }
230 : }
|