Line data Source code
1 : /* Various diagnostic subroutines for the GNU C language.
2 : Copyright (C) 2000-2026 Free Software Foundation, Inc.
3 : Contributed by Gabriel Dos Reis <gdr@codesourcery.com>
4 :
5 : This file is part of GCC.
6 :
7 : GCC is free software; you can redistribute it and/or modify it under
8 : the terms of the GNU General Public License as published by the Free
9 : Software Foundation; either version 3, or (at your option) any later
10 : version.
11 :
12 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 : for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with GCC; see the file COPYING3. If not see
19 : <http://www.gnu.org/licenses/>. */
20 :
21 : #include "config.h"
22 : #include "system.h"
23 : #include "coretypes.h"
24 : #include "tm.h"
25 : #include "c-tree.h"
26 : #include "opts.h"
27 :
28 : /* Issue an ISO C23 pedantic warning MSGID if -pedantic outside C2Y mode,
29 : otherwise issue warning MSGID if -Wc23-c2y-compat is specified.
30 : This function is supposed to be used for matters that are allowed in
31 : ISO C2Y but not supported in ISO C23, thus we explicitly don't pedwarn
32 : when C2Y is specified. */
33 :
34 : bool
35 1036 : pedwarn_c23 (location_t location,
36 : diagnostics::option_id option_id,
37 : const char *gmsgid, ...)
38 : {
39 1036 : diagnostics::diagnostic_info diagnostic;
40 1036 : va_list ap;
41 1036 : bool warned = false;
42 1036 : rich_location richloc (line_table, location);
43 :
44 1036 : va_start (ap, gmsgid);
45 : /* If desired, issue the C23/C2Y compat warning, which is more specific
46 : than -pedantic. */
47 1036 : if (warn_c23_c2y_compat > 0)
48 : {
49 185 : diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
50 185 : (pedantic && !flag_isoc2y)
51 : ? diagnostics::kind::pedwarn
52 : : diagnostics::kind::warning);
53 185 : diagnostic.m_option_id = OPT_Wc23_c2y_compat;
54 185 : warned = diagnostic_report_diagnostic (global_dc, &diagnostic);
55 : }
56 : /* -Wno-c23-c2y-compat suppresses even the pedwarns. */
57 851 : else if (warn_c23_c2y_compat == 0)
58 : ;
59 : /* For -pedantic outside C2Y, issue a pedwarn. */
60 760 : else if (pedantic && !flag_isoc2y)
61 : {
62 190 : diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
63 : diagnostics::kind::pedwarn);
64 190 : diagnostic.m_option_id = option_id;
65 190 : warned = diagnostic_report_diagnostic (global_dc, &diagnostic);
66 : }
67 1036 : va_end (ap);
68 2072 : return warned;
69 1036 : }
70 :
71 : /* Issue an ISO C11 pedantic warning MSGID if -pedantic outside C23 mode,
72 : otherwise issue warning MSGID if -Wc11-c23-compat is specified.
73 : This function is supposed to be used for matters that are allowed in
74 : ISO C23 but not supported in ISO C11, thus we explicitly don't pedwarn
75 : when C23 is specified.
76 :
77 : Additionally, warn if OPTION_ID is not OPT_Wpedantic nor
78 : OPT_Wc11_c23_compat. */
79 :
80 : bool
81 170521 : pedwarn_c11 (location_t location,
82 : diagnostics::option_id option_id,
83 : const char *gmsgid, ...)
84 : {
85 170521 : diagnostics::diagnostic_info diagnostic;
86 170521 : va_list ap;
87 170521 : bool warned = false;
88 170521 : rich_location richloc (line_table, location);
89 :
90 170521 : va_start (ap, gmsgid);
91 : /* If desired, issue the C11/C23 compat warning, which is more specific than
92 : -pedantic, or the warning specified by option_id. */
93 170521 : if (warn_c11_c23_compat > 0 || (option_id.m_idx != OPT_Wpedantic
94 746 : && option_id.m_idx != OPT_Wc11_c23_compat))
95 : {
96 871 : diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
97 871 : (pedantic && !flag_isoc23)
98 : ? diagnostics::kind::pedwarn
99 : : diagnostics::kind::warning);
100 871 : if (option_id == OPT_Wpedantic)
101 121 : diagnostic.m_option_id = OPT_Wc11_c23_compat;
102 : else
103 750 : diagnostic.m_option_id = option_id;
104 871 : warned = diagnostic_report_diagnostic (global_dc, &diagnostic);
105 : }
106 : /* -Wno-c11-c23-compat suppresses even the pedwarns. */
107 169650 : else if (warn_c11_c23_compat == 0)
108 : ;
109 : /* For -pedantic outside C23, issue a pedwarn. */
110 169473 : else if (pedantic && !flag_isoc23)
111 : {
112 262 : diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
113 : diagnostics::kind::pedwarn);
114 262 : diagnostic.m_option_id = option_id;
115 262 : warned = diagnostic_report_diagnostic (global_dc, &diagnostic);
116 : }
117 170521 : va_end (ap);
118 341042 : return warned;
119 170521 : }
120 :
121 : /* Issue an ISO C99 pedantic warning MSGID if -pedantic outside C11 mode,
122 : otherwise issue warning MSGID if -Wc99-c11-compat is specified.
123 : This function is supposed to be used for matters that are allowed in
124 : ISO C11 but not supported in ISO C99, thus we explicitly don't pedwarn
125 : when C11 is specified. */
126 :
127 : bool
128 73660 : pedwarn_c99 (location_t location,
129 : diagnostics::option_id option_id,
130 : const char *gmsgid, ...)
131 : {
132 73660 : diagnostics::diagnostic_info diagnostic;
133 73660 : va_list ap;
134 73660 : bool warned = false;
135 73660 : rich_location richloc (line_table, location);
136 :
137 73660 : va_start (ap, gmsgid);
138 : /* If desired, issue the C99/C11 compat warning, which is more specific
139 : than -pedantic. */
140 73660 : if (warn_c99_c11_compat > 0)
141 : {
142 53 : diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
143 53 : (pedantic && !flag_isoc11)
144 : ? diagnostics::kind::pedwarn
145 : : diagnostics::kind::warning);
146 53 : diagnostic.m_option_id = OPT_Wc99_c11_compat;
147 53 : warned = diagnostic_report_diagnostic (global_dc, &diagnostic);
148 : }
149 : /* -Wno-c99-c11-compat suppresses even the pedwarns. */
150 73607 : else if (warn_c99_c11_compat == 0)
151 : ;
152 : /* For -pedantic outside C11, issue a pedwarn. */
153 67313 : else if (pedantic && !flag_isoc11)
154 : {
155 81 : diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
156 : diagnostics::kind::pedwarn);
157 81 : diagnostic.m_option_id = option_id;
158 81 : warned = diagnostic_report_diagnostic (global_dc, &diagnostic);
159 : }
160 73660 : va_end (ap);
161 147320 : return warned;
162 73660 : }
163 :
164 : /* Issue an ISO C90 pedantic warning MSGID if -pedantic outside C99 mode,
165 : otherwise issue warning MSGID if -Wc90-c99-compat is specified, or if
166 : a specific option such as -Wlong-long is specified.
167 : This function is supposed to be used for matters that are allowed in
168 : ISO C99 but not supported in ISO C90, thus we explicitly don't pedwarn
169 : when C99 is specified. (There is no flag_c90.) */
170 :
171 : bool
172 4531996 : pedwarn_c90 (location_t location,
173 : diagnostics::option_id option_id,
174 : const char *gmsgid, ...)
175 : {
176 4531996 : diagnostics::diagnostic_info diagnostic;
177 4531996 : va_list ap;
178 4531996 : bool warned = false;
179 4531996 : rich_location richloc (line_table, location);
180 :
181 4531996 : va_start (ap, gmsgid);
182 : /* Warnings such as -Wvla are the most specific ones. */
183 4531996 : if (option_id.m_idx != OPT_Wpedantic)
184 : {
185 3277371 : int opt_var = *(int *) option_flag_var (option_id.m_idx, &global_options);
186 3277371 : if (opt_var == 0)
187 2944879 : goto out;
188 332492 : else if (opt_var > 0)
189 : {
190 948 : diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
191 948 : (pedantic && !flag_isoc99)
192 : ? diagnostics::kind::pedwarn
193 : : diagnostics::kind::warning);
194 948 : diagnostic.m_option_id = option_id;
195 948 : diagnostic_report_diagnostic (global_dc, &diagnostic);
196 948 : warned = true;
197 948 : goto out;
198 : }
199 : }
200 : /* Maybe we want to issue the C90/C99 compat warning, which is more
201 : specific than -pedantic. */
202 1586169 : if (warn_c90_c99_compat > 0)
203 : {
204 67 : diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
205 67 : (pedantic && !flag_isoc99)
206 : ? diagnostics::kind::pedwarn
207 : : diagnostics::kind::warning);
208 67 : diagnostic.m_option_id = OPT_Wc90_c99_compat;
209 67 : diagnostic_report_diagnostic (global_dc, &diagnostic);
210 : }
211 : /* -Wno-c90-c99-compat suppresses the pedwarns. */
212 1586102 : else if (warn_c90_c99_compat == 0)
213 : ;
214 : /* For -pedantic outside C99, issue a pedwarn. */
215 1140907 : else if (pedantic && !flag_isoc99)
216 : {
217 401 : diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
218 : diagnostics::kind::pedwarn);
219 401 : diagnostic.m_option_id = option_id;
220 401 : diagnostic_report_diagnostic (global_dc, &diagnostic);
221 401 : warned = true;
222 : }
223 1140506 : out:
224 4531996 : va_end (ap);
225 9063992 : return warned;
226 4531996 : }
227 :
228 : /* Determine in which version of the standard IDENTIFIER
229 : became a keyword. */
230 :
231 : static const char *
232 177 : get_std_for_keyword (tree identifier)
233 : {
234 177 : switch (C_RID_CODE (identifier))
235 : {
236 0 : default:
237 0 : gcc_unreachable ();
238 : case RID_FALSE:
239 : case RID_TRUE:
240 : return "-std=c23";
241 175 : case RID_BOOL:
242 175 : if (IDENTIFIER_POINTER (identifier)[0] == 'b')
243 : /* "bool". */
244 : return "-std=c23";
245 : else
246 : /* "_Bool". */
247 173 : return "-std=c99";
248 : }
249 : }
250 :
251 : /* Issue a note to the user at LOC that KEYWORD_ID is a keyword
252 : in STD_OPTION version of the standard onwards. */
253 :
254 : void
255 177 : add_note_about_new_keyword (location_t loc,
256 : tree keyword_id)
257 : {
258 177 : gcc_assert (TREE_CODE (keyword_id) == IDENTIFIER_NODE);
259 177 : const char *std_option = get_std_for_keyword (keyword_id);
260 177 : inform (loc, "%qs is a keyword with %qs onwards",
261 177 : IDENTIFIER_POINTER (keyword_id), std_option);
262 177 : }
|