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