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