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 514660177 : 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 514660177 : switch (opt)
41 : {
42 61924 : case no_warning:
43 61924 : m_bits = 0;
44 61924 : break;
45 :
46 26179439 : case all_warnings:
47 26179439 : m_bits = -1;
48 26179439 : break;
49 :
50 : /* Flow-sensitive warnings about pointer problems issued by both
51 : front ends and the middle end. */
52 299006 : case OPT_Waddress:
53 299006 : case OPT_Wnonnull:
54 299006 : m_bits = NW_NONNULL;
55 299006 : break;
56 :
57 : /* Flow-sensitive warnings about arithmetic overflow issued by both
58 : front ends and the middle end. */
59 671946 : case OPT_Woverflow:
60 671946 : case OPT_Wshift_count_negative:
61 671946 : case OPT_Wshift_count_overflow:
62 671946 : m_bits = NW_VFLOW;
63 671946 : break;
64 :
65 : /* Lexical warnings issued by front ends. */
66 136229487 : case OPT_Wabi:
67 136229487 : case OPT_Wlogical_op:
68 136229487 : case OPT_Wparentheses:
69 136229487 : case OPT_Wreturn_type:
70 136229487 : case OPT_Wsizeof_array_div:
71 136229487 : case OPT_Wstrict_aliasing:
72 136229487 : case OPT_Wunused:
73 136229487 : case OPT_Wunused_function:
74 136229487 : case OPT_Wunused_but_set_variable_:
75 136229487 : case OPT_Wunused_variable:
76 136229487 : case OPT_Wunused_but_set_parameter_:
77 136229487 : m_bits = NW_LEXICAL;
78 136229487 : break;
79 :
80 : /* Access warning group. */
81 731004 : case OPT_Warray_bounds_:
82 731004 : case OPT_Wformat_overflow_:
83 731004 : case OPT_Wformat_truncation_:
84 731004 : case OPT_Wrestrict:
85 731004 : case OPT_Wsizeof_pointer_memaccess:
86 731004 : case OPT_Wstrict_aliasing_:
87 731004 : case OPT_Wstringop_overflow_:
88 731004 : case OPT_Wstringop_overread:
89 731004 : case OPT_Wstringop_truncation:
90 731004 : m_bits = NW_ACCESS;
91 731004 : break;
92 :
93 : /* Initialization warning group. */
94 1921994 : case OPT_Winit_self:
95 1921994 : case OPT_Wuninitialized:
96 1921994 : case OPT_Wmaybe_uninitialized:
97 1921994 : m_bits = NW_UNINIT;
98 1921994 : break;
99 :
100 834863 : case OPT_Wdangling_pointer_:
101 834863 : case OPT_Wreturn_local_addr:
102 834863 : case OPT_Wuse_after_free:
103 834863 : case OPT_Wuse_after_free_:
104 834863 : m_bits = NW_DANGLING;
105 834863 : break;
106 :
107 344955028 : case OPT_Wpessimizing_move:
108 344955028 : case OPT_Wredundant_move:
109 344955028 : m_bits = NW_REDUNDANT;
110 344955028 : break;
111 :
112 2775486 : default:
113 : /* A catchall group for everything else. */
114 2775486 : m_bits = NW_OTHER;
115 : }
116 514660177 : }
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 156975 : warning_suppressed_at (location_t loc, opt_code opt /* = all_warnings */)
127 : {
128 156975 : gcc_checking_assert (!RESERVED_LOCATION_P (loc));
129 :
130 156975 : if (!nowarn_map)
131 : return false;
132 :
133 156787 : if (const nowarn_spec_t* const pspec = nowarn_map->get (loc))
134 : {
135 23910 : const nowarn_spec_t optspec (opt);
136 23910 : 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 383519245 : suppress_warning_at (location_t loc, opt_code opt /* = all_warnings */,
150 : bool supp /* = true */)
151 : {
152 383519245 : gcc_checking_assert (!RESERVED_LOCATION_P (loc));
153 :
154 383581169 : const nowarn_spec_t optspec (supp ? opt : opt_code ());
155 :
156 383519245 : if (nowarn_spec_t *pspec = nowarn_map ? nowarn_map->get (loc) : nullptr)
157 : {
158 110452920 : if (supp)
159 : {
160 110449947 : *pspec |= optspec;
161 110449947 : 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 273066325 : if (!supp || opt == no_warning)
173 : return false;
174 :
175 273007374 : if (!nowarn_map)
176 185787 : nowarn_map = nowarn_map_t::create_ggc (32);
177 :
178 273007374 : nowarn_map->put (loc, optspec);
179 273007374 : return true;
180 : }
181 :
182 : /* Change the warning disposition for LOC to match OPTSPEC. */
183 :
184 : void
185 486782 : put_warning_spec_at (location_t loc, unsigned bits)
186 : {
187 486782 : gcc_checking_assert (!RESERVED_LOCATION_P (loc));
188 :
189 486782 : nowarn_spec_t optspec = nowarn_spec_t::from_bits (bits);
190 486782 : if (!optspec)
191 : {
192 202614 : if (nowarn_map)
193 202484 : nowarn_map->remove (loc);
194 : }
195 : else
196 : {
197 284168 : if (!nowarn_map)
198 208 : nowarn_map = nowarn_map_t::create_ggc (32);
199 284168 : nowarn_map->put (loc, optspec);
200 : }
201 486782 : }
202 :
203 : /* Copy the no-warning disposition from one location to another. */
204 :
205 : void
206 237457499 : copy_warning (location_t to, location_t from)
207 : {
208 237457499 : if (!nowarn_map)
209 : return;
210 :
211 224329397 : nowarn_spec_t *from_spec;
212 224329397 : if (RESERVED_LOCATION_P (from))
213 : from_spec = nullptr;
214 : else
215 203667366 : from_spec = nowarn_map->get (from);
216 224329397 : 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 204253802 : if (from_spec)
223 : {
224 58922982 : nowarn_spec_t tem = *from_spec;
225 58922982 : nowarn_map->put (to, tem);
226 : }
227 : else
228 145330820 : nowarn_map->remove (to);
229 : }
230 : }
|