Home | History | Annotate | Line # | Download | only in lint1
      1 /*	$NetBSD: decl.c,v 1.36 2025/09/14 12:27:42 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: invalid 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: invalid 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 
    324 
    325 void no_prototype_declaration();
    326 void prototype_declaration(void);
    327 
    328 // TODO: Warn about the missing 'void', for C99 and later.
    329 void
    330 no_prototype_definition()
    331 {
    332 }
    333 
    334 void
    335 prototype_definition(void)
    336 {
    337 }
    338 
    339 /* These integer overflows in '<<' expressions are detected by KUBSAN. */
    340 /* expect+1: warning: constant -0x8000000000000000 too large for 'int' [56] */
    341 typedef int shl_overflow_positive[1LL << 32 << 31];
    342 /* expect+1: warning: constant -0x8000000000000000 too large for 'int' [56] */
    343 typedef int shl_overflow_negative[-1LL << 32 << 31];
    344