| @@ -341,8 +341,8 @@ ST_FUNC void check_vstack(void) · 340 unmodified lines |
| 341 | 341 | (int)(vtop - vstack + 1)); |
| 342 | 342 | } |
| 343 | 343 | |
| 344 | | −/* vstack debugging aid */ |
| 345 | 344 | #if 0 |
| 345 | +/* dump 'b' vstack entries starting with 'a' */ |
| 346 | 346 | void pv (const char *lbl, int a, int b) |
| 347 | 347 | { |
| 348 | 348 | int i; |
| @@ -352,6 +352,27 @@ void pv (const char *lbl, int a, int b) · 3 unmodified lines |
| 352 | 352 | lbl, i, p->type.t, p->r, p->r2, (int)p->c.i); |
| 353 | 353 | } |
| 354 | 354 | } |
| 355 | + |
| 356 | +/* dump symbols on stack from s ... last */ |
| 357 | +static inline void psyms(const char *msg, Sym *s, Sym *last) |
| 358 | +{ |
| 359 | + printf("%-8s scope v c r type.t\n", msg); |
| 360 | + while (s && s != last) { |
| 361 | + printf(" %8x %08x %08x %08x %08x %s\n", |
| 362 | + s->sym_scope, s->v, s->c, s->r, s->type.t, get_tok_str(s->v, 0)); |
| 363 | + s = s->prev; |
| 364 | + } |
| 365 | +} |
| 366 | + |
| 367 | +static void type_to_str(char *buf, int buf_size, CType *type, const char *varstr); |
| 368 | + |
| 369 | +/* print type */ |
| 370 | +static void ptype(CType *type, int v) |
| 371 | +{ |
| 372 | + char buf[500]; |
| 373 | + type_to_str(buf, sizeof(buf), type, get_tok_str(v, NULL)); |
| 374 | + printf("type = '%s'\n", buf); |
| 375 | +} |
| 355 | 376 | #endif |
| 356 | 377 | |
| 357 | 378 | /* ------------------------------------------------------------------------- */ |
| @@ -506,7 +527,7 @@ ST_FUNC void put_extern_sym2(Sym *sym, int sh_num, · 148 unmodified lines |
| 506 | 527 | sym_type = STT_FUNC; |
| 507 | 528 | } else if ((t & VT_BTYPE) == VT_VOID) { |
| 508 | 529 | sym_type = STT_NOTYPE; |
| 509 | | − if ((t & (VT_BTYPE|VT_ASM_FUNC)) == VT_ASM_FUNC) |
| 530 | + if (IS_ASM_FUNC(t)) |
| 510 | 531 | sym_type = STT_FUNC; |
| 511 | 532 | } else { |
| 512 | 533 | sym_type = STT_OBJECT; |
| @@ -575,8 +596,18 @@ ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type, · 62 unmodified lines |
| 575 | 596 | return; |
| 576 | 597 | |
| 577 | 598 | if (sym) { |
| 578 | | − if (0 == sym->c) |
| 599 | + if (0 == sym->c) { |
| 579 | 600 | put_extern_sym(sym, NULL, 0, 0); |
| 601 | + if (sym->sym_scope |
| 602 | + && (sym->type.t & (VT_STATIC|VT_EXTERN)) == (VT_STATIC|VT_EXTERN)) { |
| 603 | + /* when a local function declaraion redeclares a global static one |
| 604 | + then tccelf would not resolve them to the same symbol. */ |
| 605 | + Sym *s = sym; |
| 606 | + while (s->prev_tok) |
| 607 | + s = s->prev_tok; |
| 608 | + s->c = sym->c; |
| 609 | + } |
| 610 | + } |
| 580 | 611 | c = sym->c; |
| 581 | 612 | } |
| 582 | 613 | |
| @@ -683,6 +714,13 @@ ST_INLN Sym *sym_find(int v) · 100 unmodified lines |
| 683 | 714 | return table_ident[v]->sym_identifier; |
| 684 | 715 | } |
| 685 | 716 | |
| 717 | +static int sym_scope_e(Sym *s) |
| 718 | +{ |
| 719 | + return IS_ENUM_VAL (s->type.t) |
| 720 | + ? s->type.ref->sym_scope |
| 721 | + : s->sym_scope; |
| 722 | +} |
| 723 | + |
| 686 | 724 | /* make sym in-/visible to the parser */ |
| 687 | 725 | static inline void sym_link(Sym *s, int yes) |
| 688 | 726 | { |
| @@ -692,10 +730,14 @@ static inline void sym_link(Sym *s, int yes) · 3 unmodified lines |
| 692 | 730 | ps = &ts->sym_struct; |
| 693 | 731 | else |
| 694 | 732 | ps = &ts->sym_identifier; |
| 695 | | − if (yes) |
| 733 | + if (yes) { |
| 734 | + if (*ps && sym_scope_e(*ps) == local_scope) |
| 735 | + tcc_error("redeclaration of '%s'", get_tok_str(s->v, NULL)); |
| 696 | 736 | s->prev_tok = *ps, *ps = s; |
| 697 | | − else |
| 737 | + s->sym_scope = local_scope; |
| 738 | + } else { |
| 698 | 739 | *ps = s->prev_tok; |
| 740 | + } |
| 699 | 741 | } |
| 700 | 742 | |
| 701 | 743 | /* push a given symbol on the symbol stack */ |
| @@ -710,18 +752,9 @@ ST_FUNC Sym *sym_push(int v, CType *type, int r, int c) · 8 unmodified lines |
| 710 | 752 | s->type.ref = type->ref; |
| 711 | 753 | s->r = r; |
| 712 | 754 | /* don't record fields or anonymous symbols */ |
| 713 | | − /* XXX: simplify */ |
| 714 | 755 | if ((v & ~SYM_STRUCT) < SYM_FIRST_ANOM) { |
| 715 | 756 | /* record symbol in token array */ |
| 716 | 757 | sym_link(s, 1); |
| 717 | | − s->sym_scope = local_scope; |
| 718 | | − if (s->prev_tok |
| 719 | | − && (IS_ENUM_VAL (s->prev_tok->type.t) |
| 720 | | − ? s->prev_tok->type.ref->sym_scope |
| 721 | | − : s->prev_tok->sym_scope) |
| 722 | | − == s->sym_scope) |
| 723 | | − tcc_error("redeclaration of '%s'", |
| 724 | | − get_tok_str(v & ~SYM_STRUCT, NULL)); |
| 725 | 758 | } |
| 726 | 759 | return s; |
| 727 | 760 | } |
| @@ -824,19 +857,6 @@ ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep) · 96 unmodified lines |
| 824 | 857 | *ptop = slast; |
| 825 | 858 | } |
| 826 | 859 | |
| 827 | | −#if 0 |
| 828 | | −/* debug: print symbols on stack from s ... last */ |
| 829 | | −static inline void psyms(const char *msg, Sym *s, Sym *last) |
| 830 | | −{ |
| 831 | | − printf("%-8s scope v c r type.t\n", msg); |
| 832 | | − while (s && s != last) { |
| 833 | | − printf(" %8x %08x %08x %08x %08x %s\n", |
| 834 | | − s->sym_scope, s->v, s->c, s->r, s->type.t, get_tok_str(s->v, 0)); |
| 835 | | − s = s->prev; |
| 836 | | − } |
| 837 | | −} |
| 838 | | −#endif |
| 839 | | − |
| 840 | 860 | /* ------------------------------------------------------------------------- */ |
| 841 | 861 | static void vcheck_cmp(void) |
| 842 | 862 | { |
| @@ -1294,27 +1314,47 @@ static Sym *sym_copy(Sym *s0, Sym **ps) · 451 unmodified lines |
| 1294 | 1314 | Sym *s; |
| 1295 | 1315 | s = sym_malloc(), *s = *s0; |
| 1296 | 1316 | s->prev = *ps, *ps = s; |
| 1297 | | − if ((s->v & ~SYM_STRUCT) < SYM_FIRST_ANOM && ps == &local_stack) |
| 1317 | + if ((s->v & ~SYM_STRUCT) < SYM_FIRST_ANOM) |
| 1298 | 1318 | sym_link(s, 1); |
| 1299 | 1319 | return s; |
| 1300 | 1320 | } |
| 1301 | 1321 | |
| 1302 | | −/* Symbol 's' was locally declared 'extern' (or as function), and |
| 1303 | | − is on global_stack. Now must copy its 'ref' to global_stack too */ |
| 1304 | | −static void sym_copy_ref(Sym *s, Sym **ps) |
| 1322 | +/* Symbol 's' was locally declared 'extern' (or as function), and is |
| 1323 | + on global_stack. Now must copy its 'ref' to global_stack too */ |
| 1324 | +static void move_ref_to_global(Sym *s) |
| 1305 | 1325 | { |
| 1306 | | − int bt = s->type.t & VT_BTYPE; |
| 1307 | | − if (bt == VT_PTR |
| 1308 | | − || bt == VT_FUNC |
| 1309 | | − || ((bt == VT_STRUCT || IS_ENUM(s->type.t)) |
| 1310 | | − && s->type.ref |
| 1311 | | − && s->type.ref->sym_scope)) { |
| 1312 | | − Sym **sp = &s->type.ref; |
| 1313 | | − for (s = *sp, *sp = NULL; s; s = s->next) { |
| 1314 | | − Sym *s2 = sym_copy(s, ps); |
| 1315 | | − sp = &(*sp = s2)->next; |
| 1316 | | − sym_copy_ref(s2, ps); |
| 1326 | + Sym *l, **lp; |
| 1327 | + int n, bt; |
| 1328 | + |
| 1329 | + bt = s->type.t & VT_BTYPE; |
| 1330 | + if (!(bt == VT_PTR |
| 1331 | + || bt == VT_FUNC |
| 1332 | + || bt == VT_STRUCT |
| 1333 | + || (IS_ENUM(s->type.t)) && (bt = VT_ENUM,1))) |
| 1334 | + return; |
| 1335 | + |
| 1336 | + for (s = s->type.ref, n = 0; s; s = s->next) { |
| 1337 | + for (lp = &local_stack; !!(l = *lp); lp = &l->prev) { |
| 1338 | + if (l == s) { |
| 1339 | + *lp = s->prev; |
| 1340 | + s->prev = global_stack, global_stack = s; |
| 1341 | + if (n || bt == VT_PTR) { |
| 1342 | + move_ref_to_global(s); |
| 1343 | + } else { |
| 1344 | + if ((bt == VT_STRUCT || bt == VT_ENUM) |
| 1345 | + && (s->v & ~SYM_STRUCT) < SYM_FIRST_ANOM) { |
| 1346 | + /* copy struct/enum tag to local scope */ |
| 1347 | + s->v |= SYM_FIELD; |
| 1348 | + l = sym_copy(s, lp); |
| 1349 | + l->v &= ~SYM_FIELD; |
| 1350 | + } |
| 1351 | + n = 1; |
| 1352 | + } |
| 1353 | + break; |
| 1354 | + } |
| 1317 | 1355 | } |
| 1356 | + if (n == 0) /* no next (VT_PTR) or ref not on local_stack */ |
| 1357 | + break; |
| 1318 | 1358 | } |
| 1319 | 1359 | } |
| 1320 | 1360 | |
| @@ -1335,15 +1375,15 @@ static Sym *external_sym(int v, CType *type, int r, AttributeDef *ad) · 14 unmodified lines |
| 1335 | 1375 | s->a = ad->a; |
| 1336 | 1376 | s->asm_label = ad->asm_label; |
| 1337 | 1377 | s->type.ref = type->ref; |
| 1338 | | − /* copy type to the global stack */ |
| 1339 | | − if (local_stack) |
| 1340 | | − sym_copy_ref(s, &global_stack); |
| 1341 | 1378 | } else { |
| 1342 | 1379 | patch_storage(s, ad, type); |
| 1343 | 1380 | } |
| 1344 | | − /* push variables on local_stack if any */ |
| 1345 | | − if (local_stack && (s->type.t & VT_BTYPE) != VT_FUNC) |
| 1381 | + if (local_stack) { |
| 1382 | + /* make sure that type->ref is on global stack */ |
| 1383 | + move_ref_to_global(s); |
| 1384 | + /* put into local scope */ |
| 1346 | 1385 | s = sym_copy(s, &local_stack); |
| 1386 | + } |
| 1347 | 1387 | return s; |
| 1348 | 1388 | } |
| 1349 | 1389 | |
| @@ -3457,8 +3497,8 @@ ST_FUNC int type_size(CType *type, int *a) · 2107 unmodified lines |
| 3457 | 3497 | int ts; |
| 3458 | 3498 | s = type->ref; |
| 3459 | 3499 | ts = type_size(&s->type, a); |
| 3460 | | − if (ts < 0 && s->c < 0) |
| 3461 | | − ts = -ts; |
| 3500 | + if (s->c < 0) |
| 3501 | + return s->c; |
| 3462 | 3502 | return ts * s->c; |
| 3463 | 3503 | } else { |
| 3464 | 3504 | *a = PTR_SIZE; |
| @@ -4367,6 +4407,15 @@ static void struct_layout(CType *type, AttributeDef *ad) · 902 unmodified lines |
| 4367 | 4407 | } |
| 4368 | 4408 | } |
| 4369 | 4409 | |
| 4410 | +/* Does 'n' fit into integer type 't' ? */ |
| 4411 | +static int in_range(long long n, int t) |
| 4412 | +{ |
| 4413 | + unsigned long long m = (1ULL << (btype_size(t & VT_BTYPE) * 8 - 1)) - 1; |
| 4414 | + if (t & VT_UNSIGNED) |
| 4415 | + return n <= (m << 1) + 1; |
| 4416 | + return n >= -(long long)m - 1 && n <= (long long)m; |
| 4417 | +} |
| 4418 | + |
| 4370 | 4419 | /* enum/struct/union declaration. u is VT_ENUM/VT_STRUCT/VT_UNION */ |
| 4371 | 4420 | static void struct_decl(CType *type, int u) |
| 4372 | 4421 | { |
| @@ -4431,36 +4480,26 @@ do_decl: · 58 unmodified lines |
| 4431 | 4480 | /* non empty enums are not allowed */ |
| 4432 | 4481 | ps = &s->next; |
| 4433 | 4482 | if (u == VT_ENUM) { |
| 4434 | | − long long ll = 0, pl = 0, nl = 0, ni = 0, pi = 0; |
| 4435 | | − unsigned long long mu = 0; |
| 4483 | + long long ll = 0, pl = 0, nl = 0; |
| 4436 | 4484 | CType t; |
| 4437 | 4485 | t.ref = s; |
| 4486 | + s->sym_scope = local_scope; /* anonymous symbol won't have set */ |
| 4438 | 4487 | /* enum symbols have static storage */ |
| 4439 | 4488 | t.t = VT_INT|VT_STATIC|VT_ENUM_VAL; |
| 4440 | | − if (bt) { |
| 4489 | + if (bt) |
| 4441 | 4490 | t.t = bt|VT_STATIC|VT_ENUM_VAL; |
| 4442 | | − mu = 1llu << (type_size(&t, &align) * 8 - 1); |
| 4443 | | − pi = mu - 1; |
| 4444 | | − ni = -mu; |
| 4445 | | − mu = (mu << 1) - 1u; |
| 4446 | | − } |
| 4447 | 4491 | for(;;) { |
| 4448 | 4492 | v = tok; |
| 4449 | 4493 | if (v < TOK_UIDENT) |
| 4450 | 4494 | expect("identifier"); |
| 4451 | | − ss = sym_find(v); |
| 4452 | | − if (ss && !local_stack) |
| 4453 | | − tcc_error("redefinition of enumerator '%s'", |
| 4454 | | − get_tok_str(v, NULL)); |
| 4455 | 4495 | next(); |
| 4456 | 4496 | if (tok == '=') { |
| 4457 | 4497 | next(); |
| 4458 | 4498 | ll = expr_const64(); |
| 4459 | 4499 | } |
| 4460 | | − if (bt && (t.t & VT_UNSIGNED ? (unsigned long long)ll > mu |
| 4461 | | − : ll < ni || ll > pi)) |
| 4462 | | − tcc_error("enumerator value outside the range of underlying type '%s'", |
| 4463 | | − get_tok_str(v, NULL)); |
| 4500 | + if (bt && !in_range(ll, t.t)) |
| 4501 | + tcc_error("enumerator '%s' out of range of its type", |
| 4502 | + get_tok_str(v, NULL)); |
| 4464 | 4503 | ss = sym_push(v, &t, VT_CONST, 0); |
| 4465 | 4504 | ss->enum_val = ll; |
| 4466 | 4505 | *ps = ss, ps = &ss->next; |
| @@ -4626,9 +4665,9 @@ do_decl: · 159 unmodified lines |
| 4626 | 4665 | check_fields(type, 1); |
| 4627 | 4666 | check_fields(type, 0); |
| 4628 | 4667 | struct_layout(type, &ad); |
| 4629 | | − if (debug_modes) |
| 4630 | | − tcc_debug_fix_forw(tcc_state, type); |
| 4631 | 4668 | } |
| 4669 | + if (debug_modes) |
| 4670 | + tcc_debug_fix_forw(tcc_state, type); |
| 4632 | 4671 | } |
| 4633 | 4672 | } |
| 4634 | 4673 | |
| @@ -4860,8 +4899,11 @@ static int parse_btype(CType *type, AttributeDef *ad, int ignore_label) · 225 unmodified lines |
| 4860 | 4899 | parse_expr_type(&type1); |
| 4861 | 4900 | /* remove all storage modifiers except typedef */ |
| 4862 | 4901 | type1.t &= ~(VT_STORAGE&~VT_TYPEDEF); |
| 4863 | | − if (type1.ref) |
| 4902 | + if (type1.ref) { |
| 4864 | 4903 | sym_to_attr(ad, type1.ref); |
| 4904 | + if (type1.t & VT_ARRAY) |
| 4905 | + type1.t |= VT_BT_ARRAY; |
| 4906 | + } |
| 4865 | 4907 | goto basic_type2; |
| 4866 | 4908 | case TOK_THREAD_LOCAL: |
| 4867 | 4909 | tcc_error("_Thread_local is not implemented"); |
| @@ -4886,12 +4928,12 @@ static int parse_btype(CType *type, AttributeDef *ad, int ignore_label) · 18 unmodified lines |
| 4886 | 4928 | if (t) |
| 4887 | 4929 | parse_btype_qualify(type, t); |
| 4888 | 4930 | t = type->t; |
| 4931 | + if (t & VT_ARRAY) |
| 4932 | + t |= VT_BT_ARRAY; |
| 4889 | 4933 | /* get attributes from typedef */ |
| 4890 | 4934 | sym_to_attr(ad, s); |
| 4891 | 4935 | typespec_found = 1; |
| 4892 | 4936 | st = bt = -2; |
| 4893 | | − if (type->ref && (t & VT_ARRAY) && type->ref->c < 0) |
| 4894 | | − type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c); |
| 4895 | 4937 | break; |
| 4896 | 4938 | } |
| 4897 | 4939 | type_found = 1; |
| @@ -4994,15 +5036,15 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td) · 96 unmodified lines |
| 4994 | 5036 | type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT | TYPE_PARAM); |
| 4995 | 5037 | if ((pt.t & VT_BTYPE) == VT_VOID) |
| 4996 | 5038 | tcc_error("parameter declared as void"); |
| 4997 | | − if (local_scope > 1 || n == 0) |
| 4998 | | − n = SYM_FIELD; |
| 5039 | + if (n == 0 || (td & TYPE_PARAM)) |
| 5040 | + n |= SYM_FIELD; |
| 4999 | 5041 | } else { |
| 5000 | 5042 | n = tok; |
| 5001 | 5043 | pt.t = VT_INT | VT_EXTERN; /* default type */ |
| 5002 | 5044 | pt.ref = NULL; |
| 5003 | 5045 | next(); |
| 5004 | 5046 | } |
| 5005 | | − if (local_scope == 1 && n < TOK_UIDENT) |
| 5047 | + if (n < TOK_UIDENT) |
| 5006 | 5048 | expect("identifier"); |
| 5007 | 5049 | convert_parameter_type(&pt); |
| 5008 | 5050 | arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE; |
| @@ -5026,7 +5068,6 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td) · 17 unmodified lines |
| 5026 | 5068 | /* if no parameters, then old type prototype */ |
| 5027 | 5069 | l = FUNC_OLD; |
| 5028 | 5070 | skip(')'); |
| 5029 | | − --local_scope; |
| 5030 | 5071 | /* NOTE: const is ignored in returned type as it has a special |
| 5031 | 5072 | meaning in gcc / C++ */ |
| 5032 | 5073 | type->t &= ~VT_CONSTANT; |
| @@ -5046,10 +5087,9 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td) · 13 unmodified lines |
| 5046 | 5087 | s->next = first; |
| 5047 | 5088 | type->t = VT_FUNC; |
| 5048 | 5089 | type->ref = s; |
| 5049 | | − |
| 5050 | | − /* unlink symbols from the token table, keep on stack */ |
| 5090 | + /* unlink parameter symbols from the token table, keep on stack */ |
| 5051 | 5091 | sym_pop(ps, sr, 1); |
| 5052 | | − //psyms("---", *ps, sr); |
| 5092 | + --local_scope; |
| 5053 | 5093 | |
| 5054 | 5094 | } else if (tok == '[') { |
| 5055 | 5095 | int saved_nocode_wanted = nocode_wanted; |
| @@ -6901,7 +6941,7 @@ static void try_call_scope_cleanup(Sym *stop) · 1845 unmodified lines |
| 6901 | 6941 | Sym *cls = cur_scope->cl.s; |
| 6902 | 6942 | for (; cls != stop; cls = cls->next) { |
| 6903 | 6943 | Sym *fs = cls->cleanup_func; |
| 6904 | | − Sym *vs = cls->prev_tok; |
| 6944 | + Sym *vs = cls->cleanup_sym; |
| 6905 | 6945 | save_lvalues(); |
| 6906 | 6946 | vpushsym(&fs->type, fs); |
| 6907 | 6947 | vset(&vs->type, vs->r, vs->c); |
| @@ -6912,6 +6952,7 @@ static void try_call_scope_cleanup(Sym *stop) · 4 unmodified lines |
| 6912 | 6952 | } |
| 6913 | 6953 | } |
| 6914 | 6954 | |
| 6955 | + |
| 6915 | 6956 | static void try_call_cleanup_goto(Sym *cleanupstate) |
| 6916 | 6957 | { |
| 6917 | 6958 | Sym *oc, *cc; |
| @@ -6938,7 +6979,7 @@ static void block_cleanup(struct scope *o) · 20 unmodified lines |
| 6938 | 6979 | int jmp = 0; |
| 6939 | 6980 | Sym *g, **pg; |
| 6940 | 6981 | for (pg = &pending_gotos; (g = *pg) && g->c > o->cl.n;) { |
| 6941 | | − if (g->prev_tok->r & LABEL_FORWARD) { |
| 6982 | + if (g->cleanup_label->r & LABEL_FORWARD) { |
| 6942 | 6983 | Sym *pcl = g->next; |
| 6943 | 6984 | if (!jmp) |
| 6944 | 6985 | jmp = gjmp(0); |
| @@ -7360,7 +7401,7 @@ again: · 415 unmodified lines |
| 7360 | 7401 | /* start new goto chain for cleanups, linked via label->next */ |
| 7361 | 7402 | if (cur_scope->cl.s && !nocode_wanted) { |
| 7362 | 7403 | sym_push2(&pending_gotos, SYM_FIELD, 0, cur_scope->cl.n); |
| 7363 | | − pending_gotos->prev_tok = s; |
| 7404 | + pending_gotos->cleanup_label = s; |
| 7364 | 7405 | s = sym_push2(&s->next, SYM_FIELD, 0, 0); |
| 7365 | 7406 | pending_gotos->next = s; |
| 7366 | 7407 | } |
| @@ -7570,7 +7611,7 @@ static void decl_design_flex(init_params *p, Sym *ref, int index) · 203 unmodified lines |
| 7570 | 7611 | if (ref == p->flex_array_ref) { |
| 7571 | 7612 | if (index >= ref->c) |
| 7572 | 7613 | ref->c = index + 1; |
| 7573 | | − } else if (ref->c < 0) |
| 7614 | + } else if (ref->c < 0 && index >= 0) |
| 7574 | 7615 | tcc_error("flexible array has zero size in this context"); |
| 7575 | 7616 | } |
| 7576 | 7617 | |
| @@ -8029,7 +8070,7 @@ static void decl_initializer(init_params *p, CType *type, unsigned long c, int f · 452 unmodified lines |
| 8029 | 8070 | /* GNU extension: if the initializer is empty for a flex array, |
| 8030 | 8071 | it's size is zero. We won't enter the loop, so set the size |
| 8031 | 8072 | now. */ |
| 8032 | | − decl_design_flex(p, s, len); |
| 8073 | + decl_design_flex(p, s, len - 1); |
| 8033 | 8074 | while (tok != '}' || (flags & DIF_HAVE_ELEM)) { |
| 8034 | 8075 | len = decl_designator(p, type, c, &f, flags, len); |
| 8035 | 8076 | flags &= ~DIF_HAVE_ELEM; |
| @@ -8165,6 +8206,13 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 129 unmodified lines |
| 8165 | 8206 | // (arrays of incomplete types are handled in array parsing) |
| 8166 | 8207 | if (!(type->t & VT_ARRAY)) |
| 8167 | 8208 | tcc_error("initialization of incomplete type"); |
| 8209 | + /* If the base type itself was an array type of unspecified |
| 8210 | + size (like in 'typedef int arr[]; arr x = {1};') then |
| 8211 | + we will overwrite the unknown size by the real one for |
| 8212 | + this decl. We need to unshare the ref symbol holding |
| 8213 | + that size. */ |
| 8214 | + if (type->t & VT_BT_ARRAY) |
| 8215 | + type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c); |
| 8168 | 8216 | p.flex_array_ref = type->ref; |
| 8169 | 8217 | |
| 8170 | 8218 | } else if (has_init && (type->t & VT_BTYPE) == VT_STRUCT) { |
| @@ -8182,8 +8230,8 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 11 unmodified lines |
| 8182 | 8230 | |
| 8183 | 8231 | if (size < 0) { |
| 8184 | 8232 | /* If unknown size, do a dry-run 1st pass */ |
| 8185 | | − if (!has_init) |
| 8186 | | − tcc_error("unknown type size"); |
| 8233 | + if (!has_init) |
| 8234 | + goto err_size; |
| 8187 | 8235 | if (has_init == 2) { |
| 8188 | 8236 | /* only get strings */ |
| 8189 | 8237 | init_str = tok_str_alloc(); |
| @@ -8206,7 +8254,8 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 16 unmodified lines |
| 8206 | 8254 | |
| 8207 | 8255 | /* if still unknown size, error */ |
| 8208 | 8256 | size = type_size(type, &align); |
| 8209 | | − if (size < 0) |
| 8257 | + if (size < 0) |
| 8258 | + err_size: |
| 8210 | 8259 | tcc_error("unknown type size"); |
| 8211 | 8260 | |
| 8212 | 8261 | /* If there's a flex member and it was used in the initializer |
| @@ -8258,7 +8307,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 45 unmodified lines |
| 8258 | 8307 | if (ad->cleanup_func) { |
| 8259 | 8308 | Sym *cls = sym_push2(&all_cleanups, |
| 8260 | 8309 | SYM_FIELD | ++cur_scope->cl.n, 0, 0); |
| 8261 | | − cls->prev_tok = sym; |
| 8310 | + cls->cleanup_sym = sym; |
| 8262 | 8311 | cls->cleanup_func = ad->cleanup_func; |
| 8263 | 8312 | cls->next = cur_scope->cl.s; |
| 8264 | 8313 | cur_scope->cl.s = cls; |
| @@ -8423,19 +8472,21 @@ ST_FUNC Sym *gfunc_set_param(Sym *s, int c, int byref) · 158 unmodified lines |
| 8423 | 8472 | return NULL; |
| 8424 | 8473 | s->c = c; |
| 8425 | 8474 | if (byref) |
| 8426 | | − s->r = VT_LLOCAL | VT_LVAL; |
| 8475 | + s->r = VT_LLOCAL | VT_LVAL; /* otherwise VT_LOCAL */ |
| 8427 | 8476 | return s; |
| 8428 | 8477 | } |
| 8429 | 8478 | |
| 8430 | 8479 | /* push parameters (and their types), last first */ |
| 8431 | 8480 | static void sym_push_params(Sym *ref) |
| 8432 | 8481 | { |
| 8433 | | − Sym *s; |
| 8434 | | − for (s = ref; s->next; s = s->next) |
| 8435 | | − ; |
| 8436 | | − for (; s && s != ref; s = s->prev) |
| 8482 | + Sym *s = ref; |
| 8483 | + while (s->next) |
| 8484 | + s = s->next; |
| 8485 | + while (s != ref) { |
| 8437 | 8486 | if ((s->v & ~SYM_STRUCT) < SYM_FIRST_ANOM) |
| 8438 | 8487 | sym_copy(s, &local_stack); |
| 8488 | + s = s->prev; |
| 8489 | + } |
| 8439 | 8490 | } |
| 8440 | 8491 | |
| 8441 | 8492 | /* parse a function defined by symbol 'sym' and generate its code in |
| @@ -8473,8 +8524,8 @@ static void gen_function(Sym *sym) · 31 unmodified lines |
| 8473 | 8524 | /* push a dummy symbol to enable local sym storage */ |
| 8474 | 8525 | sym_push2(&local_stack, SYM_FIELD, 0, 0); |
| 8475 | 8526 | /* push parameters */ |
| 8527 | + local_scope = 1; |
| 8476 | 8528 | sym_push_params(sym->type.ref); |
| 8477 | | − //psyms(funcname, local_stack, 0); |
| 8478 | 8529 | |
| 8479 | 8530 | local_scope = 0; |
| 8480 | 8531 | rsym = 0; |
| @@ -8608,7 +8659,7 @@ static int decl(int l) · 127 unmodified lines |
| 8608 | 8659 | { |
| 8609 | 8660 | int v, has_init, r, oldint; |
| 8610 | 8661 | CType type, btype; |
| 8611 | | − Sym *sym; |
| 8662 | + Sym *sym, *sa; |
| 8612 | 8663 | AttributeDef ad, adbase; |
| 8613 | 8664 | ElfSym *esym; |
| 8614 | 8665 | |
| @@ -8663,22 +8714,8 @@ static int decl(int l) · 48 unmodified lines |
| 8663 | 8714 | while (1) { /* iterate thru each declaration */ |
| 8664 | 8715 | type = btype; |
| 8665 | 8716 | ad = adbase; |
| 8666 | | − if ((btype.t & VT_ARRAY) && btype.ref->c < 0) { |
| 8667 | | − /* If the base type itself was an array type of unspecified |
| 8668 | | − size (like in 'typedef int arr[]; arr x = {1};') then |
| 8669 | | − we will overwrite the unknown size by the real one for |
| 8670 | | − this decl. We need to unshare the ref symbol holding |
| 8671 | | − that size. */ |
| 8672 | | − type.ref = sym_push(SYM_FIELD, &type.ref->type, 0, type.ref->c); |
| 8673 | | − } |
| 8674 | 8717 | type_decl(&type, &ad, &v, TYPE_DIRECT); |
| 8675 | | −#if 0 |
| 8676 | | − { |
| 8677 | | − char buf[500]; |
| 8678 | | − type_to_str(buf, sizeof(buf), &type, get_tok_str(v, NULL)); |
| 8679 | | − printf("type = '%s'\n", buf); |
| 8680 | | − } |
| 8681 | | −#endif |
| 8718 | + |
| 8682 | 8719 | if ((type.t & VT_BTYPE) == VT_FUNC) { |
| 8683 | 8720 | if ((type.t & VT_STATIC) && (l != VT_CONST)) |
| 8684 | 8721 | tcc_error("function without file scope cannot be static"); |
| @@ -8722,8 +8759,6 @@ static int decl(int l) · 37 unmodified lines |
| 8722 | 8759 | pe_check_linkage(&type, &ad); |
| 8723 | 8760 | #endif |
| 8724 | 8761 | if (tok == '{') { |
| 8725 | | − Sym *sa; |
| 8726 | | − |
| 8727 | 8762 | if (l != VT_CONST) |
| 8728 | 8763 | tcc_error("cannot use local functions"); |
| 8729 | 8764 | if ((type.t & VT_BTYPE) != VT_FUNC) |