1 1.36 rillig /* $NetBSD: decl.c,v 1.36 2025/09/14 12:27:42 rillig Exp $ */ 2 1.1 rillig # 3 "decl.c" 3 1.1 rillig 4 1.1 rillig /* 5 1.1 rillig * Tests for declarations, especially the distinction between the 6 1.1 rillig * declaration-specifiers and the declarators. 7 1.1 rillig */ 8 1.1 rillig 9 1.22 rillig /* lint1-extra-flags: -X 191,351 */ 10 1.21 rillig 11 1.1 rillig /* 12 1.1 rillig * Even though 'const' comes after 'char' and is therefore quite close to the 13 1.1 rillig * first identifier, it applies to both identifiers. 14 1.1 rillig */ 15 1.1 rillig void 16 1.1 rillig specifier_qualifier(void) 17 1.1 rillig { 18 1.1 rillig char const a = 1, b = 2; 19 1.1 rillig 20 1.1 rillig /* expect+1: warning: left operand of '=' must be modifiable lvalue [115] */ 21 1.1 rillig a = 1; 22 1.1 rillig /* expect+1: warning: left operand of '=' must be modifiable lvalue [115] */ 23 1.1 rillig b = 2; 24 1.1 rillig } 25 1.1 rillig 26 1.1 rillig /* 27 1.1 rillig * Since 'const' comes before 'char', there is no ambiguity whether the 28 1.1 rillig * 'const' applies to all variables or just to the first. 29 1.1 rillig */ 30 1.1 rillig void 31 1.1 rillig qualifier_specifier(void) 32 1.1 rillig { 33 1.1 rillig const char a = 1, b = 2; 34 1.1 rillig 35 1.1 rillig /* expect+1: warning: left operand of '=' must be modifiable lvalue [115] */ 36 1.1 rillig a = 3; 37 1.1 rillig /* expect+1: warning: left operand of '=' must be modifiable lvalue [115] */ 38 1.1 rillig b = 5; 39 1.1 rillig } 40 1.1 rillig 41 1.1 rillig void 42 1.1 rillig declarator_with_prefix_qualifier(void) 43 1.1 rillig { 44 1.17 rillig /* expect+1: error: syntax error 'const' [249] */ 45 1.1 rillig char a = 1, const b = 2; 46 1.1 rillig 47 1.1 rillig a = 1; 48 1.1 rillig /* expect+1: error: 'b' undefined [99] */ 49 1.1 rillig b = 2; 50 1.1 rillig } 51 1.1 rillig 52 1.1 rillig void 53 1.1 rillig declarator_with_postfix_qualifier(void) 54 1.1 rillig { 55 1.17 rillig /* expect+1: error: syntax error 'const' [249] */ 56 1.1 rillig char a = 1, b const = 2; 57 1.1 rillig 58 1.1 rillig a = 1; 59 1.1 rillig b = 2; 60 1.1 rillig } 61 1.1 rillig 62 1.1 rillig void sink(double *); 63 1.1 rillig 64 1.1 rillig void 65 1.1 rillig declarators(void) 66 1.1 rillig { 67 1.1 rillig char *pc = 0, c = 0, **ppc = 0; 68 1.1 rillig 69 1.17 rillig /* expect+1: warning: converting 'pointer to char' to incompatible 'pointer to double' for argument 1 [153] */ 70 1.1 rillig sink(pc); 71 1.35 rillig /* expect+1: warning: invalid combination of pointer 'pointer to double' and integer 'char', arg #1 [154] */ 72 1.1 rillig sink(c); 73 1.17 rillig /* expect+1: warning: converting 'pointer to pointer to char' to incompatible 'pointer to double' for argument 1 [153] */ 74 1.1 rillig sink(ppc); 75 1.1 rillig } 76 1.2 rillig 77 1.2 rillig _Bool 78 1.2 rillig enum_error_handling(void) 79 1.2 rillig { 80 1.2 rillig enum { 81 1.17 rillig /* expect+1: error: syntax error '"' [249] */ 82 1.2 rillig "error 1" 83 1.2 rillig : /* still the same error */ 84 1.2 rillig , /* back on track */ 85 1.2 rillig A, 86 1.2 rillig B 87 1.2 rillig } x = A; 88 1.2 rillig 89 1.2 rillig return x == B; 90 1.2 rillig } 91 1.3 rillig 92 1.4 rillig /* 93 1.4 rillig * An __attribute__ at the beginning of a declaration may become ambiguous 94 1.4 rillig * since a GCC fallthrough statement starts with __attribute__ as well. 95 1.4 rillig */ 96 1.3 rillig void 97 1.3 rillig unused_local_variable(void) 98 1.3 rillig { 99 1.3 rillig __attribute__((unused)) _Bool unused_var; 100 1.3 rillig 101 1.3 rillig __attribute__((unused)) 102 1.3 rillig __attribute__((unused)) _Bool unused_twice; 103 1.3 rillig } 104 1.5 rillig 105 1.5 rillig int 106 1.5 rillig declaration_without_type_specifier(void) 107 1.5 rillig { 108 1.5 rillig const i = 3; 109 1.20 rillig /* expect-1: error: old-style declaration; add 'int' [1] */ 110 1.5 rillig return i; 111 1.5 rillig } 112 1.5 rillig 113 1.16 rillig 114 1.16 rillig /* expect+2: warning: static function 'unused' unused [236] */ 115 1.5 rillig static void 116 1.5 rillig unused(void) 117 1.5 rillig { 118 1.5 rillig } 119 1.5 rillig 120 1.5 rillig /* 121 1.5 rillig * The attribute 'used' does not influence static functions, it only 122 1.5 rillig * applies to function parameters. 123 1.5 rillig */ 124 1.5 rillig /* LINTED */ 125 1.5 rillig static void 126 1.5 rillig unused_linted(void) 127 1.5 rillig { 128 1.5 rillig } 129 1.6 rillig 130 1.6 rillig /* covers 'type_qualifier_list: type_qualifier_list type_qualifier' */ 131 1.6 rillig int *const volatile cover_type_qualifier_list; 132 1.7 rillig 133 1.8 rillig _Bool bool; 134 1.8 rillig char plain_char; 135 1.8 rillig signed char signed_char; 136 1.8 rillig unsigned char unsigned_char; 137 1.8 rillig short signed_short; 138 1.8 rillig unsigned short unsigned_short; 139 1.8 rillig int signed_int; 140 1.8 rillig unsigned int unsigned_int; 141 1.8 rillig long signed_long; 142 1.8 rillig unsigned long unsigned_long; 143 1.9 rillig struct { 144 1.9 rillig int member; 145 1.9 rillig } unnamed_struct; 146 1.8 rillig 147 1.8 rillig /* 148 1.8 rillig * Before decl.c 1.201 from 2021-07-15, lint crashed with an internal error 149 1.19 rillig * in dcs_end_type (named end_type back then). 150 1.8 rillig */ 151 1.8 rillig unsigned long sizes = 152 1.8 rillig sizeof(const typeof(bool)) + 153 1.8 rillig sizeof(const typeof(plain_char)) + 154 1.8 rillig sizeof(const typeof(signed_char)) + 155 1.8 rillig sizeof(const typeof(unsigned_char)) + 156 1.8 rillig sizeof(const typeof(signed_short)) + 157 1.8 rillig sizeof(const typeof(unsigned_short)) + 158 1.8 rillig sizeof(const typeof(signed_int)) + 159 1.8 rillig sizeof(const typeof(unsigned_int)) + 160 1.8 rillig sizeof(const typeof(signed_long)) + 161 1.9 rillig sizeof(const typeof(unsigned_long)) + 162 1.9 rillig sizeof(const typeof(unnamed_struct)); 163 1.10 rillig 164 1.20 rillig /* expect+2: error: old-style declaration; add 'int' [1] */ 165 1.17 rillig /* expect+1: error: syntax error 'int' [249] */ 166 1.10 rillig thread int thread_int; 167 1.10 rillig __thread int thread_int; 168 1.20 rillig /* expect+2: error: old-style declaration; add 'int' [1] */ 169 1.17 rillig /* expect+1: error: syntax error 'int' [249] */ 170 1.10 rillig __thread__ int thread_int; 171 1.12 rillig 172 1.12 rillig static 173 1.28 rillig /* expect+1: warning: static function 'cover_func_declarator' unused [236] */ 174 1.12 rillig cover_func_declarator(void) 175 1.28 rillig /* expect+1: error: old-style declaration; add 'int' [1] */ 176 1.12 rillig { 177 1.12 rillig } 178 1.13 rillig 179 1.13 rillig /* 180 1.13 rillig * Before decl.c 1.268 from 2022-04-03, lint ran into an assertion failure for 181 1.13 rillig * "elsz > 0" in 'length'. 182 1.13 rillig */ 183 1.13 rillig /* expect+2: error: syntax error 'goto' [249] */ 184 1.18 rillig /* expect+1: warning: empty array declaration for 'void_array_error' [190] */ 185 1.13 rillig void void_array_error[] goto; 186 1.23 rillig 187 1.23 rillig const volatile int 188 1.23 rillig /* expect+1: warning: duplicate 'const' [10] */ 189 1.23 rillig *const volatile const 190 1.23 rillig /* expect+1: warning: duplicate 'volatile' [10] */ 191 1.23 rillig *volatile const volatile 192 1.23 rillig *duplicate_ptr; 193 1.24 rillig 194 1.24 rillig 195 1.24 rillig /* 196 1.24 rillig * Since tree.c 1.573 from 2023-07-15 and before decl.c 1.370 from 2023-07-31, 197 1.24 rillig * lint crashed due to a failed assertion in find_member. The assertion states 198 1.24 rillig * that every member of a struct or union must link back to its containing 199 1.24 rillig * type, which had not been the case for unnamed bit-fields. 200 1.24 rillig */ 201 1.24 rillig struct bit_and_data { 202 1.24 rillig unsigned int :0; 203 1.24 rillig unsigned int bit:1; 204 1.24 rillig unsigned int :0; 205 1.24 rillig 206 1.24 rillig void *data; 207 1.24 rillig }; 208 1.24 rillig 209 1.24 rillig static inline void * 210 1.24 rillig bit_and_data(struct bit_and_data *node) 211 1.24 rillig { 212 1.24 rillig return node->data; 213 1.24 rillig } 214 1.25 rillig 215 1.25 rillig 216 1.25 rillig // See cgram.y, rule 'notype_member_declarator'. 217 1.25 rillig void 218 1.25 rillig symbol_type_in_unnamed_bit_field_member(void) 219 1.25 rillig { 220 1.25 rillig enum { 221 1.25 rillig bits = 4, 222 1.25 rillig }; 223 1.25 rillig 224 1.25 rillig struct s { 225 1.25 rillig // Since there is no name in the declarator, the next symbol 226 1.25 rillig // after the ':' must not be interpreted as a member name, but 227 1.27 rillig // instead as a variable, type or function (SK_VCFT). 228 1.25 rillig unsigned int :bits; 229 1.25 rillig int named_member; 230 1.25 rillig }; 231 1.25 rillig } 232 1.26 rillig 233 1.26 rillig // Symbols that are defined in the parameter list of a function definition can 234 1.26 rillig // be accessed in the body of the function, even if they are nested. 235 1.26 rillig int 236 1.26 rillig get_x(struct point3d { struct point3d_number { int v; } x, y, z; } arg) 237 1.26 rillig { 238 1.26 rillig /* expect-1: warning: dubious tag declaration 'struct point3d' [85] */ 239 1.26 rillig /* expect-2: warning: dubious tag declaration 'struct point3d_number' [85] */ 240 1.26 rillig static struct point3d local; 241 1.26 rillig static struct point3d_number z; 242 1.26 rillig return arg.x.v + local.x.v + z.v; 243 1.26 rillig } 244 1.29 rillig 245 1.29 rillig // Expressions of the form '(size_t)&null_ptr->member' are used by several 246 1.30 rillig // C implementations to implement the offsetof macro. 247 1.29 rillig void 248 1.29 rillig offsetof_on_array_member(void) 249 1.29 rillig { 250 1.30 rillig typedef struct { 251 1.29 rillig int padding, plain, arr[2]; 252 1.30 rillig } s1; 253 1.29 rillig 254 1.30 rillig // Bit-fields must have a constant number of bits. 255 1.29 rillig struct s2 { 256 1.30 rillig unsigned int off_plain:(unsigned long)&((s1 *)0)->plain; 257 1.30 rillig unsigned int off_arr:(unsigned long)&((s1 *)0)->arr; 258 1.30 rillig unsigned int off_arr_0:(unsigned long)&((s1 *)0)->arr[0]; 259 1.30 rillig unsigned int off_arr_3:(unsigned long)&((s1 *)0)->arr[3]; 260 1.29 rillig }; 261 1.30 rillig 262 1.30 rillig // Arrays may be variable-width, but the diagnostic reveals the size. 263 1.30 rillig /* expect+1: error: negative array dimension (-4) [20] */ 264 1.30 rillig typedef int off_plain[-(int)(unsigned long)&((s1 *)0)->plain]; 265 1.30 rillig /* expect+1: error: negative array dimension (-8) [20] */ 266 1.30 rillig typedef int off_arr[-(int)(unsigned long)&((s1 *)0)->arr]; 267 1.30 rillig /* expect+1: error: negative array dimension (-8) [20] */ 268 1.30 rillig typedef int off_arr_0[-(int)(unsigned long)&((s1 *)0)->arr[0]]; 269 1.30 rillig /* expect+1: error: negative array dimension (-20) [20] */ 270 1.30 rillig typedef int off_arr_3[-(int)(unsigned long)&((s1 *)0)->arr[3]]; 271 1.29 rillig } 272 1.31 rillig 273 1.31 rillig /* PR bin/39639: writing "long double" gave "long int" */ 274 1.31 rillig int 275 1.31 rillig long_double_vs_long_int(long double *a, long int *b) 276 1.31 rillig { 277 1.35 rillig /* expect+1: warning: invalid combination of 'pointer to long double' and 'pointer to long', op '==' [124] */ 278 1.31 rillig return a == b; 279 1.31 rillig } 280 1.31 rillig 281 1.31 rillig struct zero_sized_array { 282 1.31 rillig int member[0]; 283 1.31 rillig }; 284 1.31 rillig 285 1.31 rillig void 286 1.31 rillig type_name_as_member_name(void) 287 1.31 rillig { 288 1.31 rillig typedef char h[10]; 289 1.31 rillig 290 1.31 rillig typedef struct { 291 1.31 rillig int i; 292 1.31 rillig char *c; 293 1.31 rillig } fh; 294 1.31 rillig 295 1.31 rillig struct foo { 296 1.31 rillig fh h; 297 1.31 rillig struct { 298 1.31 rillig int x; 299 1.31 rillig int y; 300 1.31 rillig } fl; 301 1.31 rillig }; 302 1.31 rillig } 303 1.32 rillig 304 1.32 rillig 305 1.32 rillig // When query 16 is not enabled, don't produce a 'previous declaration' message 306 1.32 rillig // without a preceding main diagnostic. 307 1.32 rillig static void static_function(void) __attribute__((__used__)); 308 1.32 rillig 309 1.32 rillig // The definition is without 'static'. 310 1.32 rillig void 311 1.32 rillig static_function(void) 312 1.32 rillig { 313 1.32 rillig } 314 1.33 rillig 315 1.33 rillig 316 1.33 rillig typedef void (*fprint_function)(int, const char *, ...); 317 1.33 rillig typedef fprint_function (*change_logger) 318 1.33 rillig (fprint_function, fprint_function, fprint_function, fprint_function); 319 1.33 rillig 320 1.33 rillig // Provoke a long type name to test reallocation in type_name. 321 1.33 rillig /* expect+1: error: redeclaration of 'static_function' with type 'function(pointer to function(pointer to function(int, pointer to const char, ...) returning void, pointer to function(int, pointer to const char, ...) returning void, pointer to function(int, pointer to const char, ...) returning void, pointer to function(int, pointer to const char, ...) returning void) returning pointer to function(int, pointer to const char, ...) returning void) returning void', expected 'function(void) returning void' [347] */ 322 1.33 rillig void static_function(change_logger); 323 1.34 rillig 324 1.34 rillig 325 1.34 rillig void no_prototype_declaration(); 326 1.34 rillig void prototype_declaration(void); 327 1.34 rillig 328 1.34 rillig // TODO: Warn about the missing 'void', for C99 and later. 329 1.34 rillig void 330 1.34 rillig no_prototype_definition() 331 1.34 rillig { 332 1.34 rillig } 333 1.34 rillig 334 1.34 rillig void 335 1.34 rillig prototype_definition(void) 336 1.34 rillig { 337 1.34 rillig } 338 1.36 rillig 339 1.36 rillig /* These integer overflows in '<<' expressions are detected by KUBSAN. */ 340 1.36 rillig /* expect+1: warning: constant -0x8000000000000000 too large for 'int' [56] */ 341 1.36 rillig typedef int shl_overflow_positive[1LL << 32 << 31]; 342 1.36 rillig /* expect+1: warning: constant -0x8000000000000000 too large for 'int' [56] */ 343 1.36 rillig typedef int shl_overflow_negative[-1LL << 32 << 31]; 344