Home | History | Annotate | Line # | Download | only in lint1
gcc_attribute.c revision 1.10
      1 /*	$NetBSD: gcc_attribute.c,v 1.10 2021/07/15 21:00:05 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 /* expect+1: syntax error 'unknown_attribute' */
     33 void __attribute__((unknown_attribute))
     34 function_with_unknown_attribute(void);
     35 
     36 /*
     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
     39  * from 2017-01-07, that variable name generated a syntax error.  Fixed in
     40  * lex.c 1.33 from 2021-05-03.
     41  *
     42  * Seen in yds.c, function yds_allocate_slots.
     43  */
     44 int
     45 local_variable_pcs(void)
     46 {
     47 	int pcs = 3;
     48 	return pcs;
     49 }
     50 
     51 /*
     52  * FIXME: The attributes are handled by different grammar rules even though
     53  *  they occur in the same syntactical position.
     54  *
     55  * Grammar rule abstract_decl_param_list handles the first attribute.
     56  *
     57  * Grammar rule direct_abstract_declarator handles all remaining attributes.
     58  *
     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.
     61  */
     62 int
     63 func(
     64     int(int)
     65     __attribute__((__noreturn__))
     66     __attribute__((__noreturn__))
     67 );
     68 
     69 /*
     70  * https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html says that the
     71  * attribute-list is a "possibly empty comma-separated sequence of
     72  * attributes".
     73  *
     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
     76  * both cases.
     77  */
     78 void one_empty_attribute(void)
     79     __attribute__((/* none */));
     80 
     81 /*
     82  * https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html further says that
     83  * each individual attribute may be "Empty. Empty attributes are ignored".
     84  */
     85 void two_empty_attributes(void)
     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")))
    102 const
    103 __attribute__((deprecated("d2")))
    104 int
    105 __attribute__((deprecated("d3")))
    106 *
    107 // The below line would produce a syntax error.
    108 // __attribute__((deprecated("d3")))
    109 const
    110 __attribute__((deprecated("d4")))
    111 identifier
    112 __attribute__((deprecated("d5")))
    113 (
    114     __attribute__((deprecated("d6")))
    115     void
    116     __attribute__((deprecated("d7")))
    117     )
    118     __attribute__((deprecated("d8")))
    119 ;
    120 
    121 /*
    122  * The attribute 'const' provides stronger guarantees than 'pure', and
    123  * 'volatile' is not defined.  To keep the grammar simple, any T_QUAL is
    124  * allowed at this point, but only syntactically.
    125  */
    126 int const_function(int) __attribute__((const));
    127 /* cover 'gcc_attribute_spec: T_QUAL' */
    128 /* expect+1: syntax error 'volatile' [249] */
    129 int volatile_function(int) __attribute__((volatile));
    130