Home | History | Annotate | Line # | Download | only in lint1
emit.c revision 1.7
      1  1.7  rillig /*	$NetBSD: emit.c,v 1.7 2021/09/10 20:02:51 rillig Exp $	*/
      2  1.1  rillig # 3 "emit.c"
      3  1.1  rillig 
      4  1.1  rillig /*
      5  1.1  rillig  * Test the symbol information that lint1 writes to a .ln file.  Using this
      6  1.1  rillig  * symbol information, lint2 later checks that the symbols are used
      7  1.1  rillig  * consistently across different translation units.
      8  1.1  rillig  */
      9  1.1  rillig 
     10  1.4  rillig /* Do not warn about unused parameters. */
     11  1.4  rillig /* lint1-extra-flags: -X 231 */
     12  1.1  rillig 
     13  1.1  rillig /*
     14  1.1  rillig  * Define some derived types.
     15  1.1  rillig  */
     16  1.1  rillig 
     17  1.1  rillig struct struct_tag {
     18  1.1  rillig 	int member;
     19  1.1  rillig };
     20  1.1  rillig 
     21  1.1  rillig typedef struct {
     22  1.1  rillig 	int member;
     23  1.1  rillig } struct_typedef;
     24  1.1  rillig 
     25  1.1  rillig union union_tag {
     26  1.1  rillig 	int member;
     27  1.1  rillig };
     28  1.1  rillig 
     29  1.1  rillig typedef union {
     30  1.1  rillig 	int member;
     31  1.1  rillig } union_typedef;
     32  1.1  rillig 
     33  1.1  rillig enum enum_tag {
     34  1.1  rillig 	enum_tag_constant
     35  1.1  rillig };
     36  1.1  rillig 
     37  1.1  rillig typedef enum {
     38  1.1  rillig 	enum_typedef_constant
     39  1.1  rillig } enum_typedef;
     40  1.1  rillig 
     41  1.1  rillig /*
     42  1.1  rillig  * Variable declarations using the basic types (C99 6.2.5p14).
     43  1.1  rillig  *
     44  1.1  rillig  * Last synced with function outtype from emit1.c 1.43.
     45  1.1  rillig  */
     46  1.1  rillig 
     47  1.1  rillig extern _Bool			extern__Bool;
     48  1.7  rillig extern float _Complex		extern__Complex_float;
     49  1.1  rillig extern double _Complex		extern__Complex_double;
     50  1.1  rillig extern long double _Complex	extern__Complex_long_double;
     51  1.1  rillig extern char			extern_char;
     52  1.1  rillig extern signed char		extern_signed_char;
     53  1.1  rillig extern unsigned char		extern_unsigned_char;
     54  1.1  rillig extern short			extern_short;
     55  1.1  rillig extern signed short		extern_signed_short;
     56  1.1  rillig extern unsigned short		extern_unsigned_short;
     57  1.1  rillig extern int			extern_int;
     58  1.1  rillig extern signed int		extern_signed_int;
     59  1.1  rillig extern unsigned int		extern_unsigned_int;
     60  1.1  rillig extern long			extern_long;
     61  1.1  rillig extern signed long		extern_signed_long;
     62  1.1  rillig extern unsigned long		extern_unsigned_long;
     63  1.1  rillig extern long long		extern_long_long;
     64  1.1  rillig extern signed long long		extern_signed_long_long;
     65  1.1  rillig extern unsigned long long	extern_unsigned_long_long;
     66  1.1  rillig extern float			extern_float;
     67  1.1  rillig extern double			extern_double;
     68  1.1  rillig extern long double		extern_long_double;
     69  1.1  rillig 
     70  1.1  rillig /*
     71  1.1  rillig  * Variable declarations using derived types (C99 6.2.5p20).
     72  1.1  rillig  */
     73  1.1  rillig 
     74  1.1  rillig extern void *			extern_pointer_to_void;
     75  1.1  rillig extern int			extern_array_5_of_int[5];
     76  1.1  rillig 
     77  1.1  rillig /*
     78  1.1  rillig  * Type tags are written to the .ln file as 'T kind length name', where 'kind'
     79  1.1  rillig  * is either 1, 2 or 3.  This is confusing at first since in 'T110struct_tag',
     80  1.1  rillig  * the apparent number 110 is to be read as 'tag kind 1, length 10'.
     81  1.1  rillig  */
     82  1.1  rillig extern struct struct_tag	extern_struct_tag;
     83  1.1  rillig extern struct_typedef		extern_struct_typedef;
     84  1.1  rillig extern union union_tag		extern_union_tag;
     85  1.1  rillig extern union_typedef		extern_union_typedef;
     86  1.1  rillig extern enum enum_tag		extern_enum_tag;
     87  1.1  rillig extern enum_typedef		extern_enum_typedef;
     88  1.1  rillig 
     89  1.1  rillig extern struct {
     90  1.1  rillig 	int member;
     91  1.1  rillig }				extern_anonymous_struct;
     92  1.1  rillig extern union {
     93  1.1  rillig 	int member;
     94  1.1  rillig }				extern_anonymous_union;
     95  1.1  rillig extern enum {
     96  1.1  rillig 	anonymous_enum_constant
     97  1.1  rillig }				extern_anonymous_enum;
     98  1.1  rillig 
     99  1.1  rillig /*
    100  1.1  rillig  * Variable definitions.
    101  1.1  rillig  *
    102  1.1  rillig  * Static variables are not recorded in the .ln file.
    103  1.1  rillig  */
    104  1.1  rillig 
    105  1.1  rillig extern int			declared_int;
    106  1.1  rillig int				defined_int;
    107  1.1  rillig static int			static_int;		/* expect: unused */
    108  1.1  rillig 
    109  1.1  rillig /*
    110  1.1  rillig  * Type qualifiers.
    111  1.1  rillig  */
    112  1.1  rillig 
    113  1.1  rillig extern const int		extern_const_int;
    114  1.1  rillig extern volatile int		extern_volatile_int;
    115  1.1  rillig extern const volatile int	extern_const_volatile_int;
    116  1.1  rillig 
    117  1.1  rillig /*
    118  1.1  rillig  * Functions.
    119  1.1  rillig  */
    120  1.1  rillig 
    121  1.1  rillig extern void return_void_unknown_parameters();
    122  1.1  rillig extern /* implicit int */ return_implicit_int_unknown_parameters();
    123  1.1  rillig 
    124  1.1  rillig /* For function declarations, the keyword 'extern' is optional. */
    125  1.1  rillig extern void extern_return_void_no_parameters(void);
    126  1.1  rillig /* implicit extern */ void return_void_no_parameters(void);
    127  1.1  rillig static void static_return_void_no_parameters(void);	/* expect: declared */
    128  1.1  rillig 
    129  1.1  rillig void taking_int(int);
    130  1.1  rillig /* The 'const' parameter does not make a difference. */
    131  1.1  rillig void taking_const_int(const int);
    132  1.1  rillig void taking_int_double_bool(int, double, _Bool);
    133  1.1  rillig void taking_struct_union_enum_tags(struct struct_tag, union union_tag,
    134  1.1  rillig     enum enum_tag);
    135  1.1  rillig void taking_struct_union_enum_typedefs(struct_typedef, union_typedef,
    136  1.1  rillig     enum_typedef);
    137  1.1  rillig 
    138  1.1  rillig void taking_varargs(const char *, ...);
    139  1.1  rillig 
    140  1.1  rillig /*
    141  1.1  rillig  * This function does not affect anything outside this translation unit.
    142  1.1  rillig  * Naively there is no need to record this function in the .ln file, but it
    143  1.1  rillig  * is nevertheless recorded.  There's probably a good reason for recording
    144  1.1  rillig  * it.
    145  1.1  rillig  */
    146  1.1  rillig static int static_function(void);			/* expect: declared */
    147  1.2  rillig 
    148  1.2  rillig void my_printf(const char *, ...);
    149  1.6  rillig void my_scanf(const char *, ...);
    150  1.2  rillig 
    151  1.2  rillig /*
    152  1.2  rillig  * String literals that occur in function calls are written to the .ln file,
    153  1.2  rillig  * just in case they are related to a printf-like or scanf-like function.
    154  1.2  rillig  *
    155  1.2  rillig  * In this example, the various strings are not format strings, they just
    156  1.2  rillig  * serve to cover the code that escapes character literals (outqchar in
    157  1.2  rillig  * lint1) and reads them back into characters (inpqstrg in lint2).
    158  1.2  rillig  */
    159  1.2  rillig void
    160  1.2  rillig cover_outqchar(void)
    161  1.2  rillig {
    162  1.2  rillig 	my_printf("%s", "%");
    163  1.2  rillig 	my_printf("%s", "%s");
    164  1.2  rillig 	my_printf("%s", "%%");
    165  1.6  rillig 	my_printf("%s", "%\\ %\" %' %\a %\b %\f %\n %\r %\t %\v %\177");
    166  1.6  rillig }
    167  1.6  rillig 
    168  1.6  rillig void
    169  1.6  rillig cover_outfstrg(void)
    170  1.6  rillig {
    171  1.6  rillig 	my_printf("%s", "%-3d %+3d % d %#x %03d %*.*s %6.2f %hd %ld %Ld %qd");
    172  1.6  rillig 	my_scanf("%s", "%[0-9]s %[^A-Za-z]s %[][A-Za-z0-9]s %[+-]s");
    173  1.2  rillig }
    174  1.3  rillig 
    175  1.3  rillig /*
    176  1.3  rillig  * Calls to GCC builtin functions should not be emitted since GCC already
    177  1.3  rillig  * guarantees a consistent definition of these function and checks the
    178  1.3  rillig  * arguments, so there is nothing left to do for lint.
    179  1.3  rillig  */
    180  1.3  rillig void
    181  1.3  rillig call_gcc_builtins(int x, long *ptr)
    182  1.3  rillig {
    183  1.3  rillig 	long value;
    184  1.3  rillig 
    185  1.3  rillig 	__builtin_expect(x > 0, 1);
    186  1.3  rillig 	__builtin_bswap32(0x12345678);
    187  1.3  rillig 
    188  1.3  rillig 	__atomic_load(ptr, &value, 0);
    189  1.3  rillig }
    190  1.4  rillig 
    191  1.4  rillig /*
    192  1.4  rillig  * XXX: It's strange that a function can be annotated with VARARGS even
    193  1.4  rillig  * though it does not take varargs at all.
    194  1.4  rillig  *
    195  1.4  rillig  * This feature is not useful for modern code anyway, it focused on pre-C90
    196  1.4  rillig  * code that did not have function prototypes.
    197  1.4  rillig  */
    198  1.4  rillig 
    199  1.4  rillig /* VARARGS */
    200  1.4  rillig void
    201  1.4  rillig varargs_comment(const char *fmt)
    202  1.4  rillig {
    203  1.4  rillig }
    204  1.4  rillig 
    205  1.4  rillig /* VARARGS 0 */
    206  1.4  rillig void
    207  1.4  rillig varargs_0_comment(const char *fmt)
    208  1.4  rillig {
    209  1.4  rillig }
    210  1.4  rillig 
    211  1.4  rillig /* VARARGS 3 */
    212  1.4  rillig void
    213  1.4  rillig varargs_3_comment(int a, int b, int c, const char *fmt)
    214  1.4  rillig {
    215  1.4  rillig }
    216  1.4  rillig 
    217  1.4  rillig /* PRINTFLIKE */
    218  1.4  rillig void
    219  1.4  rillig printflike_comment(const char *fmt)
    220  1.4  rillig {
    221  1.4  rillig }
    222  1.4  rillig 
    223  1.4  rillig /* PRINTFLIKE 0 */
    224  1.4  rillig void
    225  1.4  rillig printflike_0_comment(const char *fmt)
    226  1.4  rillig {
    227  1.4  rillig }
    228  1.4  rillig 
    229  1.4  rillig /* PRINTFLIKE 3 */
    230  1.4  rillig void
    231  1.4  rillig printflike_3_comment(int a, int b, const char *fmt)
    232  1.4  rillig {
    233  1.4  rillig }
    234  1.4  rillig 
    235  1.4  rillig /* PRINTFLIKE 10 */
    236  1.4  rillig void
    237  1.4  rillig printflike_10_comment(int a1, int a2, int a3, int a4, int a5,
    238  1.4  rillig 		      int a6, int a7, int a8, int a9,
    239  1.4  rillig 		      const char *fmt)
    240  1.4  rillig {
    241  1.4  rillig }
    242  1.4  rillig 
    243  1.4  rillig /* SCANFLIKE */
    244  1.4  rillig void
    245  1.4  rillig scanflike_comment(const char *fmt)
    246  1.4  rillig {
    247  1.4  rillig }
    248  1.4  rillig 
    249  1.4  rillig /* SCANFLIKE 0 */
    250  1.4  rillig void
    251  1.4  rillig scanflike_0_comment(const char *fmt)
    252  1.4  rillig {
    253  1.4  rillig }
    254  1.4  rillig 
    255  1.4  rillig /* SCANFLIKE 3 */
    256  1.4  rillig void
    257  1.4  rillig scanflike_3_comment(int a, int b, const char *fmt)
    258  1.4  rillig {
    259  1.4  rillig }
    260  1.5  rillig 
    261  1.5  rillig int
    262  1.5  rillig used_function(void)
    263  1.5  rillig {
    264  1.5  rillig 	return 4;
    265  1.5  rillig }
    266  1.5  rillig 
    267  1.5  rillig inline int
    268  1.5  rillig inline_function(void)
    269  1.5  rillig {
    270  1.5  rillig 	used_function();
    271  1.5  rillig 	(void)used_function();
    272  1.5  rillig 	return used_function();
    273  1.5  rillig }
    274  1.6  rillig 
    275  1.6  rillig extern int declared_used_var;
    276  1.6  rillig int defined_used_var;
    277  1.6  rillig 
    278  1.6  rillig /*
    279  1.6  rillig  * When a function is used, that usage is output as a 'c' record.
    280  1.6  rillig  * When a variable is used, that usage is output as a 'u' record.
    281  1.6  rillig  */
    282  1.6  rillig void
    283  1.6  rillig use_vars(void)
    284  1.6  rillig {
    285  1.6  rillig 	declared_used_var++;
    286  1.6  rillig 	defined_used_var++;
    287  1.6  rillig }
    288