1 /* $NetBSD: decl.c,v 1.31 2024/06/08 09:09: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