emit.c revision 1.13 1 1.13 rillig /* $NetBSD: emit.c,v 1.13 2022/06/22 19:23:18 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.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.11 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