Branch data Line data Source code
1 : : /* Various diagnostic subroutines for the GNU C language.
2 : : Copyright (C) 2000-2025 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 : 736 : pedwarn_c23 (location_t location,
36 : : diagnostics::option_id option_id,
37 : : const char *gmsgid, ...)
38 : : {
39 : 736 : diagnostics::diagnostic_info diagnostic;
40 : 736 : va_list ap;
41 : 736 : bool warned = false;
42 : 736 : rich_location richloc (line_table, location);
43 : :
44 : 736 : va_start (ap, gmsgid);
45 : : /* If desired, issue the C23/C2Y compat warning, which is more specific
46 : : than -pedantic. */
47 : 736 : if (warn_c23_c2y_compat > 0)
48 : : {
49 : 108 : diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
50 : 108 : (pedantic && !flag_isoc2y)
51 : : ? diagnostics::kind::pedwarn
52 : : : diagnostics::kind::warning);
53 : 108 : diagnostic.m_option_id = OPT_Wc23_c2y_compat;
54 : 108 : warned = diagnostic_report_diagnostic (global_dc, &diagnostic);
55 : : }
56 : : /* -Wno-c23-c2y-compat suppresses even the pedwarns. */
57 : 628 : else if (warn_c23_c2y_compat == 0)
58 : : ;
59 : : /* For -pedantic outside C2Y, issue a pedwarn. */
60 : 576 : else if (pedantic && !flag_isoc2y)
61 : : {
62 : 110 : diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
63 : : diagnostics::kind::pedwarn);
64 : 110 : diagnostic.m_option_id = option_id;
65 : 110 : warned = diagnostic_report_diagnostic (global_dc, &diagnostic);
66 : : }
67 : 736 : va_end (ap);
68 : 1472 : return warned;
69 : 736 : }
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 : 166955 : pedwarn_c11 (location_t location,
82 : : diagnostics::option_id option_id,
83 : : const char *gmsgid, ...)
84 : : {
85 : 166955 : diagnostics::diagnostic_info diagnostic;
86 : 166955 : va_list ap;
87 : 166955 : bool warned = false;
88 : 166955 : rich_location richloc (line_table, location);
89 : :
90 : 166955 : 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 : 166955 : if (warn_c11_c23_compat > 0 || (option_id.m_idx != OPT_Wpedantic
94 : 686 : && option_id.m_idx != OPT_Wc11_c23_compat))
95 : : {
96 : 811 : diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
97 : 811 : (pedantic && !flag_isoc23)
98 : : ? diagnostics::kind::pedwarn
99 : : : diagnostics::kind::warning);
100 : 811 : if (option_id == OPT_Wpedantic)
101 : 121 : diagnostic.m_option_id = OPT_Wc11_c23_compat;
102 : : else
103 : 690 : diagnostic.m_option_id = option_id;
104 : 811 : warned = diagnostic_report_diagnostic (global_dc, &diagnostic);
105 : : }
106 : : /* -Wno-c11-c23-compat suppresses even the pedwarns. */
107 : 166144 : else if (warn_c11_c23_compat == 0)
108 : : ;
109 : : /* For -pedantic outside C23, issue a pedwarn. */
110 : 165967 : 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 : 166955 : va_end (ap);
118 : 333910 : return warned;
119 : 166955 : }
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 : 70883 : pedwarn_c99 (location_t location,
129 : : diagnostics::option_id option_id,
130 : : const char *gmsgid, ...)
131 : : {
132 : 70883 : diagnostics::diagnostic_info diagnostic;
133 : 70883 : va_list ap;
134 : 70883 : bool warned = false;
135 : 70883 : rich_location richloc (line_table, location);
136 : :
137 : 70883 : va_start (ap, gmsgid);
138 : : /* If desired, issue the C99/C11 compat warning, which is more specific
139 : : than -pedantic. */
140 : 70883 : 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 : 70830 : else if (warn_c99_c11_compat == 0)
151 : : ;
152 : : /* For -pedantic outside C11, issue a pedwarn. */
153 : 64764 : 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 : 70883 : va_end (ap);
161 : 141766 : return warned;
162 : 70883 : }
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 : 4441185 : pedwarn_c90 (location_t location,
173 : : diagnostics::option_id option_id,
174 : : const char *gmsgid, ...)
175 : : {
176 : 4441185 : diagnostics::diagnostic_info diagnostic;
177 : 4441185 : va_list ap;
178 : 4441185 : bool warned = false;
179 : 4441185 : rich_location richloc (line_table, location);
180 : :
181 : 4441185 : va_start (ap, gmsgid);
182 : : /* Warnings such as -Wvla are the most specific ones. */
183 : 4441185 : if (option_id.m_idx != OPT_Wpedantic)
184 : : {
185 : 3213461 : int opt_var = *(int *) option_flag_var (option_id.m_idx, &global_options);
186 : 3213461 : if (opt_var == 0)
187 : 2889084 : goto out;
188 : 324377 : 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 : 1551153 : 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 : 1551086 : else if (warn_c90_c99_compat == 0)
213 : : ;
214 : : /* For -pedantic outside C99, issue a pedwarn. */
215 : 1115551 : 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 : 1115150 : out:
224 : 4441185 : va_end (ap);
225 : 8882370 : return warned;
226 : 4441185 : }
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 : }
|