Branch data Line data Source code
1 : : /* Functions to enable and disable individual warnings on an expression
2 : : and statement basis.
3 : : Copyright (C) 2021-2025 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 : 480502770 : 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 : 480502770 : switch (opt)
41 : : {
42 : 86927 : case no_warning:
43 : 86927 : m_bits = 0;
44 : 86927 : break;
45 : :
46 : 28774254 : case all_warnings:
47 : 28774254 : m_bits = -1;
48 : 28774254 : break;
49 : :
50 : : /* Flow-sensitive warnings about pointer problems issued by both
51 : : front ends and the middle end. */
52 : 511510 : case OPT_Waddress:
53 : 511510 : case OPT_Wnonnull:
54 : 511510 : m_bits = NW_NONNULL;
55 : 511510 : break;
56 : :
57 : : /* Flow-sensitive warnings about arithmetic overflow issued by both
58 : : front ends and the middle end. */
59 : 8465526 : case OPT_Woverflow:
60 : 8465526 : case OPT_Wshift_count_negative:
61 : 8465526 : case OPT_Wshift_count_overflow:
62 : 8465526 : case OPT_Wstrict_overflow:
63 : 8465526 : m_bits = NW_VFLOW;
64 : 8465526 : break;
65 : :
66 : : /* Lexical warnings issued by front ends. */
67 : 121017370 : case OPT_Wabi:
68 : 121017370 : case OPT_Wlogical_op:
69 : 121017370 : case OPT_Wparentheses:
70 : 121017370 : case OPT_Wreturn_type:
71 : 121017370 : case OPT_Wsizeof_array_div:
72 : 121017370 : case OPT_Wstrict_aliasing:
73 : 121017370 : case OPT_Wunused:
74 : 121017370 : case OPT_Wunused_function:
75 : 121017370 : case OPT_Wunused_but_set_variable_:
76 : 121017370 : case OPT_Wunused_variable:
77 : 121017370 : case OPT_Wunused_but_set_parameter_:
78 : 121017370 : m_bits = NW_LEXICAL;
79 : 121017370 : break;
80 : :
81 : : /* Access warning group. */
82 : 1036500 : case OPT_Warray_bounds_:
83 : 1036500 : case OPT_Wformat_overflow_:
84 : 1036500 : case OPT_Wformat_truncation_:
85 : 1036500 : case OPT_Wrestrict:
86 : 1036500 : case OPT_Wsizeof_pointer_memaccess:
87 : 1036500 : case OPT_Wstrict_aliasing_:
88 : 1036500 : case OPT_Wstringop_overflow_:
89 : 1036500 : case OPT_Wstringop_overread:
90 : 1036500 : case OPT_Wstringop_truncation:
91 : 1036500 : m_bits = NW_ACCESS;
92 : 1036500 : break;
93 : :
94 : : /* Initialization warning group. */
95 : 1960998 : case OPT_Winit_self:
96 : 1960998 : case OPT_Wuninitialized:
97 : 1960998 : case OPT_Wmaybe_uninitialized:
98 : 1960998 : m_bits = NW_UNINIT;
99 : 1960998 : break;
100 : :
101 : 866309 : case OPT_Wdangling_pointer_:
102 : 866309 : case OPT_Wreturn_local_addr:
103 : 866309 : case OPT_Wuse_after_free_:
104 : 866309 : m_bits = NW_DANGLING;
105 : 866309 : break;
106 : :
107 : 315621286 : case OPT_Wpessimizing_move:
108 : 315621286 : case OPT_Wredundant_move:
109 : 315621286 : m_bits = NW_REDUNDANT;
110 : 315621286 : break;
111 : :
112 : 2162090 : default:
113 : : /* A catchall group for everything else. */
114 : 2162090 : m_bits = NW_OTHER;
115 : : }
116 : 480502770 : }
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 otions by default. */
124 : :
125 : : bool
126 : 47160 : warning_suppressed_at (location_t loc, opt_code opt /* = all_warnings */)
127 : : {
128 : 47160 : gcc_checking_assert (!RESERVED_LOCATION_P (loc));
129 : :
130 : 47160 : if (!nowarn_map)
131 : : return false;
132 : :
133 : 47006 : if (const nowarn_spec_t* const pspec = nowarn_map->get (loc))
134 : : {
135 : 25724 : const nowarn_spec_t optspec (opt);
136 : 25724 : return *pspec & optspec;
137 : : }
138 : :
139 : : return false;
140 : : }
141 : :
142 : : /* Change the supression 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 : 347649885 : suppress_warning_at (location_t loc, opt_code opt /* = all_warnings */,
150 : : bool supp /* = true */)
151 : : {
152 : 347649885 : gcc_checking_assert (!RESERVED_LOCATION_P (loc));
153 : :
154 : 347736812 : const nowarn_spec_t optspec (supp ? opt : opt_code ());
155 : :
156 : 347649885 : if (nowarn_spec_t *pspec = nowarn_map ? nowarn_map->get (loc) : nullptr)
157 : : {
158 : 109560825 : if (supp)
159 : : {
160 : 109557840 : *pspec |= optspec;
161 : 109557840 : return true;
162 : : }
163 : :
164 : 2985 : *pspec &= optspec;
165 : 2985 : if (*pspec)
166 : : return true;
167 : :
168 : 2985 : nowarn_map->remove (loc);
169 : 2985 : return false;
170 : : }
171 : :
172 : 238089060 : if (!supp || opt == no_warning)
173 : : return false;
174 : :
175 : 238005118 : if (!nowarn_map)
176 : 178624 : nowarn_map = nowarn_map_t::create_ggc (32);
177 : :
178 : 238005118 : nowarn_map->put (loc, optspec);
179 : 238005118 : return true;
180 : : }
181 : :
182 : : /* Change the warning disposition for LOC to match OPTSPEC. */
183 : :
184 : : void
185 : 309071 : put_warning_spec_at (location_t loc, unsigned bits)
186 : : {
187 : 309071 : gcc_checking_assert (!RESERVED_LOCATION_P (loc));
188 : :
189 : 309071 : nowarn_spec_t optspec = nowarn_spec_t::from_bits (bits);
190 : 309071 : if (!optspec)
191 : : {
192 : 125310 : if (nowarn_map)
193 : 125230 : nowarn_map->remove (loc);
194 : : }
195 : : else
196 : : {
197 : 183761 : if (!nowarn_map)
198 : 179 : nowarn_map = nowarn_map_t::create_ggc (32);
199 : 183761 : nowarn_map->put (loc, optspec);
200 : : }
201 : 309071 : }
202 : :
203 : : /* Copy the no-warning disposition from one location to another. */
204 : :
205 : : void
206 : 236087586 : copy_warning (location_t to, location_t from)
207 : : {
208 : 236087586 : if (!nowarn_map)
209 : : return;
210 : :
211 : 223190494 : nowarn_spec_t *from_spec;
212 : 223190494 : if (RESERVED_LOCATION_P (from))
213 : : from_spec = nullptr;
214 : : else
215 : 202670597 : from_spec = nowarn_map->get (from);
216 : 223190494 : 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 : 203114183 : if (from_spec)
223 : : {
224 : 56875141 : nowarn_spec_t tem = *from_spec;
225 : 56875141 : nowarn_map->put (to, tem);
226 : : }
227 : : else
228 : 146239042 : nowarn_map->remove (to);
229 : : }
230 : : }
|