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