Fri Jul 9 18:55:28 2021 UTC ()
tests/lint: ensure that GCC __attribute__ can be parsed


(rillig)
diff -r1.8 -r1.9 src/tests/usr.bin/xlint/lint1/gcc_attribute.c

cvs diff -r1.8 -r1.9 src/tests/usr.bin/xlint/lint1/gcc_attribute.c (switch to unified diff)

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