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