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