Home | History | Annotate | Line # | Download | only in lint1
decl.c revision 1.21
      1 /*	$NetBSD: decl.c,v 1.21 2023/03/28 14:44:34 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 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 /* expect+4: error: old-style declaration; add 'int' [1] */
    173 /* expect+2: warning: static function 'cover_func_declarator' unused [236] */
    174 static
    175 cover_func_declarator(void)
    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