| @@ -1,28 +1,69 @@ | | | @@ -1,28 +1,69 @@ |
1 | /* $NetBSD: gcc_attribute_var.c,v 1.1 2021/07/06 17:33:07 rillig Exp $ */ | | 1 | /* $NetBSD: gcc_attribute_var.c,v 1.2 2021/07/11 13:32:06 rillig Exp $ */ |
2 | # 3 "gcc_attribute_var.c" | | 2 | # 3 "gcc_attribute_var.c" |
3 | | | 3 | |
4 | /* | | 4 | /* |
5 | * Tests for the GCC __attribute__ for variables. | | 5 | * Tests for the GCC __attribute__ for variables. |
6 | * | | 6 | * |
7 | * https://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html | | 7 | * https://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html |
8 | */ | | 8 | */ |
9 | | | 9 | |
10 | void | | 10 | void |
11 | write_to_page(unsigned index, char ch) | | 11 | write_to_page(unsigned index, char ch) |
12 | { | | 12 | { |
13 | static char page[4096] | | 13 | static char page[4096] |
14 | __attribute__((__aligned__(4096))); | | 14 | __attribute__((__aligned__(4096))); |
15 | | | 15 | |
16 | page[index] = ch; | | 16 | page[index] = ch; |
17 | } | | 17 | } |
18 | | | 18 | |
19 | void | | 19 | void |
20 | placement( | | 20 | placement( |
21 | __attribute__((__deprecated__)) int before, | | 21 | __attribute__((__deprecated__)) int before, |
22 | int __attribute__((__deprecated__)) between, | | 22 | int __attribute__((__deprecated__)) between, |
23 | int after __attribute__((__deprecated__)) | | 23 | int after __attribute__((__deprecated__)) |
24 | ); | | 24 | ); |
25 | | | 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 | /*FIXME*//* expect+1: error: syntax error '_Bool' [249] */ |
| | | 54 | __attribute__((unused)) _Bool var1; |
| | | 55 | |
| | | 56 | switch (1) { |
| | | 57 | case 1: |
| | | 58 | println(); |
| | | 59 | /*FIXME*//* expect+1: error: syntax error '_Bool' [249] */ |
| | | 60 | __attribute__((unused)) _Bool var2; |
| | | 61 | __attribute__((fallthrough)); |
| | | 62 | case 2: |
| | | 63 | println(); |
| | | 64 | } |
| | | 65 | } |
| | | 66 | |
26 | /* just to trigger _some_ error, to keep the .exp file */ | | 67 | /* just to trigger _some_ error, to keep the .exp file */ |
27 | /* expect+1: error: syntax error 'syntax_error' [249] */ | | 68 | /* expect+1: error: syntax error 'syntax_error' [249] */ |
28 | __attribute__((syntax_error)); | | 69 | __attribute__((syntax_error)); |