lex.c revision 1.175 1 /* $NetBSD: lex.c,v 1.175 2023/07/12 10:08:11 rillig Exp $ */
2
3 /*
4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
5 * Copyright (c) 1994, 1995 Jochen Pohl
6 * All Rights Reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by Jochen Pohl for
19 * The NetBSD Project.
20 * 4. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 #if HAVE_NBTOOL_CONFIG_H
36 #include "nbtool_config.h"
37 #endif
38
39 #include <sys/cdefs.h>
40 #if defined(__RCSID)
41 __RCSID("$NetBSD: lex.c,v 1.175 2023/07/12 10:08:11 rillig Exp $");
42 #endif
43
44 #include <ctype.h>
45 #include <errno.h>
46 #include <float.h>
47 #include <limits.h>
48 #include <math.h>
49 #include <stdlib.h>
50 #include <string.h>
51
52 #include "lint1.h"
53 #include "cgram.h"
54
55 #define CHAR_MASK ((1U << CHAR_SIZE) - 1)
56
57
58 /* Current position (it's also updated when an included file is parsed) */
59 pos_t curr_pos = { "", 1, 0 };
60
61 /*
62 * Current position in C source (not updated when an included file is
63 * parsed).
64 */
65 pos_t csrc_pos = { "", 1, 0 };
66
67 bool in_gcc_attribute;
68 bool in_system_header;
69
70 /*
71 * Valid values for 'since' are 78, 90, 99, 11.
72 *
73 * The C11 keywords are added in C99 mode as well, to provide good error
74 * messages instead of a simple parse error. If the keyword '_Generic' were
75 * not defined, it would be interpreted as an implicit function call, leading
76 * to a parse error.
77 */
78 #define kwdef(name, token, detail, since, gcc, deco) \
79 { \
80 name, token, detail, \
81 (since) == 90, \
82 /* CONSTCOND */ (since) == 99 || (since) == 11, \
83 (gcc) > 0, \
84 ((deco) & 1) != 0, ((deco) & 2) != 0, ((deco) & 4) != 0, \
85 }
86 #define kwdef_token(name, token, since, gcc, deco) \
87 kwdef(name, token, {false}, since, gcc, deco)
88 #define kwdef_sclass(name, sclass, since, gcc, deco) \
89 kwdef(name, T_SCLASS, .u.kw_scl = (sclass), since, gcc, deco)
90 #define kwdef_type(name, tspec, since) \
91 kwdef(name, T_TYPE, .u.kw_tspec = (tspec), since, 0, 1)
92 #define kwdef_tqual(name, tqual, since, gcc, deco) \
93 kwdef(name, T_QUAL, .u.kw_tqual = (tqual), since, gcc, deco)
94 #define kwdef_keyword(name, token) \
95 kwdef(name, token, {false}, 78, 0, 1)
96
97 /* During initialization, these keywords are written to the symbol table. */
98 static const struct keyword {
99 const char *kw_name;
100 int kw_token; /* token returned by yylex() */
101 union {
102 bool kw_dummy;
103 scl_t kw_scl; /* if kw_token is T_SCLASS */
104 tspec_t kw_tspec; /* if kw_token is T_TYPE or
105 * T_STRUCT_OR_UNION */
106 tqual_t kw_tqual; /* if kw_token is T_QUAL */
107 } u;
108 bool kw_c90:1; /* available in C90 mode */
109 bool kw_c99_or_c11:1; /* available in C99 or C11 mode */
110 bool kw_gcc:1; /* available in GCC mode */
111 bool kw_plain:1; /* 'name' */
112 bool kw_leading:1; /* '__name' */
113 bool kw_both:1; /* '__name__' */
114 } keywords[] = {
115 kwdef_keyword( "_Alignas", T_ALIGNAS),
116 kwdef_keyword( "_Alignof", T_ALIGNOF),
117 kwdef_token( "alignof", T_ALIGNOF, 78,0,6),
118 kwdef_token( "asm", T_ASM, 78,1,7),
119 kwdef_token( "_Atomic", T_ATOMIC, 11,0,1),
120 kwdef_token( "attribute", T_ATTRIBUTE, 78,1,6),
121 kwdef_sclass( "auto", AUTO, 78,0,1),
122 kwdef_type( "_Bool", BOOL, 99),
123 kwdef_keyword( "break", T_BREAK),
124 kwdef_token( "__builtin_offsetof", T_BUILTIN_OFFSETOF, 78,1,1),
125 kwdef_keyword( "case", T_CASE),
126 kwdef_type( "char", CHAR, 78),
127 kwdef_type( "_Complex", COMPLEX, 99),
128 kwdef_tqual( "const", CONST, 90,0,7),
129 kwdef_keyword( "continue", T_CONTINUE),
130 kwdef_keyword( "default", T_DEFAULT),
131 kwdef_keyword( "do", T_DO),
132 kwdef_type( "double", DOUBLE, 78),
133 kwdef_keyword( "else", T_ELSE),
134 kwdef_keyword( "enum", T_ENUM),
135 kwdef_token( "__extension__",T_EXTENSION, 78,1,1),
136 kwdef_sclass( "extern", EXTERN, 78,0,1),
137 kwdef_type( "float", FLOAT, 78),
138 kwdef_keyword( "for", T_FOR),
139 kwdef_token( "_Generic", T_GENERIC, 11,0,1),
140 kwdef_keyword( "goto", T_GOTO),
141 kwdef_keyword( "if", T_IF),
142 kwdef_token( "__imag__", T_IMAG, 78,1,1),
143 kwdef_sclass( "inline", INLINE, 99,0,7),
144 kwdef_type( "int", INT, 78),
145 #ifdef INT128_SIZE
146 kwdef_type( "__int128_t", INT128, 99),
147 #endif
148 kwdef_type( "long", LONG, 78),
149 kwdef_token( "_Noreturn", T_NORETURN, 11,0,1),
150 kwdef_token( "__packed", T_PACKED, 78,0,1),
151 kwdef_token( "__real__", T_REAL, 78,1,1),
152 kwdef_sclass( "register", REG, 78,0,1),
153 kwdef_tqual( "restrict", RESTRICT, 99,0,7),
154 kwdef_keyword( "return", T_RETURN),
155 kwdef_type( "short", SHORT, 78),
156 kwdef( "signed", T_TYPE, .u.kw_tspec = SIGNED, 90,0,3),
157 kwdef_keyword( "sizeof", T_SIZEOF),
158 kwdef_sclass( "static", STATIC, 78,0,1),
159 kwdef_keyword( "_Static_assert", T_STATIC_ASSERT),
160 kwdef("struct", T_STRUCT_OR_UNION, .u.kw_tspec = STRUCT, 78,0,1),
161 kwdef_keyword( "switch", T_SWITCH),
162 kwdef_token( "__symbolrename", T_SYMBOLRENAME, 78,0,1),
163 kwdef_tqual( "__thread", THREAD, 78,1,1),
164 /* XXX: _Thread_local is a storage-class-specifier, not tqual. */
165 kwdef_tqual( "_Thread_local", THREAD, 11,0,1),
166 kwdef_sclass( "typedef", TYPEDEF, 78,0,1),
167 kwdef_token( "typeof", T_TYPEOF, 78,1,7),
168 #ifdef INT128_SIZE
169 kwdef_type( "__uint128_t", UINT128, 99),
170 #endif
171 kwdef("union", T_STRUCT_OR_UNION, .u.kw_tspec = UNION, 78,0,1),
172 kwdef_type( "unsigned", UNSIGN, 78),
173 kwdef_type( "void", VOID, 78),
174 kwdef_tqual( "volatile", VOLATILE, 90,0,7),
175 kwdef_keyword( "while", T_WHILE),
176 #undef kwdef
177 #undef kwdef_token
178 #undef kwdef_sclass
179 #undef kwdef_type
180 #undef kwdef_tqual
181 #undef kwdef_keyword
182 };
183
184 /*
185 * The symbol table containing all keywords, identifiers and labels. The hash
186 * entries are linked via sym_t.s_symtab_next.
187 */
188 static sym_t *symtab[503];
189
190 /*
191 * The kind of the next expected symbol, to distinguish the namespaces of
192 * members, labels, type tags and other identifiers.
193 */
194 symt_t symtyp;
195
196
197 static unsigned int
198 hash(const char *s)
199 {
200 unsigned int v;
201 const char *p;
202
203 v = 0;
204 for (p = s; *p != '\0'; p++) {
205 v = (v << 4) + (unsigned char)*p;
206 v ^= v >> 28;
207 }
208 return v % (sizeof(symtab) / sizeof(symtab[0]));
209 }
210
211 static void
212 symtab_add(sym_t *sym)
213 {
214 unsigned int h;
215
216 h = hash(sym->s_name);
217 if ((sym->s_symtab_next = symtab[h]) != NULL)
218 symtab[h]->s_symtab_ref = &sym->s_symtab_next;
219 sym->s_symtab_ref = &symtab[h];
220 symtab[h] = sym;
221 }
222
223 static sym_t *
224 symtab_search(const char *name)
225 {
226
227 unsigned int h = hash(name);
228 for (sym_t *sym = symtab[h]; sym != NULL; sym = sym->s_symtab_next) {
229 if (strcmp(sym->s_name, name) != 0)
230 continue;
231 if (sym->s_keyword != NULL ||
232 sym->s_kind == symtyp ||
233 in_gcc_attribute)
234 return sym;
235 }
236
237 return NULL;
238 }
239
240 static void
241 symtab_remove(sym_t *sym)
242 {
243
244 if ((*sym->s_symtab_ref = sym->s_symtab_next) != NULL)
245 sym->s_symtab_next->s_symtab_ref = sym->s_symtab_ref;
246 sym->s_symtab_next = NULL;
247 }
248
249 static void
250 symtab_remove_locals(void)
251 {
252
253 for (size_t i = 0; i < sizeof(symtab) / sizeof(symtab[0]); i++) {
254 for (sym_t *sym = symtab[i]; sym != NULL; ) {
255 sym_t *next = sym->s_symtab_next;
256 if (sym->s_block_level >= 1)
257 symtab_remove(sym);
258 sym = next;
259 }
260 }
261 }
262
263 #ifdef DEBUG
264 static int
265 sym_by_name(const void *va, const void *vb)
266 {
267 const sym_t *a = *(const sym_t *const *)va;
268 const sym_t *b = *(const sym_t *const *)vb;
269
270 return strcmp(a->s_name, b->s_name);
271 }
272
273 struct syms {
274 const sym_t **items;
275 size_t len;
276 size_t cap;
277 };
278
279 static void
280 syms_add(struct syms *syms, const sym_t *sym)
281 {
282 if (syms->len >= syms->cap) {
283 syms->cap *= 2;
284 syms->items = xrealloc(syms->items,
285 syms->cap * sizeof(syms->items[0]));
286 }
287 syms->items[syms->len++] = sym;
288 }
289
290 void
291 debug_symtab(void)
292 {
293 struct syms syms = { xcalloc(64, sizeof(syms.items[0])), 0, 64 };
294
295 for (int level = -1;; level++) {
296 bool more = false;
297 size_t n = sizeof(symtab) / sizeof(symtab[0]);
298
299 syms.len = 0;
300 for (size_t i = 0; i < n; i++) {
301 for (sym_t *sym = symtab[i]; sym != NULL;) {
302 if (sym->s_block_level == level &&
303 sym->s_keyword == NULL)
304 syms_add(&syms, sym);
305 if (sym->s_block_level > level)
306 more = true;
307 sym = sym->s_symtab_next;
308 }
309 }
310
311 if (syms.len > 0) {
312 debug_printf("symbol table level %d\n", level);
313 debug_indent_inc();
314 qsort(syms.items, syms.len, sizeof(syms.items[0]),
315 sym_by_name);
316 for (size_t i = 0; i < syms.len; i++)
317 debug_sym("", syms.items[i], "\n");
318 debug_indent_dec();
319
320 lint_assert(level != -1);
321 }
322
323 if (!more)
324 break;
325 }
326
327 free(syms.items);
328 }
329 #endif
330
331 static void
332 add_keyword(const struct keyword *kw, bool leading, bool trailing)
333 {
334
335 const char *name;
336 if (!leading && !trailing) {
337 name = kw->kw_name;
338 } else {
339 char buf[256];
340 (void)snprintf(buf, sizeof(buf), "%s%s%s",
341 leading ? "__" : "", kw->kw_name, trailing ? "__" : "");
342 name = xstrdup(buf);
343 }
344
345 sym_t *sym = block_zero_alloc(sizeof(*sym));
346 sym->s_name = name;
347 sym->s_keyword = kw;
348 int tok = kw->kw_token;
349 sym->u.s_keyword.sk_token = tok;
350 if (tok == T_TYPE || tok == T_STRUCT_OR_UNION)
351 sym->u.s_keyword.sk_tspec = kw->u.kw_tspec;
352 if (tok == T_SCLASS)
353 sym->s_scl = kw->u.kw_scl;
354 if (tok == T_QUAL)
355 sym->u.s_keyword.sk_qualifier = kw->u.kw_tqual;
356
357 symtab_add(sym);
358 }
359
360 static bool
361 is_keyword_known(const struct keyword *kw)
362 {
363
364 if ((kw->kw_c90 || kw->kw_c99_or_c11) && !allow_c90)
365 return false;
366
367 /*
368 * In the 1990s, GCC defined several keywords that were later
369 * incorporated into C99, therefore in GCC mode, all C99 keywords are
370 * made available. The C11 keywords are made available as well, but
371 * there are so few that they don't matter practically.
372 */
373 if (allow_gcc)
374 return true;
375 if (kw->kw_gcc)
376 return false;
377
378 if (kw->kw_c99_or_c11 && !allow_c99)
379 return false;
380 return true;
381 }
382
383 /* Write all keywords to the symbol table. */
384 void
385 initscan(void)
386 {
387
388 size_t n = sizeof(keywords) / sizeof(keywords[0]);
389 for (size_t i = 0; i < n; i++) {
390 const struct keyword *kw = keywords + i;
391 if (!is_keyword_known(kw))
392 continue;
393 if (kw->kw_plain)
394 add_keyword(kw, false, false);
395 if (kw->kw_leading)
396 add_keyword(kw, true, false);
397 if (kw->kw_both)
398 add_keyword(kw, true, true);
399 }
400 }
401
402 /*
403 * When scanning the remainder of a long token (see lex_input), read a byte
404 * and return it as an unsigned char or as EOF.
405 *
406 * Increment the line counts if necessary.
407 */
408 static int
409 read_byte(void)
410 {
411 int c;
412
413 if ((c = lex_input()) == EOF)
414 return c;
415 if (c == '\0')
416 return EOF; /* lex returns 0 on EOF. */
417 if (c == '\n')
418 lex_next_line();
419 return c;
420 }
421
422 static int
423 lex_keyword(sym_t *sym)
424 {
425 int tok = sym->u.s_keyword.sk_token;
426
427 if (tok == T_SCLASS)
428 yylval.y_scl = sym->s_scl;
429 if (tok == T_TYPE || tok == T_STRUCT_OR_UNION)
430 yylval.y_tspec = sym->u.s_keyword.sk_tspec;
431 if (tok == T_QUAL)
432 yylval.y_tqual = sym->u.s_keyword.sk_qualifier;
433 return tok;
434 }
435
436 /*
437 * Look up the definition of a name in the symbol table. This symbol must
438 * either be a keyword or a symbol of the type required by symtyp (label,
439 * member, tag, ...).
440 */
441 extern int
442 lex_name(const char *yytext, size_t yyleng)
443 {
444
445 sym_t *sym = symtab_search(yytext);
446 if (sym != NULL && sym->s_keyword != NULL)
447 return lex_keyword(sym);
448
449 sbuf_t *sb = xmalloc(sizeof(*sb));
450 sb->sb_len = yyleng;
451 sb->sb_sym = sym;
452 yylval.y_name = sb;
453
454 if (sym != NULL) {
455 lint_assert(block_level >= sym->s_block_level);
456 sb->sb_name = sym->s_name;
457 return sym->s_scl == TYPEDEF ? T_TYPENAME : T_NAME;
458 }
459
460 char *name = block_zero_alloc(yyleng + 1);
461 (void)memcpy(name, yytext, yyleng + 1);
462 sb->sb_name = name;
463 return T_NAME;
464 }
465
466 int
467 lex_integer_constant(const char *yytext, size_t yyleng, int base)
468 {
469 /* C11 6.4.4.1p5 */
470 static const tspec_t suffix_type[2][3] = {
471 { INT, LONG, LLONG, },
472 { UINT, ULONG, ULLONG, }
473 };
474
475 const char *cp = yytext;
476 size_t len = yyleng;
477
478 /* skip 0[xX] or 0[bB] */
479 if (base == 16 || base == 2) {
480 cp += 2;
481 len -= 2;
482 }
483
484 /* read suffixes */
485 unsigned l_suffix = 0, u_suffix = 0;
486 for (;; len--) {
487 char c = cp[len - 1];
488 if (c == 'l' || c == 'L')
489 l_suffix++;
490 else if (c == 'u' || c == 'U')
491 u_suffix++;
492 else
493 break;
494 }
495 if (l_suffix > 2 || u_suffix > 1) {
496 /* malformed integer constant */
497 warning(251);
498 if (l_suffix > 2)
499 l_suffix = 2;
500 if (u_suffix > 1)
501 u_suffix = 1;
502 }
503 if (!allow_c90 && u_suffix > 0) {
504 /* suffix 'U' is illegal in traditional C */
505 warning(97);
506 }
507 tspec_t typ = suffix_type[u_suffix][l_suffix];
508
509 bool warned = false;
510 errno = 0;
511 char *eptr;
512 uint64_t ui = (uint64_t)strtoull(cp, &eptr, base);
513 lint_assert(eptr == cp + len);
514 if (errno != 0) {
515 /* integer constant out of range */
516 warning(252);
517 warned = true;
518 }
519
520 if (any_query_enabled && base == 8 && ui != 0) {
521 /* octal number '%.*s' */
522 query_message(8, (int)len, cp);
523 }
524
525 /*
526 * If the value is too big for the current type, we must choose
527 * another type.
528 */
529 bool ansiu = false;
530 switch (typ) {
531 case INT:
532 if (ui <= TARG_INT_MAX) {
533 /* ok */
534 } else if (ui <= TARG_UINT_MAX && base != 10) {
535 typ = UINT;
536 } else if (ui <= TARG_LONG_MAX) {
537 typ = LONG;
538 } else {
539 typ = ULONG;
540 if (ui > TARG_ULONG_MAX && !warned) {
541 /* integer constant out of range */
542 warning(252);
543 }
544 }
545 if (typ == UINT || typ == ULONG) {
546 if (!allow_c90) {
547 typ = LONG;
548 } else if (allow_trad) {
549 /*
550 * Remember that the constant is unsigned
551 * only in ANSI C.
552 */
553 ansiu = true;
554 }
555 }
556 break;
557 case UINT:
558 if (ui > TARG_UINT_MAX) {
559 typ = ULONG;
560 if (ui > TARG_ULONG_MAX && !warned) {
561 /* integer constant out of range */
562 warning(252);
563 }
564 }
565 break;
566 case LONG:
567 if (ui > TARG_LONG_MAX && allow_c90) {
568 typ = ULONG;
569 if (allow_trad)
570 ansiu = true;
571 if (ui > TARG_ULONG_MAX && !warned) {
572 /* integer constant out of range */
573 warning(252);
574 }
575 }
576 break;
577 case ULONG:
578 if (ui > TARG_ULONG_MAX && !warned) {
579 /* integer constant out of range */
580 warning(252);
581 }
582 break;
583 case LLONG:
584 if (ui > TARG_LLONG_MAX && allow_c90)
585 typ = ULLONG;
586 break;
587 case ULLONG:
588 if (ui > TARG_ULLONG_MAX && !warned) {
589 /* integer constant out of range */
590 warning(252);
591 }
592 break;
593 default:
594 break;
595 }
596
597 ui = (uint64_t)convert_integer((int64_t)ui, typ, 0);
598
599 yylval.y_val = xcalloc(1, sizeof(*yylval.y_val));
600 yylval.y_val->v_tspec = typ;
601 yylval.y_val->v_unsigned_since_c90 = ansiu;
602 yylval.y_val->u.integer = (int64_t)ui;
603
604 return T_CON;
605 }
606
607 /*
608 * Extend or truncate si to match t. If t is signed, sign-extend.
609 *
610 * len is the number of significant bits. If len is 0, len is set
611 * to the width of type t.
612 */
613 int64_t
614 convert_integer(int64_t si, tspec_t t, unsigned int len)
615 {
616
617 if (len == 0)
618 len = size_in_bits(t);
619
620 uint64_t vbits = value_bits(len);
621 uint64_t ui = (uint64_t)si;
622 return t == PTR || is_uinteger(t) || ((ui & bit(len - 1)) == 0)
623 ? (int64_t)(ui & vbits)
624 : (int64_t)(ui | ~vbits);
625 }
626
627 int
628 lex_floating_constant(const char *yytext, size_t yyleng)
629 {
630 const char *cp = yytext;
631 size_t len = yyleng;
632
633 bool imaginary = cp[len - 1] == 'i';
634 if (imaginary)
635 len--;
636
637 char c = cp[len - 1];
638 tspec_t typ;
639 if (c == 'f' || c == 'F') {
640 typ = imaginary ? FCOMPLEX : FLOAT;
641 len--;
642 } else if (c == 'l' || c == 'L') {
643 typ = imaginary ? LCOMPLEX : LDOUBLE;
644 len--;
645 } else
646 typ = imaginary ? DCOMPLEX : DOUBLE;
647
648 if (!allow_c90 && typ != DOUBLE) {
649 /* suffixes 'F' and 'L' are illegal in traditional C */
650 warning(98);
651 }
652
653 errno = 0;
654 char *eptr;
655 long double ld = strtold(cp, &eptr);
656 lint_assert(eptr == cp + len);
657 if (errno != 0) {
658 /* floating-point constant out of range */
659 warning(248);
660 } else if (typ == FLOAT) {
661 ld = (float)ld;
662 if (isfinite(ld) == 0) {
663 /* floating-point constant out of range */
664 warning(248);
665 ld = ld > 0 ? FLT_MAX : -FLT_MAX;
666 }
667 } else if (typ == DOUBLE
668 || /* CONSTCOND */LDOUBLE_SIZE == DOUBLE_SIZE) {
669 ld = (double)ld;
670 if (isfinite(ld) == 0) {
671 /* floating-point constant out of range */
672 warning(248);
673 ld = ld > 0 ? DBL_MAX : -DBL_MAX;
674 }
675 }
676
677 yylval.y_val = xcalloc(1, sizeof(*yylval.y_val));
678 yylval.y_val->v_tspec = typ;
679 yylval.y_val->u.floating = ld;
680
681 return T_CON;
682 }
683
684 int
685 lex_operator(int t, op_t o)
686 {
687
688 yylval.y_op = o;
689 return t;
690 }
691
692 static int prev_byte = -1;
693
694 static int
695 read_escaped_oct(int c)
696 {
697 int n = 3;
698 int value = 0;
699 do {
700 value = (value << 3) + (c - '0');
701 c = read_byte();
702 } while (--n > 0 && '0' <= c && c <= '7');
703 prev_byte = c;
704 if (value > TARG_UCHAR_MAX) {
705 /* character escape does not fit in character */
706 warning(76);
707 value &= CHAR_MASK;
708 }
709 return value;
710 }
711
712 static unsigned int
713 read_escaped_hex(int c)
714 {
715 if (!allow_c90)
716 /* \x undefined in traditional C */
717 warning(82);
718 unsigned int value = 0;
719 int state = 0; /* 0 = no digits, 1 = OK, 2 = overflow */
720 while (c = read_byte(), isxdigit(c)) {
721 c = isdigit(c) ? c - '0' : toupper(c) - 'A' + 10;
722 value = (value << 4) + c;
723 if (state == 2)
724 continue;
725 if ((value & ~CHAR_MASK) != 0) {
726 /* overflow in hex escape */
727 warning(75);
728 state = 2;
729 } else {
730 state = 1;
731 }
732 }
733 prev_byte = c;
734 if (state == 0) {
735 /* no hex digits follow \x */
736 error(74);
737 }
738 if (state == 2)
739 value &= CHAR_MASK;
740 return value;
741 }
742
743 static int
744 read_escaped_backslash(int delim)
745 {
746 int c;
747
748 switch (c = read_byte()) {
749 case '"':
750 if (!allow_c90 && delim == '\'')
751 /* \" inside character constants undef... */
752 warning(262);
753 return '"';
754 case '\'':
755 return '\'';
756 case '?':
757 if (!allow_c90)
758 /* \? undefined in traditional C */
759 warning(263);
760 return '?';
761 case '\\':
762 return '\\';
763 case 'a':
764 if (!allow_c90)
765 /* \a undefined in traditional C */
766 warning(81);
767 return '\a';
768 case 'b':
769 return '\b';
770 case 'f':
771 return '\f';
772 case 'n':
773 return '\n';
774 case 'r':
775 return '\r';
776 case 't':
777 return '\t';
778 case 'v':
779 if (!allow_c90)
780 /* \v undefined in traditional C */
781 warning(264);
782 return '\v';
783 case '8': case '9':
784 /* bad octal digit '%c' */
785 warning(77, c);
786 /* FALLTHROUGH */
787 case '0': case '1': case '2': case '3':
788 case '4': case '5': case '6': case '7':
789 return read_escaped_oct(c);
790 case 'x':
791 return (int)read_escaped_hex(c);
792 case '\n':
793 return -3;
794 case EOF:
795 return -2;
796 default:
797 if (isprint(c)) {
798 /* dubious escape \%c */
799 warning(79, c);
800 } else {
801 /* dubious escape \%o */
802 warning(80, c);
803 }
804 return c;
805 }
806 }
807
808 /*
809 * Read a character which is part of a character constant or of a string
810 * and handle escapes.
811 *
812 * 'delim' is '\'' for character constants and '"' for string literals.
813 *
814 * Returns -1 if the end of the character constant or string is reached,
815 * -2 if the EOF is reached, and the character otherwise.
816 */
817 static int
818 get_escaped_char(int delim)
819 {
820
821 int c = prev_byte;
822 if (c != -1)
823 prev_byte = -1;
824 else
825 c = read_byte();
826
827 if (c == delim)
828 return -1;
829 switch (c) {
830 case '\n':
831 if (!allow_c90) {
832 /* newline in string or char constant */
833 error(254);
834 return -2;
835 }
836 return c;
837 case '\0':
838 /* syntax error '%s' */
839 error(249, "EOF or null byte in literal");
840 return -2;
841 case EOF:
842 return -2;
843 case '\\':
844 c = read_escaped_backslash(delim);
845 if (c == -3)
846 return get_escaped_char(delim);
847 }
848 return c;
849 }
850
851 /* Called if lex found a leading "'". */
852 int
853 lex_character_constant(void)
854 {
855 size_t n;
856 int val, c;
857
858 n = 0;
859 val = 0;
860 while ((c = get_escaped_char('\'')) >= 0) {
861 val = (int)((unsigned int)val << CHAR_SIZE) + c;
862 n++;
863 }
864 if (c == -2) {
865 /* unterminated character constant */
866 error(253);
867 } else if (n > sizeof(int) || (n > 1 && (pflag || hflag))) {
868 /*
869 * XXX: ^^ should rather be sizeof(TARG_INT). Luckily,
870 * sizeof(int) is the same on all supported platforms.
871 */
872 /* too many characters in character constant */
873 error(71);
874 } else if (n > 1) {
875 /* multi-character character constant */
876 warning(294);
877 } else if (n == 0) {
878 /* empty character constant */
879 error(73);
880 }
881 if (n == 1)
882 val = (int)convert_integer(val, CHAR, CHAR_SIZE);
883
884 yylval.y_val = xcalloc(1, sizeof(*yylval.y_val));
885 yylval.y_val->v_tspec = INT;
886 yylval.y_val->v_char_constant = true;
887 yylval.y_val->u.integer = val;
888
889 return T_CON;
890 }
891
892 /*
893 * Called if lex found a leading L\'
894 */
895 int
896 lex_wide_character_constant(void)
897 {
898 static char buf[MB_LEN_MAX + 1];
899 size_t n, nmax;
900 int c;
901 wchar_t wc;
902
903 nmax = MB_CUR_MAX;
904
905 n = 0;
906 while ((c = get_escaped_char('\'')) >= 0) {
907 if (n < nmax)
908 buf[n] = (char)c;
909 n++;
910 }
911
912 wc = 0;
913
914 if (c == -2) {
915 /* unterminated character constant */
916 error(253);
917 } else if (n == 0) {
918 /* empty character constant */
919 error(73);
920 } else if (n > nmax) {
921 n = nmax;
922 /* too many characters in character constant */
923 error(71);
924 } else {
925 buf[n] = '\0';
926 (void)mbtowc(NULL, NULL, 0);
927 if (mbtowc(&wc, buf, nmax) < 0)
928 /* invalid multibyte character */
929 error(291);
930 }
931
932 yylval.y_val = xcalloc(1, sizeof(*yylval.y_val));
933 yylval.y_val->v_tspec = WCHAR_TSPEC;
934 yylval.y_val->v_char_constant = true;
935 yylval.y_val->u.integer = wc;
936
937 return T_CON;
938 }
939
940 /* See https://gcc.gnu.org/onlinedocs/cpp/Preprocessor-Output.html */
941 static void
942 parse_line_directive_flags(const char *p,
943 bool *is_begin, bool *is_end, bool *is_system)
944 {
945
946 *is_begin = false;
947 *is_end = false;
948 *is_system = false;
949
950 while (*p != '\0') {
951 while (ch_isspace(*p))
952 p++;
953
954 const char *word = p;
955 while (*p != '\0' && !ch_isspace(*p))
956 p++;
957 size_t len = (size_t)(p - word);
958
959 if (len == 1 && word[0] == '1')
960 *is_begin = true;
961 if (len == 1 && word[0] == '2')
962 *is_end = true;
963 if (len == 1 && word[0] == '3')
964 *is_system = true;
965 /* Flag '4' is only interesting for C++. */
966 }
967 }
968
969 /*
970 * Called for preprocessor directives. Currently implemented are:
971 * # pragma [argument...]
972 * # lineno
973 * # lineno "filename"
974 * # lineno "filename" GCC-flag...
975 */
976 void
977 lex_directive(const char *yytext)
978 {
979 const char *cp, *fn;
980 char c, *eptr;
981 size_t fnl;
982 long ln;
983 bool is_begin, is_end, is_system;
984
985 static bool first = true;
986
987 /* Go to first non-whitespace after # */
988 for (cp = yytext + 1; (c = *cp) == ' ' || c == '\t'; cp++)
989 continue;
990
991 if (!ch_isdigit(c)) {
992 if (strncmp(cp, "pragma", 6) == 0 && ch_isspace(cp[6]))
993 return;
994 error:
995 /* undefined or invalid '#' directive */
996 warning(255);
997 return;
998 }
999 ln = strtol(--cp, &eptr, 10);
1000 if (eptr == cp)
1001 goto error;
1002 if ((c = *(cp = eptr)) != ' ' && c != '\t' && c != '\0')
1003 goto error;
1004 while ((c = *cp++) == ' ' || c == '\t')
1005 continue;
1006 if (c != '\0') {
1007 if (c != '"')
1008 goto error;
1009 fn = cp;
1010 while ((c = *cp) != '"' && c != '\0')
1011 cp++;
1012 if (c != '"')
1013 goto error;
1014 if ((fnl = cp++ - fn) > PATH_MAX)
1015 goto error;
1016 /* empty string means stdin */
1017 if (fnl == 0) {
1018 fn = "{standard input}";
1019 fnl = 16; /* strlen (fn) */
1020 }
1021 curr_pos.p_file = record_filename(fn, fnl);
1022 /*
1023 * If this is the first directive, the name is the name
1024 * of the C source file as specified at the command line.
1025 * It is written to the output file.
1026 */
1027 if (first) {
1028 csrc_pos.p_file = curr_pos.p_file;
1029 outsrc(transform_filename(curr_pos.p_file,
1030 strlen(curr_pos.p_file)));
1031 first = false;
1032 }
1033
1034 parse_line_directive_flags(cp, &is_begin, &is_end, &is_system);
1035 update_location(curr_pos.p_file, (int)ln, is_begin, is_end);
1036 in_system_header = is_system;
1037 }
1038 curr_pos.p_line = (int)ln - 1;
1039 curr_pos.p_uniq = 0;
1040 if (curr_pos.p_file == csrc_pos.p_file) {
1041 csrc_pos.p_line = (int)ln - 1;
1042 csrc_pos.p_uniq = 0;
1043 }
1044 }
1045
1046 /*
1047 * Handle lint comments such as ARGSUSED.
1048 *
1049 * If one of these comments is recognized, the argument, if any, is
1050 * parsed and a function which handles this comment is called.
1051 */
1052 void
1053 lex_comment(void)
1054 {
1055 int c;
1056 static const struct {
1057 const char *keywd;
1058 bool arg;
1059 void (*func)(int);
1060 } keywtab[] = {
1061 { "ARGSUSED", true, argsused },
1062 { "BITFIELDTYPE", false, bitfieldtype },
1063 { "CONSTCOND", false, constcond },
1064 { "CONSTANTCOND", false, constcond },
1065 { "CONSTANTCONDITION", false, constcond },
1066 { "FALLTHRU", false, fallthru },
1067 { "FALLTHROUGH", false, fallthru },
1068 { "FALL THROUGH", false, fallthru },
1069 { "fallthrough", false, fallthru },
1070 { "LINTLIBRARY", false, lintlib },
1071 { "LINTED", true, linted },
1072 { "LONGLONG", false, longlong },
1073 { "NOSTRICT", true, linted },
1074 { "NOTREACHED", false, not_reached },
1075 { "PRINTFLIKE", true, printflike },
1076 { "PROTOLIB", true, protolib },
1077 { "SCANFLIKE", true, scanflike },
1078 { "VARARGS", true, varargs },
1079 };
1080 char keywd[32];
1081 char arg[32];
1082 size_t l, i;
1083 int a;
1084
1085 bool seen_end_of_comment = false;
1086
1087 /* Skip whitespace after the start of the comment */
1088 while (c = read_byte(), isspace(c))
1089 continue;
1090
1091 /* Read the potential keyword to keywd */
1092 l = 0;
1093 while (c != EOF && l < sizeof(keywd) - 1 &&
1094 (isalpha(c) || isspace(c))) {
1095 if (islower(c) && l > 0 && ch_isupper(keywd[0]))
1096 break;
1097 keywd[l++] = (char)c;
1098 c = read_byte();
1099 }
1100 while (l > 0 && ch_isspace(keywd[l - 1]))
1101 l--;
1102 keywd[l] = '\0';
1103
1104 /* look for the keyword */
1105 for (i = 0; i < sizeof(keywtab) / sizeof(keywtab[0]); i++) {
1106 if (strcmp(keywtab[i].keywd, keywd) == 0)
1107 break;
1108 }
1109 if (i == sizeof(keywtab) / sizeof(keywtab[0]))
1110 goto skip_rest;
1111
1112 /* skip whitespace after the keyword */
1113 while (isspace(c))
1114 c = read_byte();
1115
1116 /* read the argument, if the keyword accepts one and there is one */
1117 l = 0;
1118 if (keywtab[i].arg) {
1119 while (isdigit(c) && l < sizeof(arg) - 1) {
1120 arg[l++] = (char)c;
1121 c = read_byte();
1122 }
1123 }
1124 arg[l] = '\0';
1125 a = l != 0 ? atoi(arg) : -1;
1126
1127 /* skip whitespace after the argument */
1128 while (isspace(c))
1129 c = read_byte();
1130
1131 seen_end_of_comment = c == '*' && (c = read_byte()) == '/';
1132 if (!seen_end_of_comment && keywtab[i].func != linted)
1133 /* extra characters in lint comment */
1134 warning(257);
1135
1136 if (keywtab[i].func != NULL)
1137 keywtab[i].func(a);
1138
1139 skip_rest:
1140 while (!seen_end_of_comment) {
1141 int lc = c;
1142 if ((c = read_byte()) == EOF) {
1143 /* unterminated comment */
1144 error(256);
1145 break;
1146 }
1147 if (lc == '*' && c == '/')
1148 seen_end_of_comment = true;
1149 }
1150 }
1151
1152 void
1153 lex_slash_slash_comment(void)
1154 {
1155 int c;
1156
1157 if (!allow_c99 && !allow_gcc)
1158 /* %s does not support '//' comments */
1159 gnuism(312, allow_c90 ? "C90" : "traditional C");
1160
1161 while ((c = read_byte()) != EOF && c != '\n')
1162 continue;
1163 }
1164
1165 /*
1166 * Clear flags for lint comments LINTED, LONGLONG and CONSTCOND.
1167 * clear_warn_flags is called after function definitions and global and
1168 * local declarations and definitions. It is also called between
1169 * the controlling expression and the body of control statements
1170 * (if, switch, for, while).
1171 */
1172 void
1173 clear_warn_flags(void)
1174 {
1175
1176 lwarn = LWARN_ALL;
1177 long_long_flag = false;
1178 constcond_flag = false;
1179 }
1180
1181 int
1182 lex_string(void)
1183 {
1184 unsigned char *s;
1185 int c;
1186 size_t len, max;
1187
1188 s = xmalloc(max = 64);
1189
1190 len = 0;
1191 while ((c = get_escaped_char('"')) >= 0) {
1192 /* +1 to reserve space for a trailing NUL character */
1193 if (len + 1 == max)
1194 s = xrealloc(s, max *= 2);
1195 s[len++] = (char)c;
1196 }
1197 s[len] = '\0';
1198 if (c == -2)
1199 /* unterminated string constant */
1200 error(258);
1201
1202 strg_t *strg = xcalloc(1, sizeof(*strg));
1203 strg->st_char = true;
1204 strg->st_len = len;
1205 strg->st_mem = s;
1206
1207 yylval.y_string = strg;
1208 return T_STRING;
1209 }
1210
1211 int
1212 lex_wide_string(void)
1213 {
1214 int c, n;
1215
1216 size_t len = 0, max = 64;
1217 char *s = xmalloc(max);
1218 while ((c = get_escaped_char('"')) >= 0) {
1219 /* +1 to save space for a trailing NUL character */
1220 if (len + 1 >= max)
1221 s = xrealloc(s, max *= 2);
1222 s[len++] = (char)c;
1223 }
1224 s[len] = '\0';
1225 if (c == -2)
1226 /* unterminated string constant */
1227 error(258);
1228
1229 /* get length of wide-character string */
1230 (void)mblen(NULL, 0);
1231 size_t wlen = 0;
1232 for (size_t i = 0; i < len; i += n, wlen++) {
1233 if ((n = mblen(&s[i], MB_CUR_MAX)) == -1) {
1234 /* invalid multibyte character */
1235 error(291);
1236 break;
1237 }
1238 if (n == 0)
1239 n = 1;
1240 }
1241
1242 wchar_t *ws = xmalloc((wlen + 1) * sizeof(*ws));
1243 size_t wi = 0;
1244 /* convert from multibyte to wide char */
1245 (void)mbtowc(NULL, NULL, 0);
1246 for (size_t i = 0; i < len; i += n, wi++) {
1247 if ((n = mbtowc(&ws[wi], &s[i], MB_CUR_MAX)) == -1)
1248 break;
1249 if (n == 0)
1250 n = 1;
1251 }
1252 ws[wi] = 0;
1253 free(s);
1254
1255 strg_t *strg = xcalloc(1, sizeof(*strg));
1256 strg->st_char = false;
1257 strg->st_len = wlen;
1258 strg->st_mem = ws;
1259
1260 yylval.y_string = strg;
1261 return T_STRING;
1262 }
1263
1264 void
1265 lex_next_line(void)
1266 {
1267 curr_pos.p_line++;
1268 curr_pos.p_uniq = 0;
1269 debug_step("parsing %s:%d", curr_pos.p_file, curr_pos.p_line);
1270 if (curr_pos.p_file == csrc_pos.p_file) {
1271 csrc_pos.p_line++;
1272 csrc_pos.p_uniq = 0;
1273 }
1274 }
1275
1276 void
1277 lex_unknown_character(int c)
1278 {
1279
1280 /* unknown character \%o */
1281 error(250, c);
1282 }
1283
1284 /*
1285 * The scanner does not create new symbol table entries for symbols it cannot
1286 * find in the symbol table. This is to avoid putting undeclared symbols into
1287 * the symbol table if a syntax error occurs.
1288 *
1289 * getsym is called as soon as it is probably ok to put the symbol in the
1290 * symbol table. It is still possible that symbols are put in the symbol
1291 * table that are not completely declared due to syntax errors. To avoid too
1292 * many problems in this case, symbols get type 'int' in getsym.
1293 *
1294 * XXX calls to getsym should be delayed until declare_1_* is called.
1295 */
1296 sym_t *
1297 getsym(sbuf_t *sb)
1298 {
1299
1300 sym_t *sym = sb->sb_sym;
1301
1302 /*
1303 * During member declaration it is possible that name() looked
1304 * for symbols of type FVFT, although it should have looked for
1305 * symbols of type FTAG. Same can happen for labels. Both cases
1306 * are compensated here.
1307 */
1308 if (symtyp == FMEMBER || symtyp == FLABEL) {
1309 if (sym == NULL || sym->s_kind == FVFT)
1310 sym = symtab_search(sb->sb_name);
1311 }
1312
1313 if (sym != NULL) {
1314 lint_assert(sym->s_kind == symtyp);
1315 set_symtyp(FVFT);
1316 free(sb);
1317 return sym;
1318 }
1319
1320 /* create a new symbol table entry */
1321
1322 /* labels must always be allocated at level 1 (outermost block) */
1323 decl_level *dl;
1324 if (symtyp == FLABEL) {
1325 sym = level_zero_alloc(1, sizeof(*sym));
1326 char *s = level_zero_alloc(1, sb->sb_len + 1);
1327 (void)memcpy(s, sb->sb_name, sb->sb_len + 1);
1328 sym->s_name = s;
1329 sym->s_block_level = 1;
1330 dl = dcs;
1331 while (dl->d_enclosing != NULL &&
1332 dl->d_enclosing->d_enclosing != NULL)
1333 dl = dl->d_enclosing;
1334 lint_assert(dl->d_kind == DLK_AUTO);
1335 } else {
1336 sym = block_zero_alloc(sizeof(*sym));
1337 sym->s_name = sb->sb_name;
1338 sym->s_block_level = block_level;
1339 dl = dcs;
1340 }
1341
1342 sym->s_def_pos = unique_curr_pos();
1343 if ((sym->s_kind = symtyp) != FLABEL)
1344 sym->s_type = gettyp(INT);
1345
1346 set_symtyp(FVFT);
1347
1348 if (!in_gcc_attribute) {
1349 symtab_add(sym);
1350
1351 *dl->d_last_dlsym = sym;
1352 dl->d_last_dlsym = &sym->s_level_next;
1353 }
1354
1355 free(sb);
1356 return sym;
1357 }
1358
1359 /*
1360 * Construct a temporary symbol. The symbol name starts with a digit to avoid
1361 * name clashes with other identifiers.
1362 */
1363 sym_t *
1364 mktempsym(type_t *tp)
1365 {
1366 static unsigned n = 0;
1367 char *s = level_zero_alloc((size_t)block_level, 64);
1368 sym_t *sym = block_zero_alloc(sizeof(*sym));
1369 scl_t scl;
1370
1371 (void)snprintf(s, 64, "%.8u_tmp", n++);
1372
1373 scl = dcs->d_scl;
1374 if (scl == NOSCL)
1375 scl = block_level > 0 ? AUTO : EXTERN;
1376
1377 sym->s_name = s;
1378 sym->s_type = tp;
1379 sym->s_block_level = block_level;
1380 sym->s_scl = scl;
1381 sym->s_kind = FVFT;
1382 sym->s_used = true;
1383 sym->s_set = true;
1384
1385 symtab_add(sym);
1386
1387 *dcs->d_last_dlsym = sym;
1388 dcs->d_last_dlsym = &sym->s_level_next;
1389
1390 return sym;
1391 }
1392
1393 /* Remove a symbol forever from the symbol table. */
1394 void
1395 rmsym(sym_t *sym)
1396 {
1397
1398 debug_step("rmsym '%s' %s '%s'",
1399 sym->s_name, symt_name(sym->s_kind), type_name(sym->s_type));
1400 symtab_remove(sym);
1401
1402 /* avoid that the symbol will later be put back to the symbol table */
1403 sym->s_block_level = -1;
1404 }
1405
1406 /*
1407 * Remove all symbols from the symbol table that have the same level as the
1408 * given symbol.
1409 */
1410 void
1411 symtab_remove_level(sym_t *syms)
1412 {
1413
1414 /* Note the use of s_level_next instead of s_symtab_next. */
1415 for (sym_t *sym = syms; sym != NULL; sym = sym->s_level_next) {
1416 if (sym->s_block_level != -1) {
1417 debug_step("symtab_remove_level '%s' %s '%s'",
1418 sym->s_name, symt_name(sym->s_kind),
1419 type_name(sym->s_type));
1420 symtab_remove(sym);
1421 sym->s_symtab_ref = NULL;
1422 }
1423 }
1424 }
1425
1426 /* Put a symbol into the symbol table. */
1427 void
1428 inssym(int level, sym_t *sym)
1429 {
1430
1431 debug_step("inssym '%s' %s '%s'",
1432 sym->s_name, symt_name(sym->s_kind), type_name(sym->s_type));
1433 symtab_add(sym);
1434 sym->s_block_level = level;
1435
1436 /*
1437 * Placing the inner symbols to the beginning of the list ensures
1438 * that these symbols are preferred over symbols from the outer
1439 * blocks that happen to have the same name.
1440 */
1441 const sym_t *next = sym->s_symtab_next;
1442 if (next != NULL)
1443 lint_assert(sym->s_block_level >= next->s_block_level);
1444 }
1445
1446 /* Called at level 0 after syntax errors. */
1447 void
1448 clean_up_after_error(void)
1449 {
1450
1451 symtab_remove_locals();
1452
1453 while (mem_block_level > 0)
1454 level_free_all(mem_block_level--);
1455 }
1456
1457 /* Create a new symbol with the same name as an existing symbol. */
1458 sym_t *
1459 pushdown(const sym_t *sym)
1460 {
1461 sym_t *nsym;
1462
1463 debug_step("pushdown '%s' %s '%s'",
1464 sym->s_name, symt_name(sym->s_kind), type_name(sym->s_type));
1465 nsym = block_zero_alloc(sizeof(*nsym));
1466 lint_assert(sym->s_block_level <= block_level);
1467 nsym->s_name = sym->s_name;
1468 nsym->s_def_pos = unique_curr_pos();
1469 nsym->s_kind = sym->s_kind;
1470 nsym->s_block_level = block_level;
1471
1472 symtab_add(nsym);
1473
1474 *dcs->d_last_dlsym = nsym;
1475 dcs->d_last_dlsym = &nsym->s_level_next;
1476
1477 return nsym;
1478 }
1479
1480 /*
1481 * Free any dynamically allocated memory referenced by
1482 * the value stack or yylval.
1483 * The type of information in yylval is described by tok.
1484 */
1485 void
1486 freeyyv(void *sp, int tok)
1487 {
1488 if (tok == T_NAME || tok == T_TYPENAME) {
1489 sbuf_t *sb = *(sbuf_t **)sp;
1490 free(sb);
1491 } else if (tok == T_CON) {
1492 val_t *val = *(val_t **)sp;
1493 free(val);
1494 } else if (tok == T_STRING) {
1495 strg_t *strg = *(strg_t **)sp;
1496 free(strg->st_mem);
1497 free(strg);
1498 }
1499 }
1500