Home | History | Annotate | Line # | Download | only in lint1
decl.c revision 1.31
      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