Home | History | Annotate | Line # | Download | only in lint1
      1  1.18  rillig /*	$NetBSD: emit.c,v 1.18 2024/06/09 16:49:40 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.15  rillig /* Do not warn about unused parameters or 'extern' declarations. */
     11  1.15  rillig /* lint1-extra-flags: -X 231 -X 351 */
     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.12  rillig /* expect+1: warning: static variable 'static_int' unused [226] */
    108  1.10  rillig static int			static_int;
    109   1.1  rillig 
    110   1.1  rillig /*
    111   1.1  rillig  * Type qualifiers.
    112   1.1  rillig  */
    113   1.1  rillig 
    114   1.1  rillig extern const int		extern_const_int;
    115   1.1  rillig extern volatile int		extern_volatile_int;
    116   1.1  rillig extern const volatile int	extern_const_volatile_int;
    117   1.1  rillig 
    118   1.1  rillig /*
    119   1.1  rillig  * Functions.
    120   1.1  rillig  */
    121   1.1  rillig 
    122   1.1  rillig extern void return_void_unknown_parameters();
    123   1.1  rillig extern /* implicit int */ return_implicit_int_unknown_parameters();
    124  1.14  rillig /* expect-1: error: old-style declaration; add 'int' [1] */
    125   1.1  rillig /* For function declarations, the keyword 'extern' is optional. */
    126   1.1  rillig extern void extern_return_void_no_parameters(void);
    127   1.1  rillig /* implicit extern */ void return_void_no_parameters(void);
    128  1.13  rillig /* expect+1: warning: static function 'static_return_void_no_parameters' declared but not defined [290] */
    129  1.10  rillig static void static_return_void_no_parameters(void);
    130   1.1  rillig 
    131   1.1  rillig void taking_int(int);
    132   1.1  rillig /* The 'const' parameter does not make a difference. */
    133   1.1  rillig void taking_const_int(const int);
    134   1.1  rillig void taking_int_double_bool(int, double, _Bool);
    135   1.1  rillig void taking_struct_union_enum_tags(struct struct_tag, union union_tag,
    136   1.1  rillig     enum enum_tag);
    137   1.1  rillig void taking_struct_union_enum_typedefs(struct_typedef, union_typedef,
    138   1.1  rillig     enum_typedef);
    139   1.1  rillig 
    140   1.1  rillig void taking_varargs(const char *, ...);
    141   1.1  rillig 
    142   1.1  rillig /*
    143   1.1  rillig  * This function does not affect anything outside this translation unit.
    144   1.1  rillig  * Naively there is no need to record this function in the .ln file, but it
    145   1.1  rillig  * is nevertheless recorded.  There's probably a good reason for recording
    146   1.1  rillig  * it.
    147   1.1  rillig  */
    148  1.13  rillig /* expect+1: warning: static function 'static_function' declared but not defined [290] */
    149  1.10  rillig static int static_function(void);
    150   1.2  rillig 
    151   1.2  rillig void my_printf(const char *, ...);
    152   1.6  rillig void my_scanf(const char *, ...);
    153   1.2  rillig 
    154   1.2  rillig /*
    155   1.2  rillig  * String literals that occur in function calls are written to the .ln file,
    156   1.2  rillig  * just in case they are related to a printf-like or scanf-like function.
    157   1.2  rillig  *
    158   1.2  rillig  * In this example, the various strings are not format strings, they just
    159   1.2  rillig  * serve to cover the code that escapes character literals (outqchar in
    160   1.2  rillig  * lint1) and reads them back into characters (inpqstrg in lint2).
    161   1.2  rillig  */
    162   1.2  rillig void
    163   1.2  rillig cover_outqchar(void)
    164   1.2  rillig {
    165   1.2  rillig 	my_printf("%s", "%");
    166   1.2  rillig 	my_printf("%s", "%s");
    167   1.2  rillig 	my_printf("%s", "%%");
    168   1.6  rillig 	my_printf("%s", "%\\ %\" %' %\a %\b %\f %\n %\r %\t %\v %\177");
    169   1.6  rillig }
    170   1.6  rillig 
    171   1.6  rillig void
    172   1.6  rillig cover_outfstrg(void)
    173   1.6  rillig {
    174   1.6  rillig 	my_printf("%s", "%-3d %+3d % d %#x %03d %*.*s %6.2f %hd %ld %Ld %qd");
    175   1.6  rillig 	my_scanf("%s", "%[0-9]s %[^A-Za-z]s %[][A-Za-z0-9]s %[+-]s");
    176   1.2  rillig }
    177   1.3  rillig 
    178   1.3  rillig /*
    179   1.3  rillig  * Calls to GCC builtin functions should not be emitted since GCC already
    180   1.3  rillig  * guarantees a consistent definition of these function and checks the
    181   1.3  rillig  * arguments, so there is nothing left to do for lint.
    182   1.3  rillig  */
    183   1.3  rillig void
    184   1.3  rillig call_gcc_builtins(int x, long *ptr)
    185   1.3  rillig {
    186   1.3  rillig 	long value;
    187   1.3  rillig 
    188   1.3  rillig 	__builtin_expect(x > 0, 1);
    189   1.3  rillig 	__builtin_bswap32(0x12345678);
    190   1.3  rillig 
    191   1.3  rillig 	__atomic_load(ptr, &value, 0);
    192   1.3  rillig }
    193   1.4  rillig 
    194   1.4  rillig /*
    195   1.4  rillig  * XXX: It's strange that a function can be annotated with VARARGS even
    196   1.4  rillig  * though it does not take varargs at all.
    197   1.4  rillig  *
    198   1.4  rillig  * This feature is not useful for modern code anyway, it focused on pre-C90
    199   1.4  rillig  * code that did not have function prototypes.
    200   1.4  rillig  */
    201   1.4  rillig 
    202   1.4  rillig /* VARARGS */
    203   1.4  rillig void
    204   1.4  rillig varargs_comment(const char *fmt)
    205   1.4  rillig {
    206   1.4  rillig }
    207   1.4  rillig 
    208   1.4  rillig /* VARARGS 0 */
    209   1.4  rillig void
    210   1.4  rillig varargs_0_comment(const char *fmt)
    211   1.4  rillig {
    212   1.4  rillig }
    213   1.4  rillig 
    214   1.4  rillig /* VARARGS 3 */
    215   1.4  rillig void
    216   1.4  rillig varargs_3_comment(int a, int b, int c, const char *fmt)
    217   1.4  rillig {
    218   1.4  rillig }
    219   1.4  rillig 
    220   1.4  rillig /* PRINTFLIKE */
    221   1.4  rillig void
    222   1.4  rillig printflike_comment(const char *fmt)
    223   1.4  rillig {
    224   1.4  rillig }
    225   1.4  rillig 
    226   1.4  rillig /* PRINTFLIKE 0 */
    227   1.4  rillig void
    228   1.4  rillig printflike_0_comment(const char *fmt)
    229   1.4  rillig {
    230   1.4  rillig }
    231   1.4  rillig 
    232   1.4  rillig /* PRINTFLIKE 3 */
    233   1.4  rillig void
    234   1.4  rillig printflike_3_comment(int a, int b, const char *fmt)
    235   1.4  rillig {
    236   1.4  rillig }
    237   1.4  rillig 
    238   1.4  rillig /* PRINTFLIKE 10 */
    239   1.4  rillig void
    240   1.4  rillig printflike_10_comment(int a1, int a2, int a3, int a4, int a5,
    241   1.4  rillig 		      int a6, int a7, int a8, int a9,
    242   1.4  rillig 		      const char *fmt)
    243   1.4  rillig {
    244   1.4  rillig }
    245   1.4  rillig 
    246   1.4  rillig /* SCANFLIKE */
    247   1.4  rillig void
    248   1.4  rillig scanflike_comment(const char *fmt)
    249   1.4  rillig {
    250   1.4  rillig }
    251   1.4  rillig 
    252   1.4  rillig /* SCANFLIKE 0 */
    253   1.4  rillig void
    254   1.4  rillig scanflike_0_comment(const char *fmt)
    255   1.4  rillig {
    256   1.4  rillig }
    257   1.4  rillig 
    258   1.4  rillig /* SCANFLIKE 3 */
    259   1.4  rillig void
    260   1.4  rillig scanflike_3_comment(int a, int b, const char *fmt)
    261   1.4  rillig {
    262   1.4  rillig }
    263   1.5  rillig 
    264   1.5  rillig int
    265   1.5  rillig used_function(void)
    266   1.5  rillig {
    267   1.5  rillig 	return 4;
    268   1.5  rillig }
    269   1.5  rillig 
    270   1.5  rillig inline int
    271   1.5  rillig inline_function(void)
    272   1.5  rillig {
    273   1.5  rillig 	used_function();
    274   1.5  rillig 	(void)used_function();
    275   1.5  rillig 	return used_function();
    276   1.5  rillig }
    277   1.6  rillig 
    278   1.6  rillig extern int declared_used_var;
    279   1.6  rillig int defined_used_var;
    280   1.6  rillig 
    281   1.6  rillig /*
    282   1.6  rillig  * When a function is used, that usage is output as a 'c' record.
    283   1.6  rillig  * When a variable is used, that usage is output as a 'u' record.
    284   1.6  rillig  */
    285   1.6  rillig void
    286   1.6  rillig use_vars(void)
    287   1.6  rillig {
    288   1.6  rillig 	declared_used_var++;
    289   1.6  rillig 	defined_used_var++;
    290   1.6  rillig }
    291   1.8  rillig 
    292   1.8  rillig /*
    293   1.8  rillig  * Since C99, an initializer may contain a compound expression. This allows
    294   1.8  rillig  * to create trees of pointer data structures at compile time.
    295   1.8  rillig  *
    296   1.8  rillig  * The objects that are created for these compound literals are unnamed,
    297   1.8  rillig  * therefore there is no point in exporting them to the .ln file.
    298   1.8  rillig  *
    299   1.9  rillig  * Before emit1.c 1.60 from 2021-11-28, lint exported them.
    300   1.8  rillig  */
    301   1.8  rillig struct compound_expression_in_initializer {
    302   1.8  rillig 	const char * const *info;
    303   1.8  rillig };
    304   1.8  rillig 
    305   1.8  rillig struct compound_expression_in_initializer compound = {
    306   1.8  rillig 	.info = (const char *[16]){
    307   1.8  rillig 		[0] = "zero",
    308   1.8  rillig 	},
    309   1.8  rillig };
    310  1.16  rillig 
    311  1.16  rillig /*
    312  1.17  rillig  * Before decl.c 1.312 and init.c 1.242 from 2023-05-22, the type that ended up
    313  1.17  rillig  * in the .ln file was 'A0cC', which was wrong as it had array size 0 instead
    314  1.17  rillig  * of the correct 8.  That type had been taken too early, before looking at the
    315  1.16  rillig  * initializer.
    316  1.16  rillig  */
    317  1.16  rillig const char array_of_unknown_size[] = "unknown";
    318  1.18  rillig 
    319  1.18  rillig int used_and_using(int);
    320  1.18  rillig int only_used(void);
    321  1.18  rillig 
    322  1.18  rillig int
    323  1.18  rillig only_using(void)
    324  1.18  rillig {
    325  1.18  rillig 	return used_and_using(only_used());
    326  1.18  rillig }
    327