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 : : diagnostic_option_id option_id,
37 : : const char *gmsgid, ...)
38 : : {
39 : 736 : 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 : : ? DK_PEDWARN : DK_WARNING);
52 : 108 : diagnostic.option_id = OPT_Wc23_c2y_compat;
53 : 108 : warned = diagnostic_report_diagnostic (global_dc, &diagnostic);
54 : : }
55 : : /* -Wno-c23-c2y-compat suppresses even the pedwarns. */
56 : 628 : else if (warn_c23_c2y_compat == 0)
57 : : ;
58 : : /* For -pedantic outside C2Y, issue a pedwarn. */
59 : 576 : else if (pedantic && !flag_isoc2y)
60 : : {
61 : 110 : diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_PEDWARN);
62 : 110 : diagnostic.option_id = option_id;
63 : 110 : warned = diagnostic_report_diagnostic (global_dc, &diagnostic);
64 : : }
65 : 736 : va_end (ap);
66 : 1472 : return warned;
67 : 736 : }
68 : :
69 : : /* Issue an ISO C11 pedantic warning MSGID if -pedantic outside C23 mode,
70 : : otherwise issue warning MSGID if -Wc11-c23-compat is specified.
71 : : This function is supposed to be used for matters that are allowed in
72 : : ISO C23 but not supported in ISO C11, thus we explicitly don't pedwarn
73 : : when C23 is specified.
74 : :
75 : : Additionally, warn if OPTION_ID is not OPT_Wpedantic nor
76 : : OPT_Wc11_c23_compat. */
77 : :
78 : : bool
79 : 166645 : pedwarn_c11 (location_t location,
80 : : diagnostic_option_id option_id,
81 : : const char *gmsgid, ...)
82 : : {
83 : 166645 : diagnostic_info diagnostic;
84 : 166645 : va_list ap;
85 : 166645 : bool warned = false;
86 : 166645 : rich_location richloc (line_table, location);
87 : :
88 : 166645 : va_start (ap, gmsgid);
89 : : /* If desired, issue the C11/C23 compat warning, which is more specific than
90 : : -pedantic, or the warning specified by option_id. */
91 : 166645 : if (warn_c11_c23_compat > 0 || (option_id.m_idx != OPT_Wpedantic
92 : 662 : && option_id.m_idx != OPT_Wc11_c23_compat))
93 : : {
94 : 787 : diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
95 : 787 : (pedantic && !flag_isoc23)
96 : : ? DK_PEDWARN : DK_WARNING);
97 : 787 : if (option_id == OPT_Wpedantic)
98 : 121 : diagnostic.option_id = OPT_Wc11_c23_compat;
99 : : else
100 : 666 : diagnostic.option_id = option_id;
101 : 787 : warned = diagnostic_report_diagnostic (global_dc, &diagnostic);
102 : : }
103 : : /* -Wno-c11-c23-compat suppresses even the pedwarns. */
104 : 165858 : else if (warn_c11_c23_compat == 0)
105 : : ;
106 : : /* For -pedantic outside C23, issue a pedwarn. */
107 : 165681 : else if (pedantic && !flag_isoc23)
108 : : {
109 : 262 : diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_PEDWARN);
110 : 262 : diagnostic.option_id = option_id;
111 : 262 : warned = diagnostic_report_diagnostic (global_dc, &diagnostic);
112 : : }
113 : 166645 : va_end (ap);
114 : 333290 : return warned;
115 : 166645 : }
116 : :
117 : : /* Issue an ISO C99 pedantic warning MSGID if -pedantic outside C11 mode,
118 : : otherwise issue warning MSGID if -Wc99-c11-compat is specified.
119 : : This function is supposed to be used for matters that are allowed in
120 : : ISO C11 but not supported in ISO C99, thus we explicitly don't pedwarn
121 : : when C11 is specified. */
122 : :
123 : : bool
124 : 70713 : pedwarn_c99 (location_t location,
125 : : diagnostic_option_id option_id,
126 : : const char *gmsgid, ...)
127 : : {
128 : 70713 : diagnostic_info diagnostic;
129 : 70713 : va_list ap;
130 : 70713 : bool warned = false;
131 : 70713 : rich_location richloc (line_table, location);
132 : :
133 : 70713 : va_start (ap, gmsgid);
134 : : /* If desired, issue the C99/C11 compat warning, which is more specific
135 : : than -pedantic. */
136 : 70713 : if (warn_c99_c11_compat > 0)
137 : : {
138 : 53 : diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
139 : 53 : (pedantic && !flag_isoc11)
140 : : ? DK_PEDWARN : DK_WARNING);
141 : 53 : diagnostic.option_id = OPT_Wc99_c11_compat;
142 : 53 : warned = diagnostic_report_diagnostic (global_dc, &diagnostic);
143 : : }
144 : : /* -Wno-c99-c11-compat suppresses even the pedwarns. */
145 : 70660 : else if (warn_c99_c11_compat == 0)
146 : : ;
147 : : /* For -pedantic outside C11, issue a pedwarn. */
148 : 64661 : else if (pedantic && !flag_isoc11)
149 : : {
150 : 81 : diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_PEDWARN);
151 : 81 : diagnostic.option_id = option_id;
152 : 81 : warned = diagnostic_report_diagnostic (global_dc, &diagnostic);
153 : : }
154 : 70713 : va_end (ap);
155 : 141426 : return warned;
156 : 70713 : }
157 : :
158 : : /* Issue an ISO C90 pedantic warning MSGID if -pedantic outside C99 mode,
159 : : otherwise issue warning MSGID if -Wc90-c99-compat is specified, or if
160 : : a specific option such as -Wlong-long is specified.
161 : : This function is supposed to be used for matters that are allowed in
162 : : ISO C99 but not supported in ISO C90, thus we explicitly don't pedwarn
163 : : when C99 is specified. (There is no flag_c90.) */
164 : :
165 : : bool
166 : 4247871 : pedwarn_c90 (location_t location,
167 : : diagnostic_option_id option_id,
168 : : const char *gmsgid, ...)
169 : : {
170 : 4247871 : diagnostic_info diagnostic;
171 : 4247871 : va_list ap;
172 : 4247871 : bool warned = false;
173 : 4247871 : rich_location richloc (line_table, location);
174 : :
175 : 4247871 : va_start (ap, gmsgid);
176 : : /* Warnings such as -Wvla are the most specific ones. */
177 : 4247871 : if (option_id.m_idx != OPT_Wpedantic)
178 : : {
179 : 3022035 : int opt_var = *(int *) option_flag_var (option_id.m_idx, &global_options);
180 : 3022035 : if (opt_var == 0)
181 : 2698292 : goto out;
182 : 323743 : else if (opt_var > 0)
183 : : {
184 : 948 : diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
185 : 948 : (pedantic && !flag_isoc99)
186 : : ? DK_PEDWARN : DK_WARNING);
187 : 948 : diagnostic.option_id = option_id;
188 : 948 : diagnostic_report_diagnostic (global_dc, &diagnostic);
189 : 948 : warned = true;
190 : 948 : goto out;
191 : : }
192 : : }
193 : : /* Maybe we want to issue the C90/C99 compat warning, which is more
194 : : specific than -pedantic. */
195 : 1548631 : if (warn_c90_c99_compat > 0)
196 : : {
197 : 67 : diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
198 : 67 : (pedantic && !flag_isoc99)
199 : : ? DK_PEDWARN : DK_WARNING);
200 : 67 : diagnostic.option_id = OPT_Wc90_c99_compat;
201 : 67 : diagnostic_report_diagnostic (global_dc, &diagnostic);
202 : : }
203 : : /* -Wno-c90-c99-compat suppresses the pedwarns. */
204 : 1548564 : else if (warn_c90_c99_compat == 0)
205 : : ;
206 : : /* For -pedantic outside C99, issue a pedwarn. */
207 : 1113445 : else if (pedantic && !flag_isoc99)
208 : : {
209 : 401 : diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_PEDWARN);
210 : 401 : diagnostic.option_id = option_id;
211 : 401 : diagnostic_report_diagnostic (global_dc, &diagnostic);
212 : 401 : warned = true;
213 : : }
214 : 1113044 : out:
215 : 4247871 : va_end (ap);
216 : 8495742 : return warned;
217 : 4247871 : }
218 : :
219 : : /* Determine in which version of the standard IDENTIFIER
220 : : became a keyword. */
221 : :
222 : : static const char *
223 : 177 : get_std_for_keyword (tree identifier)
224 : : {
225 : 177 : switch (C_RID_CODE (identifier))
226 : : {
227 : 0 : default:
228 : 0 : gcc_unreachable ();
229 : : case RID_FALSE:
230 : : case RID_TRUE:
231 : : return "-std=c23";
232 : 175 : case RID_BOOL:
233 : 175 : if (IDENTIFIER_POINTER (identifier)[0] == 'b')
234 : : /* "bool". */
235 : : return "-std=c23";
236 : : else
237 : : /* "_Bool". */
238 : 173 : return "-std=c99";
239 : : }
240 : : }
241 : :
242 : : /* Issue a note to the user at LOC that KEYWORD_ID is a keyword
243 : : in STD_OPTION version of the standard onwards. */
244 : :
245 : : void
246 : 177 : add_note_about_new_keyword (location_t loc,
247 : : tree keyword_id)
248 : : {
249 : 177 : gcc_assert (TREE_CODE (keyword_id) == IDENTIFIER_NODE);
250 : 177 : const char *std_option = get_std_for_keyword (keyword_id);
251 : 177 : inform (loc, "%qs is a keyword with %qs onwards",
252 : 177 : IDENTIFIER_POINTER (keyword_id), std_option);
253 : 177 : }
|