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