emit.c revision 1.3 1 1.3 rillig /* $NetBSD: emit.c,v 1.3 2021/08/28 16:21:24 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.3 rillig
11 1.3 rillig
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.1 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.2 rillig
150 1.2 rillig /*
151 1.2 rillig * String literals that occur in function calls are written to the .ln file,
152 1.2 rillig * just in case they are related to a printf-like or scanf-like function.
153 1.2 rillig *
154 1.2 rillig * In this example, the various strings are not format strings, they just
155 1.2 rillig * serve to cover the code that escapes character literals (outqchar in
156 1.2 rillig * lint1) and reads them back into characters (inpqstrg in lint2).
157 1.2 rillig */
158 1.2 rillig void
159 1.2 rillig cover_outqchar(void)
160 1.2 rillig {
161 1.2 rillig my_printf("%s", "%");
162 1.2 rillig my_printf("%s", "%s");
163 1.2 rillig my_printf("%s", "%%");
164 1.2 rillig my_printf("%s", "%\a %\b %\f %\n %\r %\t %\v %\177");
165 1.2 rillig }
166 1.3 rillig
167 1.3 rillig /*
168 1.3 rillig * Calls to GCC builtin functions should not be emitted since GCC already
169 1.3 rillig * guarantees a consistent definition of these function and checks the
170 1.3 rillig * arguments, so there is nothing left to do for lint.
171 1.3 rillig */
172 1.3 rillig void
173 1.3 rillig call_gcc_builtins(int x, long *ptr)
174 1.3 rillig {
175 1.3 rillig long value;
176 1.3 rillig
177 1.3 rillig __builtin_expect(x > 0, 1);
178 1.3 rillig __builtin_bswap32(0x12345678);
179 1.3 rillig
180 1.3 rillig __atomic_load(ptr, &value, 0);
181 1.3 rillig }
182