gcc_attribute.c revision 1.13 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