1 /* $NetBSD: gcc_attribute.c,v 1.12 2022/08/25 19:03:48 rillig Exp $ */ 2 # 3 "gcc_attribute.c" 3 4 /* 5 * Tests for the various attributes for functions, types, statements that are 6 * provided by GCC. 7 * 8 * https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html 9 */ 10 11 void __attribute__((noinline)) 12 do_not_inline(void) 13 { 14 } 15 16 /* All pointer arguments must be nonnull. */ 17 void __attribute__((nonnull)) 18 function_nonnull(void *, const void *, int); 19 20 /* 21 * The documentation suggests that the argument list of nonnull be nonempty, 22 * but GCC 9.3.0 accepts an empty list as well, treating all parameters as 23 * nonnull. 24 */ 25 void __attribute__((nonnull())) 26 function_nonnull_list(void *, const void *, int); 27 28 /* Arguments 1 and 2 must be nonnull. */ 29 void __attribute__((nonnull(1, 2))) 30 function_nonnull_list(void *, const void *, int); 31 32 /* 33 * Unknown attributes are skipped, as lint does not have a list of all known 34 * GCC attributes. 35 */ 36 void __attribute__((unknown_attribute)) 37 function_with_unknown_attribute(void); 38 39 /* 40 * There is an attribute called 'pcs', but that attribute must not prevent an 41 * ordinary variable from being named the same. Starting with scan.l 1.77 42 * from 2017-01-07, that variable name generated a syntax error. Fixed in 43 * lex.c 1.33 from 2021-05-03. 44 * 45 * Seen in yds.c, function yds_allocate_slots. 46 */ 47 int 48 local_variable_pcs(void) 49 { 50 int pcs = 3; 51 return pcs; 52 } 53 54 /* 55 * FIXME: The attributes are handled by different grammar rules even though 56 * they occur in the same syntactical position. 57 * 58 * Grammar rule abstract_decl_param_list handles the first attribute. 59 * 60 * Grammar rule direct_abstract_declarator handles all remaining attributes. 61 * 62 * Since abstract_decl_param_list contains type_attribute_opt, this could be 63 * the source of the many shift/reduce conflicts in the grammar. 64 */ 65 int 66 func( 67 int(int) 68 __attribute__((__noreturn__)) 69 __attribute__((__noreturn__)) 70 ); 71 72 /* 73 * https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html says that the 74 * attribute-list is a "possibly empty comma-separated sequence of 75 * attributes". 76 * 77 * No matter whether this particular example is interpreted as an empty list 78 * or a list containing a single empty attribute, the result is the same in 79 * both cases. 80 */ 81 void one_empty_attribute(void) 82 __attribute__((/* none */)); 83 84 /* 85 * https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html further says that 86 * each individual attribute may be "Empty. Empty attributes are ignored". 87 */ 88 void two_empty_attributes(void) 89 __attribute__((/* none */, /* still none */)); 90 91 /* 92 * Ensure that __attribute__ can be specified everywhere in a declaration. 93 * This is the simplest possible requirement that covers all valid code. 94 * It accepts invalid code as well, but these cases are covered by GCC and 95 * Clang already. 96 * 97 * Since lint only parses the attributes but doesn't really relate them to 98 * identifiers or other entities, ensuring that valid code can be parsed is 99 * enough for now. 100 * 101 * To really associate __attribute__ with the corresponding entity, the 102 * grammar needs to be rewritten, see the example with __noreturn__ above. 103 */ 104 __attribute__((deprecated("d1"))) 105 const 106 __attribute__((deprecated("d2"))) 107 int 108 __attribute__((deprecated("d3"))) 109 * 110 // The below line would produce a syntax error. 111 // __attribute__((deprecated("d3"))) 112 const 113 __attribute__((deprecated("d4"))) 114 identifier 115 __attribute__((deprecated("d5"))) 116 ( 117 __attribute__((deprecated("d6"))) 118 void 119 __attribute__((deprecated("d7"))) 120 ) 121 __attribute__((deprecated("d8"))) 122 ; 123 124 /* 125 * The attribute 'const' provides stronger guarantees than 'pure', and 126 * 'volatile' is not defined. To keep the grammar simple, any T_QUAL is 127 * allowed at this point, but only syntactically. 128 */ 129 int const_function(int) __attribute__((const)); 130 /* cover 'gcc_attribute_spec: T_QUAL' */ 131 /* expect+1: error: syntax error 'volatile' [249] */ 132 int volatile_function(int) __attribute__((volatile)); 133