xref: /netbsd-src/tests/usr.bin/xlint/lint1/gcc_attribute_var.c (revision 53b02e147d4ed531c0d2a5ca9b3e8026ba3e99b5)
1 /*	$NetBSD: gcc_attribute_var.c,v 1.5 2021/08/11 05:19:33 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 void
11 write_to_page(unsigned index, char ch)
12 {
13 	static char page[4096]
14 	    __attribute__((__aligned__(4096)));
15 
16 	page[index] = ch;
17 }
18 
19 void
20 placement(
21     __attribute__((__deprecated__)) int before,
22     int __attribute__((__deprecated__)) between,
23     int after __attribute__((__deprecated__))
24 );
25 
26 void println(void);
27 
28 /*
29  * Since cgram.y 1.294 from 2021-07-10, lint did not accept declarations that
30  * started with __attribute__, due to a newly and accidentally introduced
31  * shift/reduce conflict in the grammar.
32  *
33  * A GCC extension allows statement of the form __attribute__((fallthrough)),
34  * thus starting with __attribute__.  This is the 'shift' in the conflict.
35  * The 'reduce' in the conflict was begin_type.
36  *
37  * Before cgram 1.294, the gcc_attribute was placed outside the pair of
38  * begin_type/end_type, exactly to resolve this conflict.
39  *
40  * Conceptually, it made sense to put the __attribute__((unused)) between
41  * begin_type and end_type, to make it part of the declaration-specifiers.
42  * This change introduced the hidden conflict though.
43  *
44  * Interestingly, the number of shift/reduce conflicts did not change in
45  * cgram 1.294, the conflicts were just resolved differently than before.
46  *
47  * To prevent this from happening again, make sure that declarations as well
48  * as statements can start with gcc_attribute.
49  */
50 void
51 ambiguity_for_attribute(void)
52 {
53 	__attribute__((unused)) _Bool var1;
54 
55 	switch (1) {
56 	case 1:
57 		println();
58 		/* expect+1: warning: 'var2' unused in function 'ambiguity_for_attribute' [192] */
59 		__attribute__((unused)) _Bool var2;
60 		__attribute__((fallthrough));
61 		case 2:
62 			println();
63 	}
64 }
65 
66 void
67 attribute_after_array_brackets(
68     const char *argv[] __attribute__((__unused__))
69 )
70 {
71 }
72 
73 /* just to trigger _some_ error, to keep the .exp file */
74 /* expect+1: error: syntax error 'syntax_error' [249] */
75 __attribute__((syntax_error));
76