... see tests
Unified · Split
| @@ -194,17 +194,18 @@ ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 193 unmodified lines | |||
| 194 | case R_ARM_PLT32: | 194 | case R_ARM_PLT32: |
| 195 | { | 195 | { |
| 196 | int x, is_thumb, is_call, h, blx_avail, is_bl, th_ko; | 196 | int x, is_thumb, is_call, h, blx_avail, is_bl, th_ko; |
| 197 | x = read32le(ptr) & 0xffffff; | 197 | unsigned code = read32le(ptr); |
| 198 | x = code & 0x00ffffff; | ||
| 198 | #ifdef DEBUG_RELOC | 199 | #ifdef DEBUG_RELOC |
| 199 | printf ("reloc %d: x=0x%x val=0x%x ", type, x, val); | 200 | printf ("reloc %d: x=0x%x val=0x%x ", type, x, val); |
| 200 | #endif | 201 | #endif |
| 201 | write32le(ptr, read32le(ptr) & 0xff000000); | 202 | code &= 0xff000000; |
| 202 | if (x & 0x800000) | 203 | x <<= 2; |
| 203 | x -= 0x1000000; | 204 | if (x & 0x2000000) |
| 204 | x = (unsigned) x << 2; | 205 | x -= 0x4000000; |
| 205 | blx_avail = (CONFIG_TCC_CPUVER >= 5); | 206 | blx_avail = (CONFIG_TCC_CPUVER >= 5); |
| 206 | is_thumb = val & 1; | 207 | is_thumb = val & 1; |
| 207 | is_bl = read32le(ptr) >> 24 == 0xeb; | 208 | is_bl = code == 0xeb000000; |
| 208 | is_call = (type == R_ARM_CALL || (type == R_ARM_PC24 && is_bl)); | 209 | is_call = (type == R_ARM_CALL || (type == R_ARM_PC24 && is_bl)); |
| 209 | x += val - addr; | 210 | x += val - addr; |
| 210 | #ifdef DEBUG_RELOC | 211 | #ifdef DEBUG_RELOC |
| @@ -220,9 +221,9 @@ ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 9 unmodified lines | |||
| 220 | /* Only reached if blx is avail and it is a call */ | 221 | /* Only reached if blx is avail and it is a call */ |
| 221 | if (is_thumb) { | 222 | if (is_thumb) { |
| 222 | x |= h << 24; | 223 | x |= h << 24; |
| 223 | write32le(ptr, 0xfa << 24); /* bl -> blx */ | 224 | code = 0xfa000000; /* bl -> blx */ |
| 224 | } | 225 | } |
| 225 | write32le(ptr, read32le(ptr) | x); | 226 | write32le(ptr, code | x); |
| 226 | } | 227 | } |
| 227 | return; | 228 | return; |
| 228 | /* Since these relocations only concern Thumb-2 and blx instruction was | 229 | /* Since these relocations only concern Thumb-2 and blx instruction was |
| @@ -326,7 +326,7 @@ struct mem_debug_header { · 325 unmodified lines | |||
| 326 | struct mem_debug_header *prev; | 326 | struct mem_debug_header *prev; |
| 327 | struct mem_debug_header *next; | 327 | struct mem_debug_header *next; |
| 328 | int line_num; | 328 | int line_num; |
| 329 | char file_name[MEM_DEBUG_FILE_LEN + 1]; | 329 | char file_name[MEM_DEBUG_FILE_LEN]; |
| 330 | unsigned magic2; | 330 | unsigned magic2; |
| 331 | ALIGNED(16) unsigned char magic3[4]; | 331 | ALIGNED(16) unsigned char magic3[4]; |
| 332 | }; | 332 | }; |
| @@ -367,9 +367,8 @@ PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line) · 34 unmodified lines | |||
| 367 | header->size = size; | 367 | header->size = size; |
| 368 | write32le(MEM_DEBUG_CHECK3(header), MEM_DEBUG_MAGIC3); | 368 | write32le(MEM_DEBUG_CHECK3(header), MEM_DEBUG_MAGIC3); |
| 369 | header->line_num = line; | 369 | header->line_num = line; |
| 370 | ofs = strlen(file) - MEM_DEBUG_FILE_LEN; | 370 | ofs = strlen(file) + 1 - MEM_DEBUG_FILE_LEN; |
| 371 | strncpy(header->file_name, file + (ofs > 0 ? ofs : 0), MEM_DEBUG_FILE_LEN); | 371 | strcpy(header->file_name, file + (ofs > 0 ? ofs : 0)); |
| 372 | header->file_name[MEM_DEBUG_FILE_LEN] = 0; | ||
| 373 | WAIT_SEM(&mem_sem); | 372 | WAIT_SEM(&mem_sem); |
| 374 | header->next = mem_debug_chain; | 373 | header->next = mem_debug_chain; |
| 375 | header->prev = NULL; | 374 | header->prev = NULL; |
| @@ -323,13 +323,12 @@ redo: · 322 unmodified lines | |||
| 323 | tcc_set_output_type(s, TCC_OUTPUT_MEMORY); | 323 | tcc_set_output_type(s, TCC_OUTPUT_MEMORY); |
| 324 | print_search_dirs(s); | 324 | print_search_dirs(s); |
| 325 | } | 325 | } |
| 326 | if (opt < 0) err: | ||
| 327 | ret = 1, opt = -1; | ||
| 328 | if (opt) { | 326 | if (opt) { |
| 327 | if (opt < 0) err: | ||
| 328 | ret = 1; | ||
| 329 | tcc_delete(s); | 329 | tcc_delete(s); |
| 330 | return ret; | 330 | return ret; |
| 331 | } | 331 | } |
| 332 | |||
| 333 | if (s->nb_files == 0) { | 332 | if (s->nb_files == 0) { |
| 334 | tcc_error_noabort("no input files"); | 333 | tcc_error_noabort("no input files"); |
| 335 | } else if (s->output_type == TCC_OUTPUT_PREPROCESS) { | 334 | } else if (s->output_type == TCC_OUTPUT_PREPROCESS) { |
| @@ -95,13 +95,13 @@ extern long double strtold (const char *__nptr, char **__endptr); · 94 unmodified lines | |||
| 95 | # define O_BINARY 0 | 95 | # define O_BINARY 0 |
| 96 | #endif | 96 | #endif |
| 97 | 97 | ||
| 98 | #ifndef offsetof | ||
| 98 | #ifdef __clang__ // clang -fsanitize compains about: NULL+value | 99 | #ifdef __clang__ // clang -fsanitize compains about: NULL+value |
| 99 | #define offsetof(type, field) __builtin_offsetof(type, field) | 100 | #define offsetof(type, field) __builtin_offsetof(type, field) |
| 100 | #endif | 101 | #else |
| 101 | |||
| 102 | #ifndef offsetof | ||
| 103 | #define offsetof(type, field) ((size_t) &((type *)0)->field) | 102 | #define offsetof(type, field) ((size_t) &((type *)0)->field) |
| 104 | #endif | 103 | #endif |
| 104 | #endif | ||
| 105 | 105 | ||
| 106 | #ifndef countof | 106 | #ifndef countof |
| 107 | #define countof(tab) (sizeof(tab) / sizeof((tab)[0])) | 107 | #define countof(tab) (sizeof(tab) / sizeof((tab)[0])) |
| @@ -1074,7 +1074,7 @@ struct filespec { · 966 unmodified lines | |||
| 1074 | 1074 | ||
| 1075 | #define VT_UNION (1 << VT_STRUCT_SHIFT | VT_STRUCT) | 1075 | #define VT_UNION (1 << VT_STRUCT_SHIFT | VT_STRUCT) |
| 1076 | #define VT_ENUM (2 << VT_STRUCT_SHIFT) /* integral type is an enum really */ | 1076 | #define VT_ENUM (2 << VT_STRUCT_SHIFT) /* integral type is an enum really */ |
| 1077 | #define VT_ENUM_VAL (3 << VT_STRUCT_SHIFT) /* integral type is an enum constant really */ | 1077 | #define VT_ENUM_VAL (4 << VT_STRUCT_SHIFT) /* integral type is an enum constant really */ |
| 1078 | 1078 | ||
| 1079 | #define IS_ENUM(t) ((t & VT_STRUCT_MASK) == VT_ENUM) | 1079 | #define IS_ENUM(t) ((t & VT_STRUCT_MASK) == VT_ENUM) |
| 1080 | #define IS_ENUM_VAL(t) ((t & VT_STRUCT_MASK) == VT_ENUM_VAL) | 1080 | #define IS_ENUM_VAL(t) ((t & VT_STRUCT_MASK) == VT_ENUM_VAL) |
| @@ -1675,16 +1675,20 @@ static void tcc_debug_check_forw(TCCState *s1, Sym *t, int debug_type) · 1674 unmodified lines | |||
| 1675 | } | 1675 | } |
| 1676 | } | 1676 | } |
| 1677 | 1677 | ||
| 1678 | static void stabs_struct_complete(TCCState *s1, CType *t); | ||
| 1679 | |||
| 1678 | ST_FUNC void tcc_debug_fix_forw(TCCState *s1, CType *t) | 1680 | ST_FUNC void tcc_debug_fix_forw(TCCState *s1, CType *t) |
| 1679 | { | 1681 | { |
| 1680 | if (!(s1->do_debug & 2)) | 1682 | if (!(s1->do_debug & 2)) |
| 1681 | return; | 1683 | return; |
| 1682 | 1684 | if (0 == s1->dwarf) { | |
| 1685 | stabs_struct_complete(s1, t); | ||
| 1686 | return; | ||
| 1687 | } | ||
| 1683 | if ((t->t & VT_BTYPE) == VT_STRUCT && t->ref->c != -1) { | 1688 | if ((t->t & VT_BTYPE) == VT_STRUCT && t->ref->c != -1) { |
| 1684 | int i, j, debug_type, g = check_global(t->ref); | 1689 | int i, j, debug_type, g = check_global(t->ref); |
| 1685 | int *n_forw_hash; | 1690 | int *n_forw_hash; |
| 1686 | struct _debug_forw_hash **forw_hash; | 1691 | struct _debug_forw_hash **forw_hash; |
| 1687 | |||
| 1688 | forw_hash = g ? &debug_forw_hash_global : &debug_forw_hash_local; | 1692 | forw_hash = g ? &debug_forw_hash_global : &debug_forw_hash_local; |
| 1689 | n_forw_hash = g ? &n_debug_forw_hash_global : &n_debug_forw_hash_local; | 1693 | n_forw_hash = g ? &n_debug_forw_hash_global : &n_debug_forw_hash_local; |
| 1690 | for (i = 0; i < *n_forw_hash; i++) | 1694 | for (i = 0; i < *n_forw_hash; i++) |
| @@ -1722,14 +1726,46 @@ static int tcc_debug_add(TCCState *s1, Sym *t, int dwarf) · 31 unmodified lines | |||
| 1722 | return offset; | 1726 | return offset; |
| 1723 | } | 1727 | } |
| 1724 | 1728 | ||
| 1725 | #define STRUCT_NODEBUG(s) \ | 1729 | static int STRUCT_NODEBUG(Sym *s) |
| 1726 | (s->a.nodebug || \ | 1730 | { |
| 1727 | ((s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM && \ | 1731 | return |
| 1728 | ((s->type.t & VT_BTYPE) == VT_BYTE || \ | 1732 | (s->a.nodebug || |
| 1729 | (s->type.t & VT_BTYPE) == VT_BOOL || \ | 1733 | ((s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM && |
| 1730 | (s->type.t & VT_BTYPE) == VT_SHORT || \ | 1734 | ((s->type.t & VT_BTYPE) == VT_BYTE || |
| 1731 | (s->type.t & VT_BTYPE) == VT_INT || \ | 1735 | (s->type.t & VT_BTYPE) == VT_BOOL || |
| 1732 | (s->type.t & VT_BTYPE) == VT_LLONG))) | 1736 | (s->type.t & VT_BTYPE) == VT_SHORT || |
| 1737 | (s->type.t & VT_BTYPE) == VT_INT || | ||
| 1738 | (s->type.t & VT_BTYPE) == VT_LLONG))); | ||
| 1739 | } | ||
| 1740 | |||
| 1741 | static int stabs_struct_find(TCCState *s1, Sym *t, int *p_id) | ||
| 1742 | { | ||
| 1743 | /* A struct/enum has a ref to its type but that type has no ref. | ||
| 1744 | So we can (ab)use it for some info. Here: | ||
| 1745 | s->c : stabs type id | ||
| 1746 | s->r : already defined in stabs */ | ||
| 1747 | Sym *s = t->type.ref; | ||
| 1748 | /* | ||
| 1749 | if (s && s->v != (SYM_FIELD|0x00DEBBED)) { | ||
| 1750 | tcc_error_noabort("tccdbg: internal error: %s", get_tok_str(t->v, 0)); | ||
| 1751 | if (p_id) | ||
| 1752 | *p_id = 0; | ||
| 1753 | return 0; | ||
| 1754 | } | ||
| 1755 | */ | ||
| 1756 | if (NULL == p_id) | ||
| 1757 | return s && !s->r && t->c >= 0; | ||
| 1758 | if (NULL == s) { | ||
| 1759 | /* just use global_stack always */ | ||
| 1760 | s = sym_push2(&global_stack, SYM_FIELD|0x00DEBBED, 0, ++debug_next_type); | ||
| 1761 | t->type.ref = s; | ||
| 1762 | } | ||
| 1763 | *p_id = s->c; | ||
| 1764 | if (s->r || t->c < 0) /* already defined or still incomplete */ | ||
| 1765 | return 0; | ||
| 1766 | s->r = 1; | ||
| 1767 | return 1; | ||
| 1768 | } | ||
| 1733 | 1769 | ||
| 1734 | static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result) | 1770 | static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result) |
| 1735 | { | 1771 | { |
| @@ -1750,9 +1786,7 @@ static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result) · 14 unmodified lines | |||
| 1750 | } | 1786 | } |
| 1751 | if ((type & VT_BTYPE) == VT_STRUCT) { | 1787 | if ((type & VT_BTYPE) == VT_STRUCT) { |
| 1752 | t = t->type.ref; | 1788 | t = t->type.ref; |
| 1753 | debug_type = tcc_debug_find(s1, t, 0); | 1789 | if (stabs_struct_find(s1, t, &debug_type)) { |
| 1754 | if (debug_type == -1) { | ||
| 1755 | debug_type = tcc_debug_add(s1, t, 0); | ||
| 1756 | cstr_new (&str); | 1790 | cstr_new (&str); |
| 1757 | cstr_printf (&str, "%s:T%d=%c%d", | 1791 | cstr_printf (&str, "%s:T%d=%c%d", |
| 1758 | (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM | 1792 | (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM |
| @@ -1760,15 +1794,16 @@ static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result) · 1 unmodified line | |||
| 1760 | debug_type, | 1794 | debug_type, |
| 1761 | IS_UNION (t->type.t) ? 'u' : 's', | 1795 | IS_UNION (t->type.t) ? 'u' : 's', |
| 1762 | t->c); | 1796 | t->c); |
| 1797 | |||
| 1763 | while (t->next) { | 1798 | while (t->next) { |
| 1764 | int pos, size, align; | 1799 | int pos, size, align; |
| 1765 | |||
| 1766 | t = t->next; | 1800 | t = t->next; |
| 1767 | if (STRUCT_NODEBUG(t)) | 1801 | if (STRUCT_NODEBUG(t)) |
| 1768 | continue; | 1802 | continue; |
| 1769 | tcc_debug_check_forw(s1, t, -1); | ||
| 1770 | cstr_printf (&str, "%s:", | 1803 | cstr_printf (&str, "%s:", |
| 1771 | get_tok_str(t->v, NULL)); | 1804 | (t->v & ~SYM_FIELD) >= SYM_FIRST_ANOM |
| 1805 | ? "" : get_tok_str(t->v, NULL) | ||
| 1806 | ); | ||
| 1772 | tcc_get_debug_info (s1, t, &str); | 1807 | tcc_get_debug_info (s1, t, &str); |
| 1773 | if (t->type.t & VT_BITFIELD) { | 1808 | if (t->type.t & VT_BITFIELD) { |
| 1774 | pos = t->c * 8 + BIT_POS(t->type.t); | 1809 | pos = t->c * 8 + BIT_POS(t->type.t); |
| @@ -1787,10 +1822,7 @@ static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result) · 12 unmodified lines | |||
| 1787 | } | 1822 | } |
| 1788 | else if (IS_ENUM(type)) { | 1823 | else if (IS_ENUM(type)) { |
| 1789 | Sym *e = t = t->type.ref; | 1824 | Sym *e = t = t->type.ref; |
| 1790 | 1825 | if (stabs_struct_find(s1, t, &debug_type)) { | |
| 1791 | debug_type = tcc_debug_find(s1, t, 0); | ||
| 1792 | if (debug_type == -1) { | ||
| 1793 | debug_type = tcc_debug_add(s1, t, 0); | ||
| 1794 | cstr_new (&str); | 1826 | cstr_new (&str); |
| 1795 | cstr_printf (&str, "%s:T%d=e", | 1827 | cstr_printf (&str, "%s:T%d=e", |
| 1796 | (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM | 1828 | (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM |
| @@ -1817,6 +1849,10 @@ static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result) · 20 unmodified lines | |||
| 1817 | if (debug_type > N_DEFAULT_DEBUG) | 1849 | if (debug_type > N_DEFAULT_DEBUG) |
| 1818 | return; | 1850 | return; |
| 1819 | } | 1851 | } |
| 1852 | |||
| 1853 | if (NULL == result) /* from stabs_struct_complete() */ | ||
| 1854 | return; | ||
| 1855 | |||
| 1820 | if (n > 0) | 1856 | if (n > 0) |
| 1821 | cstr_printf (result, "%d=", ++debug_next_type); | 1857 | cstr_printf (result, "%d=", ++debug_next_type); |
| 1822 | t = s; | 1858 | t = s; |
| @@ -1836,12 +1872,19 @@ static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result) · 13 unmodified lines | |||
| 1836 | } | 1872 | } |
| 1837 | else | 1873 | else |
| 1838 | break; | 1874 | break; |
| 1839 | tcc_debug_check_forw(s1, t, -1); | ||
| 1840 | t = t->type.ref; | 1875 | t = t->type.ref; |
| 1841 | } | 1876 | } |
| 1842 | cstr_printf (result, "%d", debug_type); | 1877 | cstr_printf (result, "%d", debug_type); |
| 1843 | } | 1878 | } |
| 1844 | 1879 | ||
| 1880 | static void stabs_struct_complete(TCCState *s1, CType *t) | ||
| 1881 | { | ||
| 1882 | if (stabs_struct_find(s1, t->ref, NULL)) { | ||
| 1883 | Sym s = {0}; s.type = *t; | ||
| 1884 | tcc_get_debug_info(s1, &s, NULL); | ||
| 1885 | } | ||
| 1886 | } | ||
| 1887 | |||
| 1845 | static int tcc_get_dwarf_info(TCCState *s1, Sym *s) | 1888 | static int tcc_get_dwarf_info(TCCState *s1, Sym *s) |
| 1846 | { | 1889 | { |
| 1847 | int type; | 1890 | int type; |
| @@ -1993,7 +2036,7 @@ static int tcc_get_dwarf_info(TCCState *s1, Sym *s) · 145 unmodified lines | |||
| 1993 | dwarf_data1(dwarf_info_section, DWARF_ABBREV_BASE_TYPE); | 2036 | dwarf_data1(dwarf_info_section, DWARF_ABBREV_BASE_TYPE); |
| 1994 | dwarf_uleb128(dwarf_info_section, default_debug[i - 1].size); | 2037 | dwarf_uleb128(dwarf_info_section, default_debug[i - 1].size); |
| 1995 | dwarf_data1(dwarf_info_section, default_debug[i - 1].encoding); | 2038 | dwarf_data1(dwarf_info_section, default_debug[i - 1].encoding); |
| 1996 | strncpy(name, default_debug[i - 1].name, sizeof(name) -1); | 2039 | pstrcpy(name, sizeof name, default_debug[i - 1].name); |
| 1997 | *strchr(name, ':') = 0; | 2040 | *strchr(name, ':') = 0; |
| 1998 | dwarf_strp(dwarf_info_section, name); | 2041 | dwarf_strp(dwarf_info_section, name); |
| 1999 | dwarf_info.base_type_used[i - 1] = debug_type; | 2042 | dwarf_info.base_type_used[i - 1] = debug_type; |
| @@ -2404,7 +2447,6 @@ ST_FUNC void tcc_debug_extern_sym(TCCState *s1, Sym *sym, int sh_num, int sym_bi · 404 unmodified lines | |||
| 2404 | sym_bind == STB_GLOBAL ? 'G' : func_ind != -1 ? 'V' : 'S' | 2447 | sym_bind == STB_GLOBAL ? 'G' : func_ind != -1 ? 'V' : 'S' |
| 2405 | ); | 2448 | ); |
| 2406 | tcc_get_debug_info(s1, sym, &str); | 2449 | tcc_get_debug_info(s1, sym, &str); |
| 2407 | tcc_debug_check_forw(s1, sym, -1); | ||
| 2408 | if (sym_bind == STB_GLOBAL) | 2450 | if (sym_bind == STB_GLOBAL) |
| 2409 | tcc_debug_stabs(s1, str.data, N_GSYM, 0, NULL, 0, 0); | 2451 | tcc_debug_stabs(s1, str.data, N_GSYM, 0, NULL, 0, 0); |
| 2410 | else | 2452 | else |
| @@ -2437,11 +2479,8 @@ ST_FUNC void tcc_debug_typedef(TCCState *s1, Sym *sym) · 26 unmodified lines | |||
| 2437 | { | 2479 | { |
| 2438 | CString str; | 2480 | CString str; |
| 2439 | cstr_new (&str); | 2481 | cstr_new (&str); |
| 2440 | cstr_printf (&str, "%s:t", | 2482 | cstr_printf (&str, "%s:t", get_tok_str(sym->v, NULL)); |
| 2441 | (sym->v & ~SYM_FIELD) >= SYM_FIRST_ANOM | ||
| 2442 | ? "" : get_tok_str(sym->v, NULL)); | ||
| 2443 | tcc_get_debug_info(s1, sym, &str); | 2483 | tcc_get_debug_info(s1, sym, &str); |
| 2444 | tcc_debug_check_forw(s1, sym, -1); | ||
| 2445 | tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0, 0); | 2484 | tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0, 0); |
| 2446 | cstr_free (&str); | 2485 | cstr_free (&str); |
| 2447 | } | 2486 | } |
| @@ -1294,16 +1294,21 @@ static Sym *sym_copy(Sym *s0, Sym **ps) · 1293 unmodified lines | |||
| 1294 | Sym *s; | 1294 | Sym *s; |
| 1295 | s = sym_malloc(), *s = *s0; | 1295 | s = sym_malloc(), *s = *s0; |
| 1296 | s->prev = *ps, *ps = s; | 1296 | s->prev = *ps, *ps = s; |
| 1297 | if ((s->v & ~SYM_STRUCT) < SYM_FIRST_ANOM) | 1297 | if ((s->v & ~SYM_STRUCT) < SYM_FIRST_ANOM && ps == &local_stack) |
| 1298 | sym_link(s, 1); | 1298 | sym_link(s, 1); |
| 1299 | return s; | 1299 | return s; |
| 1300 | } | 1300 | } |
| 1301 | 1301 | ||
| 1302 | /* copy s->type.ref to stack 'ps' for VT_FUNC and VT_PTR */ | 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 */ | ||
| 1303 | static void sym_copy_ref(Sym *s, Sym **ps) | 1304 | static void sym_copy_ref(Sym *s, Sym **ps) |
| 1304 | { | 1305 | { |
| 1305 | int bt = s->type.t & VT_BTYPE; | 1306 | int bt = s->type.t & VT_BTYPE; |
| 1306 | if (bt == VT_FUNC || bt == VT_PTR || (bt == VT_STRUCT && s->sym_scope)) { | 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)) { | ||
| 1307 | Sym **sp = &s->type.ref; | 1312 | Sym **sp = &s->type.ref; |
| 1308 | for (s = *sp, *sp = NULL; s; s = s->next) { | 1313 | for (s = *sp, *sp = NULL; s; s = s->next) { |
| 1309 | Sym *s2 = sym_copy(s, ps); | 1314 | Sym *s2 = sym_copy(s, ps); |
| @@ -5962,13 +5967,10 @@ ST_FUNC void unary(void) · 4652 unmodified lines | |||
| 5962 | learn = 1; | 5967 | learn = 1; |
| 5963 | next(); | 5968 | next(); |
| 5964 | } else { | 5969 | } else { |
| 5965 | AttributeDef ad_tmp; | 5970 | int v; |
| 5966 | int itmp; | 5971 | parse_btype(&type, &ad, 0); |
| 5967 | CType cur_type; | 5972 | type_decl(&type, &ad, &v, TYPE_ABSTRACT); |
| 5968 | 5973 | if (compare_types(&controlling_type, &type, 0)) { | |
| 5969 | parse_btype(&cur_type, &ad_tmp, 0); | ||
| 5970 | type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT); | ||
| 5971 | if (compare_types(&controlling_type, &cur_type, 0)) { | ||
| 5972 | if (has_match) { | 5974 | if (has_match) { |
| 5973 | tcc_error("type match twice"); | 5975 | tcc_error("type match twice"); |
| 5974 | } | 5976 | } |
| @@ -1,7 +1,11 @@ | |||
| 1 | #include <stdio.h> | 1 | int printf(const char*, ...); |
| 2 | |||
| 3 | #define myassert(x) \ | ||
| 4 | printf("%s:%d: %s : \"%s\"\n", __FILE__,__LINE__,(x)?"ok":"error",#x) | ||
| 5 | |||
| 2 | enum{ in = 0}; | 6 | enum{ in = 0}; |
| 3 | #define myassert(X) do{ if(!X) printf("%d: assertion failed\n", __LINE__); }while(0) | 7 | |
| 4 | int main(){ | 8 | int main_1(){ |
| 5 | { | 9 | { |
| 6 | myassert(!in); | 10 | myassert(!in); |
| 7 | if(sizeof(enum{in=1})) myassert(in); | 11 | if(sizeof(enum{in=1})) myassert(in); |
| @@ -38,6 +42,45 @@ int main(){ · 30 unmodified lines | |||
| 38 | for(;sizeof(enum{in=1});){ myassert(in); break; } | 42 | for(;sizeof(enum{in=1});){ myassert(in); break; } |
| 39 | myassert(!in); //OK | 43 | myassert(!in); //OK |
| 40 | } | 44 | } |
| 45 | return 0; | ||
| 46 | } | ||
| 47 | |||
| 48 | /* --------------------------------------------- */ | ||
| 49 | int main_2() | ||
| 50 | { | ||
| 51 | char c = 'a'; | ||
| 52 | void func1(char c); /* param 'c' must not shadow local 'c' */ | ||
| 53 | func1(c); | ||
| 54 | return 0; | ||
| 55 | } | ||
| 41 | 56 | ||
| 57 | void func1(char c) | ||
| 58 | { | ||
| 59 | myassert(c == 'a'); | ||
| 42 | } | 60 | } |
| 43 | 61 | ||
| 62 | struct st { int a; }; | ||
| 63 | |||
| 64 | /* --------------------------------------------- */ | ||
| 65 | int main_3() | ||
| 66 | { | ||
| 67 | struct st func(void); | ||
| 68 | struct st st = func(); /* not an 'incompatible redefinition' */ | ||
| 69 | myassert(st.a == 10); | ||
| 70 | return 0; | ||
| 71 | } | ||
| 72 | |||
| 73 | struct st func(void) | ||
| 74 | { | ||
| 75 | struct st st = { 10 }; | ||
| 76 | return st; | ||
| 77 | } | ||
| 78 | |||
| 79 | /* --------------------------------------------- */ | ||
| 80 | int main() | ||
| 81 | { | ||
| 82 | main_1(); | ||
| 83 | main_2(); | ||
| 84 | main_3(); | ||
| 85 | return 0; | ||
| 86 | } | ||
| @@ -0,0 +1,23 @@ | |||
| 1 | 129_scopes.c:10: ok : "!in" | ||
| 2 | 129_scopes.c:11: ok : "in" | ||
| 3 | 129_scopes.c:12: ok : "!in" | ||
| 4 | 129_scopes.c:15: ok : "!in" | ||
| 5 | 129_scopes.c:16: ok : "in" | ||
| 6 | 129_scopes.c:17: ok : "!in" | ||
| 7 | 129_scopes.c:20: ok : "!in" | ||
| 8 | 129_scopes.c:21: ok : "in" | ||
| 9 | 129_scopes.c:22: ok : "!in" | ||
| 10 | 129_scopes.c:25: ok : "!in" | ||
| 11 | 129_scopes.c:26: ok : "!in" | ||
| 12 | 129_scopes.c:27: ok : "!in" | ||
| 13 | 129_scopes.c:31: ok : "!in" | ||
| 14 | 129_scopes.c:32: ok : "in" | ||
| 15 | 129_scopes.c:33: ok : "!in" | ||
| 16 | 129_scopes.c:36: ok : "!in" | ||
| 17 | 129_scopes.c:37: ok : "in" | ||
| 18 | 129_scopes.c:38: ok : "!in" | ||
| 19 | 129_scopes.c:41: ok : "!in" | ||
| 20 | 129_scopes.c:42: ok : "in" | ||
| 21 | 129_scopes.c:43: ok : "!in" | ||
| 22 | 129_scopes.c:59: ok : "c == 'a'" | ||
| 23 | 129_scopes.c:69: ok : "st.a == 10" | ||