err.c revision 1.226 1 1.226 rillig /* $NetBSD: err.c,v 1.226 2024/03/01 19:39:28 rillig Exp $ */
2 1.2 cgd
3 1.1 cgd /*
4 1.1 cgd * Copyright (c) 1994, 1995 Jochen Pohl
5 1.1 cgd * All Rights Reserved.
6 1.1 cgd *
7 1.1 cgd * Redistribution and use in source and binary forms, with or without
8 1.1 cgd * modification, are permitted provided that the following conditions
9 1.1 cgd * are met:
10 1.1 cgd * 1. Redistributions of source code must retain the above copyright
11 1.1 cgd * notice, this list of conditions and the following disclaimer.
12 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 cgd * notice, this list of conditions and the following disclaimer in the
14 1.1 cgd * documentation and/or other materials provided with the distribution.
15 1.1 cgd * 3. All advertising materials mentioning features or use of this software
16 1.1 cgd * must display the following acknowledgement:
17 1.212 rillig * This product includes software developed by Jochen Pohl for
18 1.1 cgd * The NetBSD Project.
19 1.1 cgd * 4. The name of the author may not be used to endorse or promote products
20 1.1 cgd * derived from this software without specific prior written permission.
21 1.1 cgd *
22 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 1.1 cgd * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 1.1 cgd * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 1.1 cgd * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 1.1 cgd * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 1.1 cgd * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 1.1 cgd * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 1.1 cgd * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 1.1 cgd * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 1.1 cgd * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 1.1 cgd */
33 1.1 cgd
34 1.27 jmc #if HAVE_NBTOOL_CONFIG_H
35 1.27 jmc #include "nbtool_config.h"
36 1.27 jmc #endif
37 1.27 jmc
38 1.10 christos #include <sys/cdefs.h>
39 1.166 rillig #if defined(__RCSID)
40 1.226 rillig __RCSID("$NetBSD: err.c,v 1.226 2024/03/01 19:39:28 rillig Exp $");
41 1.1 cgd #endif
42 1.1 cgd
43 1.178 rillig #include <limits.h>
44 1.55 rillig #include <stdarg.h>
45 1.1 cgd #include <stdlib.h>
46 1.178 rillig #include <string.h>
47 1.1 cgd
48 1.1 cgd #include "lint1.h"
49 1.1 cgd
50 1.220 rillig bool seen_error;
51 1.220 rillig bool seen_warning;
52 1.12 christos
53 1.12 christos /* number of syntax errors */
54 1.220 rillig int sytxerr;
55 1.12 christos
56 1.12 christos
57 1.170 rillig static const char *const msgs[] = {
58 1.225 rillig "empty declaration", // 0
59 1.225 rillig "old-style declaration; add 'int'", // 1
60 1.225 rillig "empty declaration", // 2
61 1.225 rillig "'%s' declared in parameter declaration list", // 3
62 1.225 rillig "illegal type combination", // 4
63 1.225 rillig "modifying typedef with '%s'; only qualifiers allowed", // 5
64 1.225 rillig "use 'double' instead of 'long float'", // 6
65 1.225 rillig "only one storage class allowed", // 7
66 1.225 rillig "illegal storage class", // 8
67 1.225 rillig "only 'register' is valid as storage class in parameter", // 9
68 1.225 rillig "duplicate '%s'", // 10
69 1.225 rillig "bit-field initializer out of range", // 11
70 1.225 rillig "compiler takes size of function", // 12
71 1.225 rillig "incomplete enum type '%s'", // 13
72 1.225 rillig "", // 14
73 1.225 rillig "function returns illegal type '%s'", // 15
74 1.225 rillig "array of function is illegal", // 16
75 1.225 rillig "null dimension", // 17
76 1.225 rillig "illegal use of 'void'", // 18
77 1.225 rillig "void type for '%s'", // 19
78 1.225 rillig "negative array dimension (%d)", // 20
79 1.225 rillig "redeclaration of formal parameter '%s'", // 21
80 1.225 rillig "incomplete or misplaced function definition", // 22
81 1.225 rillig "undefined label '%s'", // 23
82 1.225 rillig "cannot initialize function '%s'", // 24
83 1.225 rillig "cannot initialize typedef '%s'", // 25
84 1.225 rillig "cannot initialize extern declaration '%s'", // 26
85 1.225 rillig "redeclaration of '%s'", // 27
86 1.225 rillig "redefinition of '%s'", // 28
87 1.225 rillig "'%s' was previously declared extern, becomes static", // 29
88 1.225 rillig "redeclaration of '%s'; C90 or later require static", // 30
89 1.225 rillig "'%s' has incomplete type '%s'", // 31
90 1.225 rillig "type of parameter '%s' defaults to 'int'", // 32
91 1.225 rillig "duplicate member name '%s'", // 33
92 1.225 rillig "nonportable bit-field type '%s'", // 34
93 1.225 rillig "illegal bit-field type '%s'", // 35
94 1.225 rillig "illegal bit-field size: %d", // 36
95 1.225 rillig "zero size bit-field", // 37
96 1.225 rillig "function illegal in structure or union", // 38
97 1.225 rillig "zero-sized array '%s' in struct requires C99 or later", // 39
98 1.225 rillig "", /* never used */ // 40
99 1.225 rillig "bit-field in union is very unusual", // 41
100 1.225 rillig "forward reference to enum type", // 42
101 1.225 rillig "redefinition of '%s' hides earlier one", // 43
102 1.225 rillig "declaration of '%s %s' introduces new type in C90 or later", // 44
103 1.225 rillig "base type is really '%s %s'", // 45
104 1.225 rillig "%s tag '%s' redeclared as %s", // 46
105 1.225 rillig "zero sized %s is a C99 feature", // 47
106 1.225 rillig "enumeration value '%s' overflows", // 48
107 1.225 rillig "anonymous struct/union members is a C11 feature", // 49
108 1.225 rillig "parameter '%s' has function type, should be pointer", // 50
109 1.225 rillig "parameter mismatch: %d declared, %d defined", // 51
110 1.225 rillig "cannot initialize parameter '%s'", // 52
111 1.225 rillig "declared parameter '%s' is missing", // 53
112 1.225 rillig "trailing ',' in enum declaration requires C99 or later", // 54
113 1.225 rillig "integral constant expression expected", // 55
114 1.225 rillig "integral constant too large", // 56
115 1.225 rillig "enumeration constant '%s' hides parameter", // 57
116 1.225 rillig "type of '%s' does not match prototype", // 58
117 1.225 rillig "formal parameter #%d lacks name", // 59
118 1.225 rillig "void must be sole parameter", // 60
119 1.225 rillig "void parameter '%s' cannot have name", // 61
120 1.225 rillig "function prototype parameters must have types", // 62
121 1.225 rillig "prototype does not match old-style definition", // 63
122 1.225 rillig "()-less function definition", // 64
123 1.225 rillig "'%s' has no named members", // 65
124 1.225 rillig "", // 66
125 1.225 rillig "cannot return incomplete type", // 67
126 1.225 rillig "typedef already qualified with '%s'", // 68
127 1.225 rillig "inappropriate qualifiers with 'void'", // 69
128 1.225 rillig "", /* unused */ // 70
129 1.225 rillig "too many characters in character constant", // 71
130 1.225 rillig "typedef declares no type name", // 72
131 1.225 rillig "empty character constant", // 73
132 1.225 rillig "no hex digits follow \\x", // 74
133 1.225 rillig "overflow in hex escape", // 75
134 1.225 rillig "character escape does not fit in character", // 76
135 1.225 rillig "bad octal digit '%c'", // 77
136 1.225 rillig "", /* unused */ // 78
137 1.225 rillig "dubious escape \\%c", // 79
138 1.225 rillig "dubious escape \\%o", // 80
139 1.225 rillig "\\a undefined in traditional C", // 81
140 1.225 rillig "\\x undefined in traditional C", // 82
141 1.225 rillig "storage class after type is obsolescent", // 83
142 1.225 rillig "C90 to C17 require formal parameter before '...'", // 84
143 1.225 rillig "dubious tag declaration '%s %s'", // 85
144 1.225 rillig "automatic '%s' hides external declaration", // 86
145 1.225 rillig "static '%s' hides external declaration", // 87
146 1.225 rillig "typedef '%s' hides external declaration", // 88
147 1.225 rillig "typedef '%s' redeclared", // 89
148 1.225 rillig "inconsistent redeclaration of extern '%s'", // 90
149 1.225 rillig "declaration of '%s' hides parameter", // 91
150 1.225 rillig "inconsistent redeclaration of static '%s'", // 92
151 1.225 rillig "dubious static function '%s' at block level", // 93
152 1.225 rillig "function '%s' has illegal storage class", // 94
153 1.225 rillig "declaration of '%s' hides earlier one", // 95
154 1.225 rillig "cannot dereference non-pointer type '%s'", // 96
155 1.225 rillig "suffix 'U' is illegal in traditional C", // 97
156 1.225 rillig "suffixes 'F' and 'L' are illegal in traditional C", // 98
157 1.225 rillig "'%s' undefined", // 99
158 1.225 rillig "unary '+' is illegal in traditional C", // 100
159 1.225 rillig "type '%s' does not have member '%s'", // 101
160 1.225 rillig "illegal use of member '%s'", // 102
161 1.225 rillig "left operand of '.' must be struct or union, not '%s'", // 103
162 1.225 rillig "left operand of '->' must be pointer to struct or union, not '%s'", // 104
163 1.225 rillig "non-unique member requires struct/union %s", // 105
164 1.225 rillig "left operand of '->' must be pointer", // 106
165 1.225 rillig "operands of '%s' have incompatible types '%s' and '%s'", // 107
166 1.225 rillig "operand of '%s' has invalid type '%s'", // 108
167 1.225 rillig "void type illegal in expression", // 109
168 1.225 rillig "pointer to function is not allowed here", // 110
169 1.225 rillig "unacceptable operand of '%s'", // 111
170 1.225 rillig "cannot take address of bit-field", // 112
171 1.225 rillig "cannot take address of register '%s'", // 113
172 1.225 rillig "%soperand of '%s' must be lvalue", // 114
173 1.225 rillig "%soperand of '%s' must be modifiable lvalue", // 115
174 1.225 rillig "illegal pointer subtraction", // 116
175 1.225 rillig "bitwise '%s' on signed value possibly nonportable", // 117
176 1.225 rillig "semantics of '%s' change in C90; use explicit cast", // 118
177 1.225 rillig "conversion of '%s' to '%s' is out of range", // 119
178 1.225 rillig "bitwise '%s' on signed value nonportable", // 120
179 1.225 rillig "negative shift", // 121
180 1.225 rillig "shift amount %llu is greater than bit-size %llu of '%s'", // 122
181 1.225 rillig "illegal combination of %s '%s' and %s '%s', op '%s'", // 123
182 1.225 rillig "illegal combination of '%s' and '%s', op '%s'", // 124
183 1.225 rillig "pointers to functions can only be compared for equality", // 125
184 1.225 rillig "incompatible types '%s' and '%s' in conditional", // 126
185 1.225 rillig "'&' before array or function: ignored", // 127
186 1.225 rillig "operands of '%s' have incompatible pointer types to '%s' and '%s'", // 128
187 1.225 rillig "expression has null effect", // 129
188 1.225 rillig "enum type mismatch: '%s' '%s' '%s'", // 130
189 1.225 rillig "conversion to '%s' may sign-extend incorrectly", // 131
190 1.225 rillig "conversion from '%s' to '%s' may lose accuracy", // 132
191 1.225 rillig "conversion of pointer to '%s' loses bits", // 133
192 1.225 rillig "conversion of pointer to '%s' may lose bits", // 134
193 1.225 rillig "converting '%s' to '%s' increases alignment from %u to %u", // 135
194 1.225 rillig "cannot do pointer arithmetic on operand of unknown size", // 136
195 1.225 rillig "", /* unused */ // 137
196 1.225 rillig "unknown operand size, op '%s'", // 138
197 1.225 rillig "division by 0", // 139
198 1.225 rillig "modulus by 0", // 140
199 1.225 rillig "operator '%s' produces integer overflow", // 141
200 1.225 rillig "operator '%s' produces floating point overflow", // 142
201 1.225 rillig "cannot take size/alignment of incomplete type", // 143
202 1.225 rillig "cannot take size/alignment of function type '%s'", // 144
203 1.225 rillig "cannot take size/alignment of bit-field", // 145
204 1.225 rillig "cannot take size/alignment of void", // 146
205 1.225 rillig "invalid cast from '%s' to '%s'", // 147
206 1.225 rillig "improper cast of void expression", // 148
207 1.225 rillig "cannot call '%s', must be a function", // 149
208 1.225 rillig "argument mismatch: %d %s passed, %d expected", // 150
209 1.225 rillig "void expressions may not be arguments, arg #%d", // 151
210 1.225 rillig "argument cannot have unknown size, arg #%d", // 152
211 1.225 rillig "converting '%s' to incompatible '%s' for argument %d", // 153
212 1.225 rillig "illegal combination of %s '%s' and %s '%s', arg #%d", // 154
213 1.225 rillig "passing '%s' to incompatible '%s', arg #%d", // 155
214 1.225 rillig "function expects '%s', passing '%s' for arg #%d", // 156
215 1.225 rillig "C90 treats constant as unsigned", // 157
216 1.225 rillig "'%s' may be used before set", // 158
217 1.225 rillig "assignment in conditional context", // 159
218 1.225 rillig "operator '==' found where '=' was expected", // 160
219 1.225 rillig "constant in conditional context", // 161
220 1.225 rillig "operator '%s' compares '%s' with '%s'", // 162
221 1.225 rillig "a cast does not yield an lvalue", // 163
222 1.225 rillig "assignment of negative constant to unsigned type", // 164
223 1.225 rillig "constant truncated by assignment", // 165
224 1.225 rillig "precision lost in bit-field assignment", // 166
225 1.225 rillig "array subscript cannot be negative: %ld", // 167
226 1.225 rillig "array subscript cannot be > %d: %ld", // 168
227 1.225 rillig "precedence confusion possible: parenthesize!", // 169
228 1.225 rillig "first operand of '?' must have scalar type", // 170
229 1.225 rillig "cannot assign to '%s' from '%s'", // 171
230 1.225 rillig "too many struct/union initializers", // 172
231 1.225 rillig "too many array initializers, expected %d", // 173
232 1.225 rillig "too many initializers", // 174
233 1.225 rillig "initialization of incomplete type '%s'", // 175
234 1.225 rillig "", /* no longer used */ // 176
235 1.225 rillig "non-constant initializer", // 177
236 1.225 rillig "initializer does not fit", // 178
237 1.225 rillig "cannot initialize struct/union with no named member", // 179
238 1.225 rillig "bit-field initializer does not fit", // 180
239 1.225 rillig "{}-enclosed or constant initializer of type '%s' required", // 181
240 1.225 rillig "incompatible pointer types to '%s' and '%s'", // 182
241 1.225 rillig "illegal combination of %s '%s' and %s '%s'", // 183
242 1.225 rillig "illegal combination of '%s' and '%s'", // 184
243 1.225 rillig "cannot initialize '%s' from '%s'", // 185
244 1.225 rillig "bit-field initialization is illegal in traditional C", // 186
245 1.225 rillig "string literal too long (%lu) for target array (%lu)", // 187
246 1.225 rillig "no automatic aggregate initialization in traditional C", // 188
247 1.225 rillig "", /* no longer used */ // 189
248 1.225 rillig "empty array declaration for '%s'", // 190
249 1.225 rillig "'%s' set but not used in function '%s'", // 191
250 1.225 rillig "'%s' unused in function '%s'", // 192
251 1.225 rillig "statement not reached", // 193
252 1.225 rillig "label '%s' redefined", // 194
253 1.225 rillig "case not in switch", // 195
254 1.225 rillig "case label affected by conversion", // 196
255 1.225 rillig "non-constant case expression", // 197
256 1.225 rillig "non-integral case expression", // 198
257 1.225 rillig "duplicate case '%ld' in switch", // 199
258 1.225 rillig "duplicate case '%lu' in switch", // 200
259 1.225 rillig "default outside switch", // 201
260 1.225 rillig "duplicate default in switch", // 202
261 1.225 rillig "case label must be of type 'int' in traditional C", // 203
262 1.225 rillig "controlling expressions must have scalar type", // 204
263 1.225 rillig "switch expression must have integral type", // 205
264 1.225 rillig "enumeration value(s) not handled in switch", // 206
265 1.225 rillig "loop not entered at top", // 207
266 1.225 rillig "break outside loop or switch", // 208
267 1.225 rillig "continue outside loop", // 209
268 1.225 rillig "enum type mismatch between '%s' and '%s' in initialization", // 210
269 1.225 rillig "function has return type '%s' but returns '%s'", // 211
270 1.225 rillig "cannot return incomplete type", // 212
271 1.225 rillig "void function '%s' cannot return value", // 213
272 1.225 rillig "function '%s' expects to return value", // 214
273 1.225 rillig "function '%s' implicitly declared to return int", // 215
274 1.225 rillig "function '%s' has 'return expr' and 'return'", // 216
275 1.225 rillig "function '%s' falls off bottom without returning value", // 217
276 1.225 rillig "C90 treats constant as unsigned, op '%s'", // 218
277 1.225 rillig "concatenated strings are illegal in traditional C", // 219
278 1.225 rillig "fallthrough on case statement", // 220
279 1.225 rillig "initialization of unsigned with negative constant", // 221
280 1.225 rillig "conversion of negative constant to unsigned type", // 222
281 1.225 rillig "end-of-loop code not reached", // 223
282 1.225 rillig "cannot recover from previous errors", // 224
283 1.225 rillig "static function '%s' called but not defined", // 225
284 1.225 rillig "static variable '%s' unused", // 226
285 1.225 rillig "const object '%s' should have initializer", // 227
286 1.225 rillig "function cannot return const or volatile object", // 228
287 1.225 rillig "converting '%s' to '%s' is questionable", // 229
288 1.225 rillig "nonportable character comparison '%s'", // 230
289 1.225 rillig "parameter '%s' unused in function '%s'", // 231
290 1.225 rillig "label '%s' unused in function '%s'", // 232
291 1.225 rillig "struct '%s' never defined", // 233
292 1.225 rillig "union '%s' never defined", // 234
293 1.225 rillig "enum '%s' never defined", // 235
294 1.225 rillig "static function '%s' unused", // 236
295 1.225 rillig "redeclaration of formal parameter '%s'", // 237
296 1.225 rillig "initialization of union is illegal in traditional C", // 238
297 1.225 rillig "constant operand to '!'", // 239
298 1.225 rillig "", /* unused */ // 240
299 1.225 rillig "dubious operation '%s' on enum", // 241
300 1.225 rillig "combination of '%s' and '%s', op '%s'", // 242
301 1.225 rillig "operator '%s' assumes that '%s' is ordered", // 243
302 1.225 rillig "illegal structure pointer combination", // 244
303 1.225 rillig "incompatible structure pointers: '%s' '%s' '%s'", // 245
304 1.225 rillig "dubious conversion of enum to '%s'", // 246
305 1.225 rillig "pointer cast from '%s' to '%s' may be troublesome", // 247
306 1.225 rillig "floating-point constant out of range", // 248
307 1.225 rillig "syntax error '%s'", // 249
308 1.225 rillig "unknown character \\%o", // 250
309 1.225 rillig "malformed integer constant", // 251
310 1.225 rillig "integer constant out of range", // 252
311 1.225 rillig "unterminated character constant", // 253
312 1.225 rillig "newline in string or char constant", // 254
313 1.225 rillig "undefined or invalid '#' directive", // 255
314 1.225 rillig "unterminated comment", // 256
315 1.225 rillig "extra characters in lint comment", // 257
316 1.225 rillig "unterminated string constant", // 258
317 1.225 rillig "argument %d is converted from '%s' to '%s' due to prototype", // 259
318 1.225 rillig "previous declaration of '%s'", // 260
319 1.225 rillig "previous definition of '%s'", // 261
320 1.225 rillig "\\\" inside character constants undefined in traditional C", // 262
321 1.225 rillig "\\? undefined in traditional C", // 263
322 1.225 rillig "\\v undefined in traditional C", // 264
323 1.225 rillig "%s does not support 'long long'", // 265
324 1.225 rillig "'long double' is illegal in traditional C", // 266
325 1.225 rillig "shift amount %u equals bit-size of '%s'", // 267
326 1.225 rillig "variable '%s' declared inline", // 268
327 1.225 rillig "parameter '%s' declared inline", // 269
328 1.225 rillig "function prototypes are illegal in traditional C", // 270
329 1.225 rillig "switch expression must be of type 'int' in traditional C", // 271
330 1.225 rillig "empty translation unit", // 272
331 1.225 rillig "bit-field type '%s' invalid in C90 or later", // 273
332 1.225 rillig "C90 or later forbid comparison of %s with %s", // 274
333 1.225 rillig "cast discards 'const' from type '%s'", // 275
334 1.225 rillig "'__%s__' is illegal for type '%s'", // 276
335 1.225 rillig "initialization of '%s' with '%s'", // 277
336 1.225 rillig "combination of '%s' and '%s', arg #%d", // 278
337 1.225 rillig "combination of '%s' and '%s' in return", // 279
338 1.225 rillig "comment /* %s */ must be outside function", // 280
339 1.225 rillig "duplicate comment /* %s */", // 281
340 1.225 rillig "comment /* %s */ must precede function definition", // 282
341 1.225 rillig "parameter number mismatch in comment /* %s */", // 283
342 1.225 rillig "fallthrough on default statement", // 284
343 1.225 rillig "prototype declaration", // 285
344 1.225 rillig "function definition is not a prototype", // 286
345 1.225 rillig "function declaration is not a prototype", // 287
346 1.225 rillig "dubious use of /* VARARGS */ with /* %s */", // 288
347 1.225 rillig "/* PRINTFLIKE */ and /* SCANFLIKE */ cannot be combined", // 289
348 1.225 rillig "static function '%s' declared but not defined", // 290
349 1.225 rillig "invalid multibyte character", // 291
350 1.225 rillig "cannot concatenate wide and regular string literals", // 292
351 1.225 rillig "parameter %d must be 'char *' for PRINTFLIKE/SCANFLIKE", // 293
352 1.225 rillig "multi-character character constant", // 294
353 1.225 rillig "conversion of '%s' to '%s' is out of range, arg #%d", // 295
354 1.225 rillig "conversion of negative constant to unsigned type, arg #%d", // 296
355 1.225 rillig "conversion to '%s' may sign-extend incorrectly, arg #%d", // 297
356 1.225 rillig "conversion from '%s' to '%s' may lose accuracy, arg #%d", // 298
357 1.225 rillig "prototype does not match old-style definition, arg #%d", // 299
358 1.225 rillig "old-style definition", // 300
359 1.225 rillig "array of incomplete type", // 301
360 1.225 rillig "'%s' returns pointer to automatic object", // 302
361 1.225 rillig "conversion of %s to %s requires a cast", // 303
362 1.225 rillig "conversion of %s to %s requires a cast, arg #%d", // 304
363 1.225 rillig "conversion of %s to %s requires a cast, op %s", // 305
364 1.225 rillig "constant truncated by conversion, op '%s'", // 306
365 1.225 rillig "static variable '%s' set but not used", // 307
366 1.225 rillig "invalid type for _Complex", // 308
367 1.225 rillig "extra bits set to 0 in conversion of '%s' to '%s', op '%s'", // 309
368 1.225 rillig "symbol renaming can't be used on function parameters", // 310
369 1.225 rillig "symbol renaming can't be used on automatic variables", // 311
370 1.225 rillig "%s does not support '//' comments", // 312
371 1.225 rillig "struct or union member name in initializer is a C99 feature", // 313
372 1.225 rillig "", /* never used */ // 314
373 1.225 rillig "GCC style struct or union member name in initializer", // 315
374 1.225 rillig "__FUNCTION__/__PRETTY_FUNCTION__ is a GCC extension", // 316
375 1.225 rillig "__func__ is a C99 feature", // 317
376 1.225 rillig "variable array dimension is a C99/GCC extension", // 318
377 1.225 rillig "compound literals are a C99/GCC extension", // 319
378 1.225 rillig "'({ ... })' is a GCC extension", // 320
379 1.225 rillig "array initializer with designators is a C99 feature", // 321
380 1.225 rillig "zero sized array requires C99 or later", // 322
381 1.225 rillig "continue in 'do ... while (0)' loop", // 323
382 1.225 rillig "suggest cast from '%s' to '%s' on op '%s' to avoid overflow", // 324
383 1.225 rillig "variable declaration in for loop", // 325
384 1.225 rillig "attribute '%s' ignored for '%s'", // 326
385 1.225 rillig "declarations after statements is a C99 feature", // 327
386 1.225 rillig "union cast is a GCC extension", // 328
387 1.225 rillig "type '%s' is not a member of '%s'", // 329
388 1.225 rillig "operand of '%s' must be bool, not '%s'", // 330
389 1.225 rillig "left operand of '%s' must be bool, not '%s'", // 331
390 1.225 rillig "right operand of '%s' must be bool, not '%s'", // 332
391 1.225 rillig "controlling expression must be bool, not '%s'", // 333
392 1.225 rillig "parameter %d expects '%s', gets passed '%s'", // 334
393 1.225 rillig "operand of '%s' must not be bool", // 335
394 1.225 rillig "left operand of '%s' must not be bool", // 336
395 1.225 rillig "right operand of '%s' must not be bool", // 337
396 1.225 rillig "option '%c' should be handled in the switch", // 338
397 1.225 rillig "option '%c' should be listed in the options string", // 339
398 1.225 rillig "initialization with '[a...b]' is a GCC extension", // 340
399 1.225 rillig "argument to '%s' must be 'unsigned char' or EOF, not '%s'", // 341
400 1.225 rillig "argument to '%s' must be cast to 'unsigned char', not to '%s'", // 342
401 1.225 rillig "static array size requires C11 or later", // 343
402 1.225 rillig "bit-field of type plain 'int' has implementation-defined signedness", // 344
403 1.225 rillig "generic selection requires C11 or later", // 345
404 1.225 rillig "call to '%s' effectively discards 'const' from argument", // 346
405 1.225 rillig "redeclaration of '%s' with type '%s', expected '%s'", // 347
406 1.225 rillig "maximum value %d of '%s' does not match maximum array index %d", // 348
407 1.225 rillig "non type argument to alignof is a GCC extension", // 349
408 1.225 rillig "'_Atomic' requires C11 or later", // 350
409 1.225 rillig "missing%s header declaration for '%s'", // 351
410 1.225 rillig "nested 'extern' declaration of '%s'", // 352
411 1.225 rillig "empty initializer braces require C23 or later", // 353
412 1.225 rillig "'_Static_assert' requires C11 or later", // 354
413 1.225 rillig "'_Static_assert' without message requires C23 or later", // 355
414 1.225 rillig "short octal escape '%.*s' followed by digit '%c'", // 356
415 1.226 rillig "hex escape '%.*s' mixes uppercase and lowercase digits", // 357
416 1.226 rillig "hex escape '%.*s' has more than 2 digits", // 358
417 1.226 rillig "missing new-style '\\177' or old-style number base", // 359
418 1.226 rillig "missing new-style number base after '\\177'", // 360
419 1.226 rillig "number base '%.*s' is %ju, should be 8, 10 or 16", // 361
420 1.226 rillig "old-style format contains '\\0'", // 362
421 1.226 rillig "non-printing character '%.*s' in description '%.*s'", // 363
422 1.226 rillig "missing bit position after '%.*s'", // 364
423 1.226 rillig "missing field width after '%.*s'", // 365
424 1.226 rillig "missing '\\0' at the end of '%.*s'", // 366
425 1.226 rillig "empty description in '%.*s'", // 367
426 1.226 rillig "missing comparison value after directive '%.*s'", // 368
427 1.226 rillig "bit position '%.*s' in '%.*s' should be escaped as octal or hex", // 369
428 1.226 rillig "field width '%.*s' in '%.*s' should be escaped as octal or hex", // 370
429 1.226 rillig "bit position '%.*s' (%ju) in '%.*s' out of range %u..%u", // 371
430 1.226 rillig "field width '%.*s' (%ju) in '%.*s' out of range 0..%u", // 372
431 1.226 rillig "bit field end %ju in '%.*s' out of range 0..64", // 373
432 1.226 rillig "unknown directive '%.*s'", // 374
433 1.226 rillig "comparison value '%.*s' (%ju) exceeds field width %ju", // 375
434 1.1 cgd };
435 1.1 cgd
436 1.220 rillig static bool is_suppressed[sizeof(msgs) / sizeof(msgs[0])];
437 1.178 rillig
438 1.104 rillig static struct include_level {
439 1.104 rillig const char *filename;
440 1.104 rillig int lineno;
441 1.104 rillig struct include_level *by;
442 1.104 rillig } *includes;
443 1.104 rillig
444 1.178 rillig void
445 1.194 rillig suppress_messages(const char *p)
446 1.178 rillig {
447 1.194 rillig char *end;
448 1.194 rillig
449 1.194 rillig for (; ch_isdigit(*p); p = end + 1) {
450 1.194 rillig unsigned long id = strtoul(p, &end, 10);
451 1.194 rillig if ((*end != '\0' && *end != ',') ||
452 1.194 rillig id >= sizeof(msgs) / sizeof(msgs[0]) ||
453 1.194 rillig msgs[id][0] == '\0')
454 1.194 rillig break;
455 1.178 rillig
456 1.179 rillig is_suppressed[id] = true;
457 1.194 rillig
458 1.194 rillig if (*end == '\0')
459 1.194 rillig return;
460 1.178 rillig }
461 1.199 rillig errx(1, "invalid message ID '%.*s'", (int)strcspn(p, ","), p);
462 1.178 rillig }
463 1.104 rillig
464 1.104 rillig void
465 1.105 rillig update_location(const char *filename, int lineno, bool is_begin, bool is_end)
466 1.104 rillig {
467 1.104 rillig struct include_level *top;
468 1.104 rillig
469 1.104 rillig top = includes;
470 1.104 rillig if (is_begin && top != NULL)
471 1.104 rillig top->lineno = curr_pos.p_line;
472 1.104 rillig
473 1.104 rillig if (top == NULL || is_begin) {
474 1.104 rillig top = xmalloc(sizeof(*top));
475 1.104 rillig top->filename = filename;
476 1.104 rillig top->lineno = lineno;
477 1.104 rillig top->by = includes;
478 1.104 rillig includes = top;
479 1.104 rillig } else {
480 1.109 rillig if (is_end) {
481 1.104 rillig includes = top->by;
482 1.104 rillig free(top);
483 1.104 rillig top = includes;
484 1.104 rillig }
485 1.123 rillig if (top != NULL) {
486 1.123 rillig top->filename = filename;
487 1.123 rillig top->lineno = lineno;
488 1.123 rillig }
489 1.104 rillig }
490 1.104 rillig }
491 1.104 rillig
492 1.104 rillig static void
493 1.104 rillig print_stack_trace(void)
494 1.104 rillig {
495 1.105 rillig const struct include_level *top;
496 1.104 rillig
497 1.104 rillig if ((top = includes) == NULL)
498 1.104 rillig return;
499 1.105 rillig /*
500 1.105 rillig * Skip the innermost include level since it is already listed in the
501 1.105 rillig * diagnostic itself. Furthermore, its lineno is the line number of
502 1.105 rillig * the last '#' line, not the current line.
503 1.105 rillig */
504 1.104 rillig for (top = top->by; top != NULL; top = top->by)
505 1.104 rillig printf("\tincluded from %s(%d)\n", top->filename, top->lineno);
506 1.104 rillig }
507 1.104 rillig
508 1.1 cgd /*
509 1.56 rillig * If Fflag is not set, lbasename() returns a pointer to the last
510 1.1 cgd * component of the path, otherwise it returns the argument.
511 1.1 cgd */
512 1.1 cgd static const char *
513 1.18 tv lbasename(const char *path)
514 1.1 cgd {
515 1.1 cgd
516 1.1 cgd if (Fflag)
517 1.57 rillig return path;
518 1.1 cgd
519 1.188 rillig const char *base = path;
520 1.188 rillig for (const char *p = path; *p != '\0'; p++)
521 1.188 rillig if (*p == '/')
522 1.188 rillig base = p + 1;
523 1.188 rillig return base;
524 1.1 cgd }
525 1.1 cgd
526 1.210 rillig static FILE *
527 1.210 rillig output_channel(void)
528 1.210 rillig {
529 1.210 rillig return yflag ? stderr : stdout;
530 1.210 rillig }
531 1.210 rillig
532 1.3 jpo static void
533 1.116 rillig verror_at(int msgid, const pos_t *pos, va_list ap)
534 1.3 jpo {
535 1.3 jpo
536 1.179 rillig if (is_suppressed[msgid])
537 1.12 christos return;
538 1.12 christos
539 1.210 rillig FILE *out = output_channel();
540 1.210 rillig (void)fprintf(out, "%s(%d): error: ",
541 1.210 rillig lbasename(pos->p_file), pos->p_line);
542 1.210 rillig (void)vfprintf(out, msgs[msgid], ap);
543 1.210 rillig (void)fprintf(out, " [%d]\n", msgid);
544 1.205 rillig seen_error = true;
545 1.104 rillig print_stack_trace();
546 1.3 jpo }
547 1.3 jpo
548 1.3 jpo static void
549 1.116 rillig vwarning_at(int msgid, const pos_t *pos, va_list ap)
550 1.3 jpo {
551 1.3 jpo
552 1.179 rillig if (is_suppressed[msgid])
553 1.12 christos return;
554 1.12 christos
555 1.132 rillig debug_step("%s: lwarn=%d msgid=%d", __func__, lwarn, msgid);
556 1.115 rillig if (lwarn == LWARN_NONE || lwarn == msgid)
557 1.3 jpo /* this warning is suppressed by a LINTED comment */
558 1.3 jpo return;
559 1.3 jpo
560 1.210 rillig FILE *out = output_channel();
561 1.210 rillig (void)fprintf(out, "%s(%d): warning: ",
562 1.210 rillig lbasename(pos->p_file), pos->p_line);
563 1.210 rillig (void)vfprintf(out, msgs[msgid], ap);
564 1.210 rillig (void)fprintf(out, " [%d]\n", msgid);
565 1.205 rillig seen_warning = true;
566 1.104 rillig print_stack_trace();
567 1.3 jpo }
568 1.3 jpo
569 1.113 rillig static void
570 1.116 rillig vmessage_at(int msgid, const pos_t *pos, va_list ap)
571 1.113 rillig {
572 1.113 rillig
573 1.179 rillig if (is_suppressed[msgid])
574 1.113 rillig return;
575 1.113 rillig
576 1.210 rillig FILE *out = output_channel();
577 1.210 rillig (void)fprintf(out, "%s(%d): ",
578 1.210 rillig lbasename(pos->p_file), pos->p_line);
579 1.210 rillig (void)vfprintf(out, msgs[msgid], ap);
580 1.210 rillig (void)fprintf(out, " [%d]\n", msgid);
581 1.113 rillig print_stack_trace();
582 1.113 rillig }
583 1.113 rillig
584 1.113 rillig void
585 1.116 rillig (error_at)(int msgid, const pos_t *pos, ...)
586 1.113 rillig {
587 1.198 rillig va_list ap;
588 1.113 rillig
589 1.113 rillig va_start(ap, pos);
590 1.115 rillig verror_at(msgid, pos, ap);
591 1.113 rillig va_end(ap);
592 1.113 rillig }
593 1.113 rillig
594 1.3 jpo void
595 1.115 rillig (error)(int msgid, ...)
596 1.1 cgd {
597 1.198 rillig va_list ap;
598 1.1 cgd
599 1.115 rillig va_start(ap, msgid);
600 1.116 rillig verror_at(msgid, &curr_pos, ap);
601 1.1 cgd va_end(ap);
602 1.1 cgd }
603 1.1 cgd
604 1.3 jpo void
605 1.59 rillig assert_failed(const char *file, int line, const char *func, const char *cond)
606 1.59 rillig {
607 1.59 rillig
608 1.167 rillig /*
609 1.219 rillig * After encountering a parse error in the grammar, lint often does not
610 1.219 rillig * properly clean up its data structures, especially in 'dcs', the
611 1.219 rillig * stack of declaration levels. This often leads to assertion
612 1.219 rillig * failures. These cases are not interesting though, as the purpose of
613 1.219 rillig * lint is to check syntactically valid code. In such a case, exit
614 1.219 rillig * gracefully. This allows a fuzzer like afl to focus on more
615 1.167 rillig * interesting cases instead of reporting nonsense translation units
616 1.167 rillig * like 'f=({e:;}' or 'v(const(char););e(v){'.
617 1.167 rillig */
618 1.167 rillig if (sytxerr > 0)
619 1.167 rillig norecover();
620 1.167 rillig
621 1.144 rillig (void)fflush(stdout);
622 1.59 rillig (void)fprintf(stderr,
623 1.59 rillig "lint: assertion \"%s\" failed in %s at %s:%d near %s:%d\n",
624 1.210 rillig cond, func, file, line,
625 1.210 rillig lbasename(curr_pos.p_file), curr_pos.p_line);
626 1.104 rillig print_stack_trace();
627 1.156 rillig (void)fflush(stdout);
628 1.59 rillig abort();
629 1.59 rillig }
630 1.59 rillig
631 1.59 rillig void
632 1.116 rillig (warning_at)(int msgid, const pos_t *pos, ...)
633 1.113 rillig {
634 1.198 rillig va_list ap;
635 1.113 rillig
636 1.113 rillig va_start(ap, pos);
637 1.115 rillig vwarning_at(msgid, pos, ap);
638 1.113 rillig va_end(ap);
639 1.113 rillig }
640 1.113 rillig
641 1.113 rillig void
642 1.115 rillig (warning)(int msgid, ...)
643 1.1 cgd {
644 1.198 rillig va_list ap;
645 1.3 jpo
646 1.115 rillig va_start(ap, msgid);
647 1.116 rillig vwarning_at(msgid, &curr_pos, ap);
648 1.113 rillig va_end(ap);
649 1.113 rillig }
650 1.113 rillig
651 1.113 rillig void
652 1.116 rillig (message_at)(int msgid, const pos_t *pos, ...)
653 1.113 rillig {
654 1.113 rillig va_list ap;
655 1.113 rillig
656 1.113 rillig va_start(ap, pos);
657 1.115 rillig vmessage_at(msgid, pos, ap);
658 1.3 jpo va_end(ap);
659 1.3 jpo }
660 1.3 jpo
661 1.63 rillig void
662 1.115 rillig (c99ism)(int msgid, ...)
663 1.25 perry {
664 1.198 rillig va_list ap;
665 1.164 rillig
666 1.164 rillig if (allow_c99)
667 1.164 rillig return;
668 1.25 perry
669 1.115 rillig va_start(ap, msgid);
670 1.164 rillig int severity = (!allow_gcc ? 1 : 0) + (!allow_trad ? 1 : 0);
671 1.161 rillig if (severity == 2)
672 1.116 rillig verror_at(msgid, &curr_pos, ap);
673 1.161 rillig if (severity == 1)
674 1.116 rillig vwarning_at(msgid, &curr_pos, ap);
675 1.25 perry va_end(ap);
676 1.1 cgd }
677 1.1 cgd
678 1.108 rillig void
679 1.115 rillig (c11ism)(int msgid, ...)
680 1.108 rillig {
681 1.198 rillig va_list ap;
682 1.108 rillig
683 1.162 rillig /* FIXME: C11 mode has nothing to do with GCC mode. */
684 1.163 rillig if (allow_c11 || allow_gcc)
685 1.110 rillig return;
686 1.115 rillig va_start(ap, msgid);
687 1.116 rillig verror_at(msgid, &curr_pos, ap);
688 1.108 rillig va_end(ap);
689 1.108 rillig }
690 1.108 rillig
691 1.204 rillig void
692 1.204 rillig (c23ism)(int msgid, ...)
693 1.204 rillig {
694 1.204 rillig va_list ap;
695 1.204 rillig
696 1.204 rillig if (allow_c23)
697 1.204 rillig return;
698 1.204 rillig va_start(ap, msgid);
699 1.204 rillig verror_at(msgid, &curr_pos, ap);
700 1.204 rillig va_end(ap);
701 1.204 rillig }
702 1.204 rillig
703 1.162 rillig bool
704 1.115 rillig (gnuism)(int msgid, ...)
705 1.1 cgd {
706 1.198 rillig va_list ap;
707 1.164 rillig int severity = (!allow_gcc ? 1 : 0) +
708 1.164 rillig (!allow_trad && !allow_c99 ? 1 : 0);
709 1.1 cgd
710 1.115 rillig va_start(ap, msgid);
711 1.161 rillig if (severity == 2)
712 1.116 rillig verror_at(msgid, &curr_pos, ap);
713 1.161 rillig if (severity == 1)
714 1.116 rillig vwarning_at(msgid, &curr_pos, ap);
715 1.1 cgd va_end(ap);
716 1.162 rillig return severity > 0;
717 1.1 cgd }
718 1.181 rillig
719 1.181 rillig
720 1.181 rillig static const char *queries[] = {
721 1.181 rillig "", /* unused, to make queries 1-based */
722 1.225 rillig "implicit conversion from floating point '%s' to integer '%s'", // Q1
723 1.225 rillig "cast from floating point '%s' to integer '%s'", // Q2
724 1.225 rillig "implicit conversion changes sign from '%s' to '%s'", // Q3
725 1.225 rillig "usual arithmetic conversion for '%s' from '%s' to '%s'", // Q4
726 1.225 rillig "pointer addition has integer on the left-hand side", // Q5
727 1.225 rillig "no-op cast from '%s' to '%s'", // Q6
728 1.225 rillig "redundant cast from '%s' to '%s' before assignment", // Q7
729 1.225 rillig "octal number '%.*s'", // Q8
730 1.225 rillig "parenthesized return value", // Q9
731 1.225 rillig "chained assignment with '%s' and '%s'", // Q10
732 1.225 rillig "static variable '%s' in function", // Q11
733 1.225 rillig "comma operator with types '%s' and '%s'", // Q12
734 1.225 rillig "redundant 'extern' in function declaration of '%s'", // Q13
735 1.225 rillig "comparison '%s' of 'char' with plain integer %d", // Q14
736 1.225 rillig "implicit conversion from integer 0 to pointer '%s'", // Q15
737 1.225 rillig "'%s' was declared 'static', now non-'static'", // Q16
738 1.225 rillig "invisible character U+%04X in %s", // Q17
739 1.225 rillig "const automatic variable '%s'", // Q18
740 1.181 rillig };
741 1.181 rillig
742 1.181 rillig bool any_query_enabled; /* for optimizing non-query scenarios */
743 1.221 rillig bool is_query_enabled[sizeof(queries) / sizeof(queries[0])];
744 1.181 rillig
745 1.181 rillig void
746 1.181 rillig (query_message)(int query_id, ...)
747 1.181 rillig {
748 1.181 rillig
749 1.181 rillig if (!is_query_enabled[query_id])
750 1.181 rillig return;
751 1.181 rillig
752 1.210 rillig va_list ap;
753 1.210 rillig FILE *out = output_channel();
754 1.210 rillig (void)fprintf(out, "%s(%d): ",
755 1.210 rillig lbasename(curr_pos.p_file), curr_pos.p_line);
756 1.181 rillig va_start(ap, query_id);
757 1.210 rillig (void)vfprintf(out, queries[query_id], ap);
758 1.181 rillig va_end(ap);
759 1.210 rillig (void)fprintf(out, " [Q%d]\n", query_id);
760 1.181 rillig print_stack_trace();
761 1.181 rillig }
762 1.181 rillig
763 1.181 rillig void
764 1.194 rillig enable_queries(const char *p)
765 1.181 rillig {
766 1.194 rillig char *end;
767 1.181 rillig
768 1.194 rillig for (; ch_isdigit(*p); p = end + 1) {
769 1.194 rillig unsigned long id = strtoul(p, &end, 10);
770 1.194 rillig if ((*end != '\0' && *end != ',') ||
771 1.194 rillig id >= sizeof(queries) / sizeof(queries[0]) ||
772 1.194 rillig queries[id][0] == '\0')
773 1.194 rillig break;
774 1.181 rillig
775 1.181 rillig any_query_enabled = true;
776 1.181 rillig is_query_enabled[id] = true;
777 1.181 rillig
778 1.194 rillig if (*end == '\0')
779 1.194 rillig return;
780 1.181 rillig }
781 1.199 rillig errx(1, "invalid query ID '%.*s'", (int)strcspn(p, ","), p);
782 1.181 rillig }
783