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