]>
Commit | Line | Data |
---|---|---|
7036e9ef MS |
1 | /* Functions to enable and disable individual warnings on an expression |
2 | and statement basis. | |
7adcbafe | 3 | Copyright (C) 2021-2022 Free Software Foundation, Inc. |
7036e9ef MS |
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 | 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 | switch (opt) | |
41 | { | |
42 | case no_warning: | |
43 | m_bits = 0; | |
44 | break; | |
45 | ||
46 | case all_warnings: | |
47 | m_bits = -1; | |
48 | break; | |
49 | ||
50 | /* Flow-sensitive warnings about pointer problems issued by both | |
51 | front ends and the middle end. */ | |
52 | case OPT_Waddress: | |
53 | case OPT_Wnonnull: | |
54 | m_bits = NW_NONNULL; | |
55 | break; | |
56 | ||
57 | /* Flow-sensitive warnings about arithmetic overflow issued by both | |
58 | front ends and the middle end. */ | |
59 | case OPT_Woverflow: | |
60 | case OPT_Wshift_count_negative: | |
61 | case OPT_Wshift_count_overflow: | |
62 | case OPT_Wstrict_overflow: | |
63 | m_bits = NW_VFLOW; | |
64 | break; | |
65 | ||
66 | /* Lexical warnings issued by front ends. */ | |
67 | case OPT_Wabi: | |
68 | case OPT_Wlogical_op: | |
69 | case OPT_Wparentheses: | |
70 | case OPT_Wreturn_type: | |
71 | case OPT_Wsizeof_array_div: | |
72 | case OPT_Wstrict_aliasing: | |
73 | case OPT_Wunused: | |
74 | case OPT_Wunused_function: | |
75 | case OPT_Wunused_but_set_variable: | |
76 | case OPT_Wunused_variable: | |
77 | case OPT_Wunused_but_set_parameter: | |
78 | m_bits = NW_LEXICAL; | |
79 | break; | |
80 | ||
81 | /* Access warning group. */ | |
82 | case OPT_Warray_bounds: | |
83 | case OPT_Warray_bounds_: | |
84 | case OPT_Wformat_overflow_: | |
85 | case OPT_Wformat_truncation_: | |
86 | case OPT_Wrestrict: | |
81d6cdd3 | 87 | case OPT_Wsizeof_pointer_memaccess: |
7036e9ef MS |
88 | case OPT_Wstrict_aliasing_: |
89 | case OPT_Wstringop_overflow_: | |
90 | case OPT_Wstringop_overread: | |
91 | case OPT_Wstringop_truncation: | |
92 | m_bits = NW_ACCESS; | |
93 | break; | |
94 | ||
95 | /* Initialization warning group. */ | |
96 | case OPT_Winit_self: | |
97 | case OPT_Wuninitialized: | |
98 | case OPT_Wmaybe_uninitialized: | |
99 | m_bits = NW_UNINIT; | |
100 | break; | |
101 | ||
671a2836 MS |
102 | case OPT_Wreturn_local_addr: |
103 | case OPT_Wuse_after_free_: | |
104 | m_bits = NW_DANGLING; | |
105 | break; | |
106 | ||
7036e9ef MS |
107 | default: |
108 | /* A catchall group for everything else. */ | |
109 | m_bits = NW_OTHER; | |
110 | } | |
111 | } | |
112 | ||
19853922 | 113 | /* A mapping from a 'location_t' to the warning spec set for it. */ |
7036e9ef | 114 | |
f861ed8b | 115 | GTY(()) nowarn_map_t *nowarn_map; |
7036e9ef MS |
116 | |
117 | /* Return the no-warning disposition for location LOC and option OPT | |
118 | or for all/any otions by default. */ | |
119 | ||
120 | bool | |
121 | warning_suppressed_at (location_t loc, opt_code opt /* = all_warnings */) | |
122 | { | |
6c79057f TS |
123 | gcc_checking_assert (!RESERVED_LOCATION_P (loc)); |
124 | ||
7036e9ef MS |
125 | if (!nowarn_map) |
126 | return false; | |
127 | ||
128 | if (const nowarn_spec_t* const pspec = nowarn_map->get (loc)) | |
129 | { | |
130 | const nowarn_spec_t optspec (opt); | |
131 | return *pspec & optspec; | |
132 | } | |
133 | ||
134 | return false; | |
135 | } | |
136 | ||
137 | /* Change the supression of warnings for location LOC. | |
138 | OPT controls which warnings are affected. | |
139 | The wildcard OPT of -1 controls all warnings. | |
140 | If SUPP is true (the default), enable the suppression of the warnings. | |
141 | If SUPP is false, disable the suppression of the warnings. */ | |
142 | ||
143 | bool | |
144 | suppress_warning_at (location_t loc, opt_code opt /* = all_warnings */, | |
145 | bool supp /* = true */) | |
146 | { | |
6c79057f TS |
147 | gcc_checking_assert (!RESERVED_LOCATION_P (loc)); |
148 | ||
7036e9ef MS |
149 | const nowarn_spec_t optspec (supp ? opt : opt_code ()); |
150 | ||
151 | if (nowarn_spec_t *pspec = nowarn_map ? nowarn_map->get (loc) : NULL) | |
152 | { | |
153 | if (supp) | |
154 | { | |
155 | *pspec |= optspec; | |
156 | return true; | |
157 | } | |
158 | ||
159 | *pspec &= optspec; | |
160 | if (*pspec) | |
161 | return true; | |
162 | ||
163 | nowarn_map->remove (loc); | |
164 | return false; | |
165 | } | |
166 | ||
167 | if (!supp || opt == no_warning) | |
168 | return false; | |
169 | ||
170 | if (!nowarn_map) | |
f861ed8b | 171 | nowarn_map = nowarn_map_t::create_ggc (32); |
7036e9ef MS |
172 | |
173 | nowarn_map->put (loc, optspec); | |
174 | return true; | |
175 | } | |
176 | ||
177 | /* Copy the no-warning disposition from one location to another. */ | |
178 | ||
179 | void | |
180 | copy_warning (location_t to, location_t from) | |
181 | { | |
182 | if (!nowarn_map) | |
183 | return; | |
184 | ||
6c79057f TS |
185 | nowarn_spec_t *from_spec; |
186 | if (RESERVED_LOCATION_P (from)) | |
187 | from_spec = NULL; | |
188 | else | |
189 | from_spec = nowarn_map->get (from); | |
190 | if (RESERVED_LOCATION_P (to)) | |
191 | /* We cannot set no-warning dispositions for 'to', so we have no chance but | |
192 | lose those potentially set for 'from'. */ | |
193 | ; | |
7036e9ef | 194 | else |
6c79057f TS |
195 | { |
196 | if (from_spec) | |
197 | nowarn_map->put (to, *from_spec); | |
198 | else | |
199 | nowarn_map->remove (to); | |
200 | } | |
7036e9ef | 201 | } |