xref: /netbsd-src/tests/usr.bin/xlint/lint1/gcc_attribute_var.c (revision ccd9df534e375a4366c5b55f23782053c7a98d82)
1 /*	$NetBSD: gcc_attribute_var.c,v 1.11 2023/07/15 21:47:35 rillig Exp $	*/
2 # 3 "gcc_attribute_var.c"
3 
4 /*
5  * Tests for the GCC __attribute__ for variables.
6  *
7  * https://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html
8  */
9 
10 /* lint1-extra-flags: -X 351 */
11 
12 void
13 write_to_page(unsigned index, char ch)
14 {
15 	static char page[4096]
16 	    __attribute__((__aligned__(4096)));
17 
18 	page[index] = ch;
19 }
20 
21 void
22 placement(
23     __attribute__((__deprecated__)) int before,
24     int __attribute__((__deprecated__)) between,
25     int after __attribute__((__deprecated__))
26 );
27 
28 void println(void);
29 
30 /*
31  * Since cgram.y 1.294 from 2021-07-10, lint did not accept declarations that
32  * started with __attribute__, due to a newly and accidentally introduced
33  * shift/reduce conflict in the grammar.
34  *
35  * A GCC extension allows statement of the form __attribute__((fallthrough)),
36  * thus starting with __attribute__.  This is the 'shift' in the conflict.
37  * The 'reduce' in the conflict was begin_type.
38  *
39  * Before cgram 1.294, the gcc_attribute was placed outside the pair of
40  * begin_type/end_type, exactly to resolve this conflict.
41  *
42  * Conceptually, it made sense to put the __attribute__((unused)) between
43  * begin_type and end_type, to make it part of the declaration-specifiers.
44  * This change introduced the hidden conflict though.
45  *
46  * Interestingly, the number of shift/reduce conflicts did not change in
47  * cgram 1.294, the conflicts were just resolved differently than before.
48  *
49  * To prevent this from happening again, make sure that declarations as well
50  * as statements can start with gcc_attribute.
51  */
52 void
53 ambiguity_for_attribute(void)
54 {
55 	/* expect+1: warning: 'var1' unused in function 'ambiguity_for_attribute' [192] */
56 	__attribute__((unused)) _Bool var1;
57 
58 	switch (1) {
59 	case 1:
60 		println();
61 		/* expect+1: warning: 'var2' unused in function 'ambiguity_for_attribute' [192] */
62 		__attribute__((unused)) _Bool var2;
63 		__attribute__((fallthrough));
64 		case 2:
65 			println();
66 	}
67 }
68 
69 void
70 attribute_after_array_brackets(
71     const char *argv[] __attribute__((__unused__))
72 )
73 {
74 }
75 
76 struct attribute_in_member_declaration {
77 	int __attribute__(())
78 	    x __attribute__(()),
79 	    y __attribute__(());
80 
81 	unsigned int __attribute__(())
82 	    bit1:1 __attribute__(()),
83 	    bit2:2 __attribute__(()),
84 	    bit3:3 __attribute__(());
85 };
86