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 "diagnostic-spec.h"
31 : : #include "pretty-print.h"
32 : : #include "options.h"
33 : :
34 : : /* Initialize *THIS from warning option OPT. */
35 : :
36 : 430924530 : 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 : 430924530 : switch (opt)
41 : : {
42 : 89340 : case no_warning:
43 : 89340 : m_bits = 0;
44 : 89340 : break;
45 : :
46 : 27121395 : case all_warnings:
47 : 27121395 : m_bits = -1;
48 : 27121395 : break;
49 : :
50 : : /* Flow-sensitive warnings about pointer problems issued by both
51 : : front ends and the middle end. */
52 : 427903 : case OPT_Waddress:
53 : 427903 : case OPT_Wnonnull:
54 : 427903 : m_bits = NW_NONNULL;
55 : 427903 : break;
56 : :
57 : : /* Flow-sensitive warnings about arithmetic overflow issued by both
58 : : front ends and the middle end. */
59 : 6954576 : case OPT_Woverflow:
60 : 6954576 : case OPT_Wshift_count_negative:
61 : 6954576 : case OPT_Wshift_count_overflow:
62 : 6954576 : case OPT_Wstrict_overflow:
63 : 6954576 : m_bits = NW_VFLOW;
64 : 6954576 : break;
65 : :
66 : : /* Lexical warnings issued by front ends. */
67 : 111727620 : case OPT_Wabi:
68 : 111727620 : case OPT_Wlogical_op:
69 : 111727620 : case OPT_Wparentheses:
70 : 111727620 : case OPT_Wreturn_type:
71 : 111727620 : case OPT_Wsizeof_array_div:
72 : 111727620 : case OPT_Wstrict_aliasing:
73 : 111727620 : case OPT_Wunused:
74 : 111727620 : case OPT_Wunused_function:
75 : 111727620 : case OPT_Wunused_but_set_variable:
76 : 111727620 : case OPT_Wunused_variable:
77 : 111727620 : case OPT_Wunused_but_set_parameter:
78 : 111727620 : m_bits = NW_LEXICAL;
79 : 111727620 : break;
80 : :
81 : : /* Access warning group. */
82 : 835430 : case OPT_Warray_bounds_:
83 : 835430 : case OPT_Wformat_overflow_:
84 : 835430 : case OPT_Wformat_truncation_:
85 : 835430 : case OPT_Wrestrict:
86 : 835430 : case OPT_Wsizeof_pointer_memaccess:
87 : 835430 : case OPT_Wstrict_aliasing_:
88 : 835430 : case OPT_Wstringop_overflow_:
89 : 835430 : case OPT_Wstringop_overread:
90 : 835430 : case OPT_Wstringop_truncation:
91 : 835430 : m_bits = NW_ACCESS;
92 : 835430 : break;
93 : :
94 : : /* Initialization warning group. */
95 : 1779001 : case OPT_Winit_self:
96 : 1779001 : case OPT_Wuninitialized:
97 : 1779001 : case OPT_Wmaybe_uninitialized:
98 : 1779001 : m_bits = NW_UNINIT;
99 : 1779001 : break;
100 : :
101 : 734238 : case OPT_Wdangling_pointer_:
102 : 734238 : case OPT_Wreturn_local_addr:
103 : 734238 : case OPT_Wuse_after_free_:
104 : 734238 : m_bits = NW_DANGLING;
105 : 734238 : break;
106 : :
107 : 280011902 : case OPT_Wpessimizing_move:
108 : 280011902 : case OPT_Wredundant_move:
109 : 280011902 : m_bits = NW_REDUNDANT;
110 : 280011902 : break;
111 : :
112 : 1243125 : default:
113 : : /* A catchall group for everything else. */
114 : 1243125 : m_bits = NW_OTHER;
115 : : }
116 : 430924530 : }
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 : 44580 : warning_suppressed_at (location_t loc, opt_code opt /* = all_warnings */)
127 : : {
128 : 44580 : gcc_checking_assert (!RESERVED_LOCATION_P (loc));
129 : :
130 : 44580 : if (!nowarn_map)
131 : : return false;
132 : :
133 : 44429 : if (const nowarn_spec_t* const pspec = nowarn_map->get (loc))
134 : : {
135 : 24093 : const nowarn_spec_t optspec (opt);
136 : 24093 : 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 : 317606566 : suppress_warning_at (location_t loc, opt_code opt /* = all_warnings */,
150 : : bool supp /* = true */)
151 : : {
152 : 317606566 : gcc_checking_assert (!RESERVED_LOCATION_P (loc));
153 : :
154 : 317695906 : const nowarn_spec_t optspec (supp ? opt : opt_code ());
155 : :
156 : 317606566 : if (nowarn_spec_t *pspec = nowarn_map ? nowarn_map->get (loc) : NULL)
157 : : {
158 : 97421750 : if (supp)
159 : : {
160 : 97418765 : *pspec |= optspec;
161 : 97418765 : 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 : 220184816 : if (!supp || opt == no_warning)
173 : : return false;
174 : :
175 : 220098461 : if (!nowarn_map)
176 : 175996 : nowarn_map = nowarn_map_t::create_ggc (32);
177 : :
178 : 220098461 : nowarn_map->put (loc, optspec);
179 : 220098461 : return true;
180 : : }
181 : :
182 : : /* Change the warning disposition for LOC to match OPTSPEC. */
183 : :
184 : : void
185 : 294732 : put_warning_spec_at (location_t loc, unsigned bits)
186 : : {
187 : 294732 : gcc_checking_assert (!RESERVED_LOCATION_P (loc));
188 : :
189 : 294732 : nowarn_spec_t optspec = nowarn_spec_t::from_bits (bits);
190 : 294732 : if (!optspec)
191 : : {
192 : 119944 : if (nowarn_map)
193 : 119879 : nowarn_map->remove (loc);
194 : : }
195 : : else
196 : : {
197 : 174788 : if (!nowarn_map)
198 : 150 : nowarn_map = nowarn_map_t::create_ggc (32);
199 : 174788 : nowarn_map->put (loc, optspec);
200 : : }
201 : 294732 : }
202 : :
203 : : /* Copy the no-warning disposition from one location to another. */
204 : :
205 : : void
206 : 183227257 : copy_warning (location_t to, location_t from)
207 : : {
208 : 183227257 : if (!nowarn_map)
209 : : return;
210 : :
211 : 173346177 : nowarn_spec_t *from_spec;
212 : 173346177 : if (RESERVED_LOCATION_P (from))
213 : : from_spec = NULL;
214 : : else
215 : 165996583 : from_spec = nowarn_map->get (from);
216 : 173346177 : 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 : 166379286 : if (from_spec)
223 : : {
224 : 46369117 : nowarn_spec_t tem = *from_spec;
225 : 46369117 : nowarn_map->put (to, tem);
226 : : }
227 : : else
228 : 120010169 : nowarn_map->remove (to);
229 : : }
230 : : }
|