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