1 1.277 rillig /* $NetBSD: err.c,v 1.277 2025/09/14 11:14:00 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.277 rillig __RCSID("$NetBSD: err.c,v 1.277 2025/09/14 11:14:00 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.269 rillig "invalid 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.269 rillig "invalid 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.269 rillig "function returns invalid type '%s'", // 15 74 1.269 rillig "array of function is invalid", // 16 75 1.225 rillig "null dimension", // 17 76 1.269 rillig "invalid 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.269 rillig "invalid bit-field type '%s'", // 35 94 1.269 rillig "invalid bit-field size: %d", // 36 95 1.225 rillig "zero size bit-field", // 37 96 1.269 rillig "function invalid 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.251 rillig "constant %s too large for 'int'", // 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.270 rillig "\\a requires C90 or later", // 81 140 1.270 rillig "\\x requires C90 or later", // 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.250 rillig "automatic '%s' hides external declaration with type '%s'", // 86 145 1.250 rillig "static '%s' hides external declaration with type '%s'", // 87 146 1.250 rillig "typedef '%s' hides external declaration with type '%s'", // 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.269 rillig "function '%s' has invalid 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.270 rillig "suffix 'U' requires C90 or later", // 97 156 1.270 rillig "suffixes 'F' or 'L' require C90 or later", // 98 157 1.225 rillig "'%s' undefined", // 99 158 1.270 rillig "unary '+' requires C90 or later", // 100 159 1.225 rillig "type '%s' does not have member '%s'", // 101 160 1.269 rillig "invalid 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.269 rillig "void type invalid 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.269 rillig "invalid pointer subtraction", // 116 175 1.277 rillig "bitwise '%s' on signed '%s' possibly nonportable", // 117 176 1.276 rillig "'%s' %s '%s' differs between traditional C and C90", // 118 177 1.225 rillig "conversion of '%s' to '%s' is out of range", // 119 178 1.277 rillig "bitwise '%s' on signed '%s' 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.269 rillig "invalid combination of %s '%s' and %s '%s', op '%s'", // 123 182 1.269 rillig "invalid 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.265 rillig "", /* no longer used */ // 127 186 1.254 rillig "operator '%s' discards '%s' from '%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.232 rillig "'%s' overflows '%s'", // 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.269 rillig "invalid 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.267 rillig "", /* no longer used */ // 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.245 rillig "assignment of negative constant %lld to unsigned type '%s'", // 164 223 1.225 rillig "constant truncated by assignment", // 165 224 1.225 rillig "precision lost in bit-field assignment", // 166 225 1.237 rillig "array subscript %jd cannot be negative", // 167 226 1.238 rillig "array subscript %ju cannot be > %d", // 168 227 1.261 rillig "possible precedence confusion between '%s' and '%s'", // 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.242 rillig "too many initializers for '%s'", // 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.254 rillig "'%s' discards '%s' from '%s'", // 182 241 1.269 rillig "invalid combination of %s '%s' and %s '%s' for '%s'", // 183 242 1.269 rillig "invalid combination of '%s' and '%s'", // 184 243 1.225 rillig "cannot initialize '%s' from '%s'", // 185 244 1.236 rillig "bit-field initializer must be an integer in traditional C", // 186 245 1.234 rillig "string literal too long (%ju) for target array (%ju)", // 187 246 1.270 rillig "automatic aggregate initialization requires C90 or later", // 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.253 rillig "'%s' statement not reached", // 193 252 1.225 rillig "label '%s' redefined", // 194 253 1.225 rillig "case not in switch", // 195 254 1.266 rillig "case label is converted from '%s' to '%s'", // 196 255 1.225 rillig "non-constant case expression", // 197 256 1.225 rillig "non-integral case expression", // 198 257 1.234 rillig "duplicate case '%jd' in switch", // 199 258 1.234 rillig "duplicate case '%ju' 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.273 rillig "", /* no longer used */ // 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.270 rillig "concatenated strings require C90 or later", // 219 278 1.225 rillig "fallthrough on case statement", // 220 279 1.245 rillig "initialization of unsigned type '%s' with negative constant %lld", // 221 280 1.245 rillig "conversion of negative constant %lld to unsigned type '%s'", // 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.270 rillig "initialization of union requires C90 or later", // 238 297 1.268 rillig "", /* no longer used */ // 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.269 rillig "invalid 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.248 rillig "pointer cast from '%s' to unrelated '%s'", // 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.270 rillig "\\\" inside a character constant requires C90 or later", // 262 321 1.270 rillig "\\? requires C90 or later", // 263 322 1.270 rillig "\\v requires C90 or later", // 264 323 1.225 rillig "%s does not support 'long long'", // 265 324 1.270 rillig "'long double' requires C90 or later", // 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.270 rillig "function prototypes require C90 or later", // 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.269 rillig "'__%s__' is invalid 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.245 rillig "conversion of negative constant %lld to unsigned type '%s', 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.264 rillig "constant %s 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.274 rillig "'%s' converts '%s' with its most significant bit being set to '%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.252 rillig "maximum value %d for '%s' of type '%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.229 rillig "number base '%.*s' is %ju, must be 8, 10 or 16", // 361 420 1.233 rillig "conversion '%.*s' should not be escaped", // 362 421 1.240 rillig "escaped character '%.*s' in description of conversion '%.*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.233 rillig "missing comparison value after conversion '%.*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.231 rillig "field width '%.*s' (%ju) in '%.*s' out of range 0..64", // 372 431 1.226 rillig "bit field end %ju in '%.*s' out of range 0..64", // 373 432 1.233 rillig "unknown conversion '%.*s', must be one of 'bfF=:*'", // 374 433 1.229 rillig "comparison value '%.*s' (%ju) exceeds maximum field value %ju", // 375 434 1.228 rillig "'%.*s' overlaps earlier '%.*s' on bit %u", // 376 435 1.230 rillig "redundant '\\0' at the end of the format", // 377 436 1.233 rillig "conversion '%.*s' is unreachable by input value", // 378 437 1.243 rillig "comparing integer '%s' to floating point constant %Lg", // 379 438 1.246 rillig "lossy conversion of %Lg to '%s', arg #%d", // 380 439 1.246 rillig "lossy conversion of %Lg to '%s'", // 381 440 1.271 rillig "constant assignment of type '%s' in operand of '%s' always evaluates to '%s'", // 382 441 1.272 rillig "passing '%s' as argument %d to '%s' discards '%s'", // 383 442 1.262 rillig "function definition for '%s' with identifier list is obsolete in C23", // 384 443 1.260 rillig "do-while macro '%.*s' ends with semicolon", // 385 444 1.275 rillig "conversion '%.*s' does not mix with '%c'", // 386 445 1.1 cgd }; 446 1.1 cgd 447 1.220 rillig static bool is_suppressed[sizeof(msgs) / sizeof(msgs[0])]; 448 1.178 rillig 449 1.104 rillig static struct include_level { 450 1.104 rillig const char *filename; 451 1.104 rillig int lineno; 452 1.104 rillig struct include_level *by; 453 1.104 rillig } *includes; 454 1.104 rillig 455 1.178 rillig void 456 1.194 rillig suppress_messages(const char *p) 457 1.178 rillig { 458 1.194 rillig char *end; 459 1.194 rillig 460 1.244 rillig for (; ch_isdigit(*p); p = end + 1) { 461 1.194 rillig unsigned long id = strtoul(p, &end, 10); 462 1.194 rillig if ((*end != '\0' && *end != ',') || 463 1.194 rillig id >= sizeof(msgs) / sizeof(msgs[0]) || 464 1.194 rillig msgs[id][0] == '\0') 465 1.194 rillig break; 466 1.178 rillig 467 1.179 rillig is_suppressed[id] = true; 468 1.194 rillig 469 1.194 rillig if (*end == '\0') 470 1.194 rillig return; 471 1.178 rillig } 472 1.199 rillig errx(1, "invalid message ID '%.*s'", (int)strcspn(p, ","), p); 473 1.178 rillig } 474 1.104 rillig 475 1.104 rillig void 476 1.105 rillig update_location(const char *filename, int lineno, bool is_begin, bool is_end) 477 1.104 rillig { 478 1.104 rillig struct include_level *top; 479 1.104 rillig 480 1.104 rillig top = includes; 481 1.104 rillig if (is_begin && top != NULL) 482 1.104 rillig top->lineno = curr_pos.p_line; 483 1.104 rillig 484 1.104 rillig if (top == NULL || is_begin) { 485 1.104 rillig top = xmalloc(sizeof(*top)); 486 1.104 rillig top->filename = filename; 487 1.104 rillig top->lineno = lineno; 488 1.104 rillig top->by = includes; 489 1.104 rillig includes = top; 490 1.104 rillig } else { 491 1.109 rillig if (is_end) { 492 1.104 rillig includes = top->by; 493 1.104 rillig free(top); 494 1.104 rillig top = includes; 495 1.104 rillig } 496 1.123 rillig if (top != NULL) { 497 1.123 rillig top->filename = filename; 498 1.123 rillig top->lineno = lineno; 499 1.123 rillig } 500 1.104 rillig } 501 1.104 rillig } 502 1.104 rillig 503 1.104 rillig static void 504 1.104 rillig print_stack_trace(void) 505 1.104 rillig { 506 1.105 rillig const struct include_level *top; 507 1.104 rillig 508 1.104 rillig if ((top = includes) == NULL) 509 1.104 rillig return; 510 1.105 rillig /* 511 1.105 rillig * Skip the innermost include level since it is already listed in the 512 1.105 rillig * diagnostic itself. Furthermore, its lineno is the line number of 513 1.105 rillig * the last '#' line, not the current line. 514 1.105 rillig */ 515 1.104 rillig for (top = top->by; top != NULL; top = top->by) 516 1.104 rillig printf("\tincluded from %s(%d)\n", top->filename, top->lineno); 517 1.104 rillig } 518 1.104 rillig 519 1.1 cgd /* 520 1.56 rillig * If Fflag is not set, lbasename() returns a pointer to the last 521 1.1 cgd * component of the path, otherwise it returns the argument. 522 1.1 cgd */ 523 1.1 cgd static const char * 524 1.18 tv lbasename(const char *path) 525 1.1 cgd { 526 1.1 cgd 527 1.1 cgd if (Fflag) 528 1.57 rillig return path; 529 1.1 cgd 530 1.188 rillig const char *base = path; 531 1.188 rillig for (const char *p = path; *p != '\0'; p++) 532 1.188 rillig if (*p == '/') 533 1.188 rillig base = p + 1; 534 1.188 rillig return base; 535 1.1 cgd } 536 1.1 cgd 537 1.210 rillig static FILE * 538 1.210 rillig output_channel(void) 539 1.210 rillig { 540 1.210 rillig return yflag ? stderr : stdout; 541 1.210 rillig } 542 1.210 rillig 543 1.3 jpo static void 544 1.116 rillig verror_at(int msgid, const pos_t *pos, va_list ap) 545 1.3 jpo { 546 1.3 jpo 547 1.179 rillig if (is_suppressed[msgid]) 548 1.12 christos return; 549 1.12 christos 550 1.210 rillig FILE *out = output_channel(); 551 1.210 rillig (void)fprintf(out, "%s(%d): error: ", 552 1.210 rillig lbasename(pos->p_file), pos->p_line); 553 1.210 rillig (void)vfprintf(out, msgs[msgid], ap); 554 1.210 rillig (void)fprintf(out, " [%d]\n", msgid); 555 1.205 rillig seen_error = true; 556 1.104 rillig print_stack_trace(); 557 1.3 jpo } 558 1.3 jpo 559 1.3 jpo static void 560 1.116 rillig vwarning_at(int msgid, const pos_t *pos, va_list ap) 561 1.3 jpo { 562 1.3 jpo 563 1.179 rillig if (is_suppressed[msgid]) 564 1.12 christos return; 565 1.12 christos 566 1.132 rillig debug_step("%s: lwarn=%d msgid=%d", __func__, lwarn, msgid); 567 1.115 rillig if (lwarn == LWARN_NONE || lwarn == msgid) 568 1.3 jpo /* this warning is suppressed by a LINTED comment */ 569 1.3 jpo return; 570 1.3 jpo 571 1.210 rillig FILE *out = output_channel(); 572 1.210 rillig (void)fprintf(out, "%s(%d): warning: ", 573 1.210 rillig lbasename(pos->p_file), pos->p_line); 574 1.210 rillig (void)vfprintf(out, msgs[msgid], ap); 575 1.210 rillig (void)fprintf(out, " [%d]\n", msgid); 576 1.205 rillig seen_warning = true; 577 1.104 rillig print_stack_trace(); 578 1.3 jpo } 579 1.3 jpo 580 1.113 rillig static void 581 1.116 rillig vmessage_at(int msgid, const pos_t *pos, va_list ap) 582 1.113 rillig { 583 1.113 rillig 584 1.179 rillig if (is_suppressed[msgid]) 585 1.113 rillig return; 586 1.113 rillig 587 1.210 rillig FILE *out = output_channel(); 588 1.210 rillig (void)fprintf(out, "%s(%d): ", 589 1.210 rillig lbasename(pos->p_file), pos->p_line); 590 1.210 rillig (void)vfprintf(out, msgs[msgid], ap); 591 1.210 rillig (void)fprintf(out, " [%d]\n", msgid); 592 1.113 rillig print_stack_trace(); 593 1.113 rillig } 594 1.113 rillig 595 1.113 rillig void 596 1.116 rillig (error_at)(int msgid, const pos_t *pos, ...) 597 1.113 rillig { 598 1.198 rillig va_list ap; 599 1.113 rillig 600 1.113 rillig va_start(ap, pos); 601 1.115 rillig verror_at(msgid, pos, ap); 602 1.113 rillig va_end(ap); 603 1.113 rillig } 604 1.113 rillig 605 1.3 jpo void 606 1.115 rillig (error)(int msgid, ...) 607 1.1 cgd { 608 1.198 rillig va_list ap; 609 1.1 cgd 610 1.115 rillig va_start(ap, msgid); 611 1.116 rillig verror_at(msgid, &curr_pos, ap); 612 1.1 cgd va_end(ap); 613 1.1 cgd } 614 1.1 cgd 615 1.3 jpo void 616 1.59 rillig assert_failed(const char *file, int line, const char *func, const char *cond) 617 1.59 rillig { 618 1.59 rillig 619 1.249 rillig #if LINT_FUZZING 620 1.167 rillig /* 621 1.219 rillig * After encountering a parse error in the grammar, lint often does not 622 1.219 rillig * properly clean up its data structures, especially in 'dcs', the 623 1.219 rillig * stack of declaration levels. This often leads to assertion 624 1.219 rillig * failures. These cases are not interesting though, as the purpose of 625 1.219 rillig * lint is to check syntactically valid code. In such a case, exit 626 1.219 rillig * gracefully. This allows a fuzzer like afl to focus on more 627 1.167 rillig * interesting cases instead of reporting nonsense translation units 628 1.167 rillig * like 'f=({e:;}' or 'v(const(char););e(v){'. 629 1.167 rillig */ 630 1.167 rillig if (sytxerr > 0) 631 1.167 rillig norecover(); 632 1.249 rillig #endif 633 1.167 rillig 634 1.144 rillig (void)fflush(stdout); 635 1.59 rillig (void)fprintf(stderr, 636 1.59 rillig "lint: assertion \"%s\" failed in %s at %s:%d near %s:%d\n", 637 1.210 rillig cond, func, file, line, 638 1.210 rillig lbasename(curr_pos.p_file), curr_pos.p_line); 639 1.104 rillig print_stack_trace(); 640 1.156 rillig (void)fflush(stdout); 641 1.59 rillig abort(); 642 1.59 rillig } 643 1.59 rillig 644 1.59 rillig void 645 1.116 rillig (warning_at)(int msgid, const pos_t *pos, ...) 646 1.113 rillig { 647 1.198 rillig va_list ap; 648 1.113 rillig 649 1.113 rillig va_start(ap, pos); 650 1.115 rillig vwarning_at(msgid, pos, ap); 651 1.113 rillig va_end(ap); 652 1.113 rillig } 653 1.113 rillig 654 1.113 rillig void 655 1.115 rillig (warning)(int msgid, ...) 656 1.1 cgd { 657 1.198 rillig va_list ap; 658 1.3 jpo 659 1.115 rillig va_start(ap, msgid); 660 1.116 rillig vwarning_at(msgid, &curr_pos, ap); 661 1.113 rillig va_end(ap); 662 1.113 rillig } 663 1.113 rillig 664 1.113 rillig void 665 1.116 rillig (message_at)(int msgid, const pos_t *pos, ...) 666 1.113 rillig { 667 1.113 rillig va_list ap; 668 1.113 rillig 669 1.113 rillig va_start(ap, pos); 670 1.115 rillig vmessage_at(msgid, pos, ap); 671 1.3 jpo va_end(ap); 672 1.3 jpo } 673 1.3 jpo 674 1.63 rillig void 675 1.115 rillig (c99ism)(int msgid, ...) 676 1.25 perry { 677 1.198 rillig va_list ap; 678 1.164 rillig 679 1.164 rillig if (allow_c99) 680 1.164 rillig return; 681 1.25 perry 682 1.115 rillig va_start(ap, msgid); 683 1.164 rillig int severity = (!allow_gcc ? 1 : 0) + (!allow_trad ? 1 : 0); 684 1.161 rillig if (severity == 2) 685 1.116 rillig verror_at(msgid, &curr_pos, ap); 686 1.161 rillig if (severity == 1) 687 1.116 rillig vwarning_at(msgid, &curr_pos, ap); 688 1.25 perry va_end(ap); 689 1.1 cgd } 690 1.1 cgd 691 1.108 rillig void 692 1.115 rillig (c11ism)(int msgid, ...) 693 1.108 rillig { 694 1.198 rillig va_list ap; 695 1.108 rillig 696 1.162 rillig /* FIXME: C11 mode has nothing to do with GCC mode. */ 697 1.163 rillig if (allow_c11 || allow_gcc) 698 1.110 rillig return; 699 1.115 rillig va_start(ap, msgid); 700 1.116 rillig verror_at(msgid, &curr_pos, ap); 701 1.108 rillig va_end(ap); 702 1.108 rillig } 703 1.108 rillig 704 1.204 rillig void 705 1.204 rillig (c23ism)(int msgid, ...) 706 1.204 rillig { 707 1.204 rillig va_list ap; 708 1.204 rillig 709 1.204 rillig if (allow_c23) 710 1.204 rillig return; 711 1.204 rillig va_start(ap, msgid); 712 1.204 rillig verror_at(msgid, &curr_pos, ap); 713 1.204 rillig va_end(ap); 714 1.204 rillig } 715 1.204 rillig 716 1.162 rillig bool 717 1.115 rillig (gnuism)(int msgid, ...) 718 1.1 cgd { 719 1.198 rillig va_list ap; 720 1.164 rillig int severity = (!allow_gcc ? 1 : 0) + 721 1.164 rillig (!allow_trad && !allow_c99 ? 1 : 0); 722 1.1 cgd 723 1.115 rillig va_start(ap, msgid); 724 1.161 rillig if (severity == 2) 725 1.116 rillig verror_at(msgid, &curr_pos, ap); 726 1.161 rillig if (severity == 1) 727 1.116 rillig vwarning_at(msgid, &curr_pos, ap); 728 1.1 cgd va_end(ap); 729 1.162 rillig return severity > 0; 730 1.1 cgd } 731 1.181 rillig 732 1.181 rillig 733 1.181 rillig static const char *queries[] = { 734 1.181 rillig "", /* unused, to make queries 1-based */ 735 1.225 rillig "implicit conversion from floating point '%s' to integer '%s'", // Q1 736 1.225 rillig "cast from floating point '%s' to integer '%s'", // Q2 737 1.225 rillig "implicit conversion changes sign from '%s' to '%s'", // Q3 738 1.225 rillig "usual arithmetic conversion for '%s' from '%s' to '%s'", // Q4 739 1.225 rillig "pointer addition has integer on the left-hand side", // Q5 740 1.225 rillig "no-op cast from '%s' to '%s'", // Q6 741 1.225 rillig "redundant cast from '%s' to '%s' before assignment", // Q7 742 1.225 rillig "octal number '%.*s'", // Q8 743 1.225 rillig "parenthesized return value", // Q9 744 1.225 rillig "chained assignment with '%s' and '%s'", // Q10 745 1.225 rillig "static variable '%s' in function", // Q11 746 1.225 rillig "comma operator with types '%s' and '%s'", // Q12 747 1.225 rillig "redundant 'extern' in function declaration of '%s'", // Q13 748 1.225 rillig "comparison '%s' of 'char' with plain integer %d", // Q14 749 1.225 rillig "implicit conversion from integer 0 to pointer '%s'", // Q15 750 1.225 rillig "'%s' was declared 'static', now non-'static'", // Q16 751 1.225 rillig "invisible character U+%04X in %s", // Q17 752 1.235 rillig "const automatic variable '%s'", // Q18 753 1.239 rillig "implicit conversion from integer '%s' to floating point '%s'", // Q19 754 1.241 rillig "implicit narrowing conversion from void pointer to '%s'", // Q20 755 1.256 rillig "typedef '%s' of struct type '%s'", // Q21 756 1.256 rillig "typedef '%s' of union type '%s'", // Q22 757 1.256 rillig "typedef '%s' of pointer to struct type '%s'", // Q23 758 1.256 rillig "typedef '%s' of pointer to union type '%s'", // Q24 759 1.181 rillig }; 760 1.181 rillig 761 1.258 rillig // Omit any expensive computations in the default mode where none of the 762 1.258 rillig // queries are enabled. Function calls in message details don't need to be 763 1.258 rillig // guarded by this flag, as that happens in the query_message macro already. 764 1.258 rillig bool any_query_enabled; 765 1.221 rillig bool is_query_enabled[sizeof(queries) / sizeof(queries[0])]; 766 1.181 rillig 767 1.181 rillig void 768 1.181 rillig (query_message)(int query_id, ...) 769 1.181 rillig { 770 1.181 rillig 771 1.181 rillig if (!is_query_enabled[query_id]) 772 1.181 rillig return; 773 1.181 rillig 774 1.210 rillig va_list ap; 775 1.210 rillig FILE *out = output_channel(); 776 1.210 rillig (void)fprintf(out, "%s(%d): ", 777 1.210 rillig lbasename(curr_pos.p_file), curr_pos.p_line); 778 1.181 rillig va_start(ap, query_id); 779 1.210 rillig (void)vfprintf(out, queries[query_id], ap); 780 1.181 rillig va_end(ap); 781 1.210 rillig (void)fprintf(out, " [Q%d]\n", query_id); 782 1.181 rillig print_stack_trace(); 783 1.181 rillig } 784 1.181 rillig 785 1.181 rillig void 786 1.194 rillig enable_queries(const char *p) 787 1.181 rillig { 788 1.194 rillig char *end; 789 1.181 rillig 790 1.244 rillig for (; ch_isdigit(*p); p = end + 1) { 791 1.194 rillig unsigned long id = strtoul(p, &end, 10); 792 1.194 rillig if ((*end != '\0' && *end != ',') || 793 1.194 rillig id >= sizeof(queries) / sizeof(queries[0]) || 794 1.194 rillig queries[id][0] == '\0') 795 1.194 rillig break; 796 1.181 rillig 797 1.258 rillig any_query_enabled = true; 798 1.181 rillig is_query_enabled[id] = true; 799 1.181 rillig 800 1.194 rillig if (*end == '\0') 801 1.194 rillig return; 802 1.181 rillig } 803 1.199 rillig errx(1, "invalid query ID '%.*s'", (int)strcspn(p, ","), p); 804 1.181 rillig } 805