libtcc.c: - revert "Small patch to allow..." (someone's personal easteregg) (see da3a763e977a84edf43c5ca101deae768ae8480d) - check return value from macho_load_tbd/dylib tcc.c: - remove help for "not yet implemented" option tccelf.c: - check PIE's for "unresolved symbols" tccgen.c: - avoid int->double->int cast (see a46372e910710b9b00d4f4122ef6c1b00b2b909c) - fix constant propagation with pseudo long doubles (must mask out VT_LONG from type) - cleanup find_field() (again) tccpp.c: - disallow strings and double constants in #if expressions win32/include/uchar.h: - change file mode
Unified · Split
| @@ -99,50 +99,12 @@ BOOL WINAPI DllMain (HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved) · 98 unmodified lines | ||
| 99 | 99 | /* on win32, we suppose the lib and includes are at the location of 'tcc.exe' */ |
| 100 | 100 | static inline char *config_tccdir_w32(char *path) |
| 101 | 101 | { |
| 102 | − char temp[1024]; | |
| 103 | − char try[1024]; | |
| 104 | 102 | char *p; |
| 105 | − int c; | |
| 106 | 103 | GetModuleFileName(tcc_module, path, MAX_PATH); |
| 107 | 104 | p = tcc_basename(normalize_slashes(strlwr(path))); |
| 108 | 105 | if (p > path) |
| 109 | 106 | --p; |
| 110 | − | |
| 111 | 107 | *p = 0; |
| 112 | − | |
| 113 | − /* | |
| 114 | − * See if we are perhaps in a "bin/" subfolder of the | |
| 115 | − * installation path, in which case the real root of | |
| 116 | − * the installation is one level up. We can test this | |
| 117 | − * by looking for the 'include' folder. | |
| 118 | − */ | |
| 119 | − strncpy(temp, path, sizeof(temp)-1); | |
| 120 | − strcat(temp, "/include"); | |
| 121 | − | |
| 122 | − if (_access(temp, 0) != 0) { | |
| 123 | − /* No 'include' folder found, so go up one level. */ | |
| 124 | − strncpy(temp, path, sizeof(temp)-1); | |
| 125 | − | |
| 126 | − /* Try this for several "levels" up. */ | |
| 127 | − for (c = 0; c < 4; c++) { | |
| 128 | − p = tcc_basename(temp); | |
| 129 | − if (p > temp) { | |
| 130 | − --p; | |
| 131 | − *p = '\0'; | |
| 132 | − } | |
| 133 | − | |
| 134 | − strncpy(try, temp, sizeof(try)-1); | |
| 135 | − strcat(try, "/include"); | |
| 136 | − | |
| 137 | − if (_access(try, 0) == 0) { | |
| 138 | − if (p != NULL) | |
| 139 | − p = '\0'; | |
| 140 | − strcpy(path, temp); | |
| 141 | − break; | |
| 142 | − } | |
| 143 | − } | |
| 144 | − } | |
| 145 | − | |
| 146 | 108 | return path; |
| 147 | 109 | } |
| 148 | 110 | #define CONFIG_TCCDIR config_tccdir_w32(alloca(MAX_PATH)) |
| @@ -1174,7 +1136,7 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 1025 unmodified lines | ||
| 1174 | 1136 | } else { |
| 1175 | 1137 | ret = macho_load_tbd(s1, fd, filename, (flags & AFF_REFERENCED_DLL) != 0); |
| 1176 | 1138 | } |
| 1177 | − break; | |
| 1139 | + goto check_success; | |
| 1178 | 1140 | default: |
| 1179 | 1141 | { |
| 1180 | 1142 | const char *ext = tcc_fileextension(filename); |
| @@ -48,7 +48,6 @@ static const char help[] = · 47 unmodified lines | ||
| 48 | 48 | " -Dsym[=val] define 'sym' with value 'val'\n" |
| 49 | 49 | " -Usym undefine 'sym'\n" |
| 50 | 50 | " -E preprocess only\n" |
| 51 | − " -C keep comments (not yet implemented)\n" | |
| 52 | 51 | "Linker options:\n" |
| 53 | 52 | " -Ldir add library path 'dir'\n" |
| 54 | 53 | " -llib link with dynamic or static library 'lib'\n" |
| @@ -303,7 +302,7 @@ redo: · 248 unmodified lines | ||
| 303 | 302 | if (opt == OPT_M32 || opt == OPT_M64) |
| 304 | 303 | return tcc_tool_cross(s, argv, opt); |
| 305 | 304 | if (s->verbose) |
| 306 | − printf(version); | |
| 305 | + printf("%s", version); | |
| 307 | 306 | if (opt == OPT_AR) |
| 308 | 307 | return tcc_tool_ar(s, argc, argv); |
| 309 | 308 | #ifdef TCC_TARGET_PE |
| @@ -284,7 +284,7 @@ extern long double strtold (const char *__nptr, char **__endptr); · 283 unmodified lines | ||
| 284 | 284 | |
| 285 | 285 | /* library search paths */ |
| 286 | 286 | #ifndef CONFIG_TCC_LIBPATHS |
| 287 | −# ifdef TCC_TARGET_PE | |
| 287 | +# if defined TCC_TARGET_PE || defined _WIN32 | |
| 288 | 288 | # define CONFIG_TCC_LIBPATHS "{B}/lib" |
| 289 | 289 | # else |
| 290 | 290 | # define CONFIG_TCC_LIBPATHS \ |
| @@ -496,7 +496,6 @@ typedef struct CString { · 205 unmodified lines | ||
| 496 | 496 | int size; /* size in bytes */ |
| 497 | 497 | int size_allocated; |
| 498 | 498 | void *data; /* either 'char *' or 'nwchar_t *' */ |
| 499 | − struct CString *prev; | |
| 500 | 499 | } CString; |
| 501 | 500 | |
| 502 | 501 | /* type definition */ |
| @@ -1880,7 +1880,7 @@ static void fill_local_got_entries(TCCState *s1) · 1879 unmodified lines | ||
| 1880 | 1880 | |
| 1881 | 1881 | /* Bind symbols of executable: resolve undefined symbols from exported symbols |
| 1882 | 1882 | in shared libraries */ |
| 1883 | −static void bind_exe_dynsyms(TCCState *s1) | |
| 1883 | +static void bind_exe_dynsyms(TCCState *s1, int is_PIE) | |
| 1884 | 1884 | { |
| 1885 | 1885 | const char *name; |
| 1886 | 1886 | int sym_index, index; |
| @@ -1895,6 +1895,8 @@ static void bind_exe_dynsyms(TCCState *s1) · 8 unmodified lines | ||
| 1895 | 1895 | name = (char *) symtab_section->link->data + sym->st_name; |
| 1896 | 1896 | sym_index = find_elf_sym(s1->dynsymtab_section, name); |
| 1897 | 1897 | if (sym_index) { |
| 1898 | + if (is_PIE) | |
| 1899 | + continue; | |
| 1898 | 1900 | esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index]; |
| 1899 | 1901 | type = ELFW(ST_TYPE)(esym->st_info); |
| 1900 | 1902 | if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) { |
| @@ -1970,9 +1972,9 @@ static void bind_libs_dynsyms(TCCState *s1) · 69 unmodified lines | ||
| 1970 | 1972 | for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { |
| 1971 | 1973 | name = (char *)symtab_section->link->data + sym->st_name; |
| 1972 | 1974 | dynsym_index = find_elf_sym(s1->dynsymtab_section, name); |
| 1973 | − if (sym->st_shndx != SHN_UNDEF | |
| 1974 | − && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { | |
| 1975 | − if (dynsym_index || s1->rdynamic) | |
| 1975 | + if (sym->st_shndx != SHN_UNDEF) { | |
| 1976 | + if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL | |
| 1977 | + && (dynsym_index || s1->rdynamic)) | |
| 1976 | 1978 | set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, |
| 1977 | 1979 | sym->st_info, 0, sym->st_shndx, name); |
| 1978 | 1980 | } else if (dynsym_index) { |
| @@ -2797,8 +2799,8 @@ static int elf_output_file(TCCState *s1, const char *filename) · 818 unmodified lines | ||
| 2797 | 2799 | dynamic->sh_entsize = sizeof(ElfW(Dyn)); |
| 2798 | 2800 | |
| 2799 | 2801 | got_sym = build_got(s1); |
| 2800 | − if (file_type == TCC_OUTPUT_EXE) { | |
| 2801 | − bind_exe_dynsyms(s1); | |
| 2802 | + if (file_type & TCC_OUTPUT_EXE) { | |
| 2803 | + bind_exe_dynsyms(s1, file_type & TCC_OUTPUT_DYN); | |
| 2802 | 2804 | if (s1->nb_errors) |
| 2803 | 2805 | goto the_end; |
| 2804 | 2806 | } |
| @@ -2474,7 +2474,7 @@ void gen_negf(int op) · 2473 unmodified lines | ||
| 2474 | 2474 | /* generate a floating point operation with constant propagation */ |
| 2475 | 2475 | static void gen_opif(int op) |
| 2476 | 2476 | { |
| 2477 | − int c1, c2, cast_int = 0; | |
| 2477 | + int c1, c2, i, bt; | |
| 2478 | 2478 | SValue *v1, *v2; |
| 2479 | 2479 | #if defined _MSC_VER && defined __x86_64__ |
| 2480 | 2480 | /* avoid bad optimization with f1 -= f2 for f1:-0.0, f2:0.0 */ |
| @@ -2486,15 +2486,16 @@ static void gen_opif(int op) · 5 unmodified lines | ||
| 2486 | 2486 | v2 = vtop; |
| 2487 | 2487 | if (op == TOK_NEG) |
| 2488 | 2488 | v1 = v2; |
| 2489 | + bt = v1->type.t & VT_BTYPE; | |
| 2489 | 2490 | |
| 2490 | 2491 | /* currently, we cannot do computations with forward symbols */ |
| 2491 | 2492 | c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; |
| 2492 | 2493 | c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; |
| 2493 | 2494 | if (c1 && c2) { |
| 2494 | − if (v1->type.t == VT_FLOAT) { | |
| 2495 | + if (bt == VT_FLOAT) { | |
| 2495 | 2496 | f1 = v1->c.f; |
| 2496 | 2497 | f2 = v2->c.f; |
| 2497 | − } else if (v1->type.t == VT_DOUBLE) { | |
| 2498 | + } else if (bt == VT_DOUBLE) { | |
| 2498 | 2499 | f1 = v1->c.d; |
| 2499 | 2500 | f2 = v2->c.d; |
| 2500 | 2501 | } else { |
| @@ -2533,41 +2534,39 @@ static void gen_opif(int op) · 32 unmodified lines | ||
| 2533 | 2534 | f1 = -f1; |
| 2534 | 2535 | goto unary_result; |
| 2535 | 2536 | case TOK_EQ: |
| 2536 | − f1 = f1 == f2; | |
| 2537 | + i = f1 == f2; | |
| 2537 | 2538 | make_int: |
| 2538 | − cast_int = 1; | |
| 2539 | − break; | |
| 2539 | + vtop -= 2; | |
| 2540 | + vpushi(i); | |
| 2541 | + return; | |
| 2540 | 2542 | case TOK_NE: |
| 2541 | − f1 = f1 != f2; | |
| 2543 | + i = f1 != f2; | |
| 2542 | 2544 | goto make_int; |
| 2543 | 2545 | case TOK_LT: |
| 2544 | − f1 = f1 < f2; | |
| 2546 | + i = f1 < f2; | |
| 2545 | 2547 | goto make_int; |
| 2546 | 2548 | case TOK_GE: |
| 2547 | − f1 = f1 >= f2; | |
| 2549 | + i = f1 >= f2; | |
| 2548 | 2550 | goto make_int; |
| 2549 | 2551 | case TOK_LE: |
| 2550 | − f1 = f1 <= f2; | |
| 2552 | + i = f1 <= f2; | |
| 2551 | 2553 | goto make_int; |
| 2552 | 2554 | case TOK_GT: |
| 2553 | − f1 = f1 > f2; | |
| 2555 | + i = f1 > f2; | |
| 2554 | 2556 | goto make_int; |
| 2555 | − /* XXX: also handles tests ? */ | |
| 2556 | 2557 | default: |
| 2557 | 2558 | goto general_case; |
| 2558 | 2559 | } |
| 2559 | 2560 | vtop--; |
| 2560 | 2561 | unary_result: |
| 2561 | 2562 | /* XXX: overflow test ? */ |
| 2562 | − if (v1->type.t == VT_FLOAT) { | |
| 2563 | + if (bt == VT_FLOAT) { | |
| 2563 | 2564 | v1->c.f = f1; |
| 2564 | − } else if (v1->type.t == VT_DOUBLE) { | |
| 2565 | + } else if (bt == VT_DOUBLE) { | |
| 2565 | 2566 | v1->c.d = f1; |
| 2566 | 2567 | } else { |
| 2567 | 2568 | v1->c.ld = f1; |
| 2568 | 2569 | } |
| 2569 | − if (cast_int) | |
| 2570 | − gen_cast_s(VT_INT); | |
| 2571 | 2570 | } else { |
| 2572 | 2571 | general_case: |
| 2573 | 2572 | if (op == TOK_NEG) { |
| @@ -4029,10 +4028,18 @@ static Sym * find_field (CType *type, int v, int *cumofs) · 1455 unmodified lines | ||
| 4029 | 4028 | { |
| 4030 | 4029 | Sym *s = type->ref; |
| 4031 | 4030 | int v1 = v | SYM_FIELD; |
| 4032 | − | |
| 4031 | + if (!(v & SYM_FIELD)) { /* top-level call */ | |
| 4032 | + if ((type->t & VT_BTYPE) != VT_STRUCT) | |
| 4033 | + expect("struct or union"); | |
| 4034 | + if (v < TOK_UIDENT) | |
| 4035 | + expect("field name"); | |
| 4036 | + if (s->c < 0) | |
| 4037 | + tcc_error("dereferencing incomplete type '%s'", | |
| 4038 | + get_tok_str(s->v & ~SYM_STRUCT, 0)); | |
| 4039 | + } | |
| 4033 | 4040 | while ((s = s->next) != NULL) { |
| 4034 | 4041 | if (s->v == v1) { |
| 4035 | − *cumofs += s->c; | |
| 4042 | + *cumofs = s->c; | |
| 4036 | 4043 | return s; |
| 4037 | 4044 | } |
| 4038 | 4045 | if ((s->type.t & VT_BTYPE) == VT_STRUCT |
| @@ -4045,17 +4052,9 @@ static Sym * find_field (CType *type, int v, int *cumofs) · 6 unmodified lines | ||
| 4045 | 4052 | } |
| 4046 | 4053 | } |
| 4047 | 4054 | } |
| 4048 | − | |
| 4049 | − if (!(v & SYM_FIELD)) { /* top-level call */ | |
| 4050 | − s = type->ref; | |
| 4051 | − if (s->c < 0) | |
| 4052 | − tcc_error("dereferencing incomplete type '%s'", | |
| 4053 | − get_tok_str(s->v & ~SYM_STRUCT, 0)); | |
| 4054 | − else | |
| 4055 | − tcc_error("field not found: %s", | |
| 4056 | − get_tok_str(v, &tokc)); | |
| 4057 | − } | |
| 4058 | − return NULL; | |
| 4055 | + if (!(v & SYM_FIELD)) | |
| 4056 | + tcc_error("field not found: %s", get_tok_str(v, NULL)); | |
| 4057 | + return s; | |
| 4059 | 4058 | } |
| 4060 | 4059 | |
| 4061 | 4060 | static void check_fields (CType *type, int check) |
| @@ -6003,21 +6002,15 @@ special_math_val: · 1941 unmodified lines | ||
| 6003 | 6002 | if (tok == TOK_INC || tok == TOK_DEC) { |
| 6004 | 6003 | inc(1, tok); |
| 6005 | 6004 | next(); |
| 6006 | − } else if (tok == '.' || tok == TOK_ARROW || tok == TOK_CDOUBLE) { | |
| 6007 | − int qualifiers, cumofs = 0; | |
| 6005 | + } else if (tok == '.' || tok == TOK_ARROW) { | |
| 6006 | + int qualifiers, cumofs; | |
| 6008 | 6007 | /* field */ |
| 6009 | 6008 | if (tok == TOK_ARROW) |
| 6010 | 6009 | indir(); |
| 6011 | 6010 | qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE); |
| 6012 | 6011 | test_lvalue(); |
| 6013 | 6012 | /* expect pointer on structure */ |
| 6014 | − if ((vtop->type.t & VT_BTYPE) != VT_STRUCT) | |
| 6015 | − expect("struct or union"); | |
| 6016 | − if (tok == TOK_CDOUBLE) | |
| 6017 | − expect("field name"); | |
| 6018 | 6013 | next(); |
| 6019 | − if (tok == TOK_CINT || tok == TOK_CUINT) | |
| 6020 | − expect("field name"); | |
| 6021 | 6014 | s = find_field(&vtop->type, tok, &cumofs); |
| 6022 | 6015 | /* add field offset to pointer */ |
| 6023 | 6016 | gaddrof(); |
| @@ -7494,9 +7487,6 @@ static int decl_designator(init_params *p, CType *type, unsigned long c, · 1470 unmodified lines | ||
| 7494 | 7487 | l = tok; |
| 7495 | 7488 | struct_field: |
| 7496 | 7489 | next(); |
| 7497 | − if ((type->t & VT_BTYPE) != VT_STRUCT) | |
| 7498 | − expect("struct/union type"); | |
| 7499 | − cumofs = 0; | |
| 7500 | 7490 | f = find_field(type, l, &cumofs); |
| 7501 | 7491 | if (cur_field) |
| 7502 | 7492 | *cur_field = f; |
| @@ -1457,7 +1457,10 @@ static int expr_preprocess(TCCState *s1) · 1456 unmodified lines | ||
| 1457 | 1457 | while (tok != TOK_LINEFEED && tok != TOK_EOF) { |
| 1458 | 1458 | next(); /* do macro subst */ |
| 1459 | 1459 | redo: |
| 1460 | − if (tok == TOK_DEFINED) { | |
| 1460 | + if (tok < TOK_IDENT) { | |
| 1461 | + if (tok >= TOK_STR && tok <= TOK_CLDOUBLE) | |
| 1462 | + tcc_error("invalid constant in preprocessor expression"); | |
| 1463 | + } else if (tok == TOK_DEFINED) { | |
| 1461 | 1464 | next_nomacro(); |
| 1462 | 1465 | t = tok; |
| 1463 | 1466 | if (t == '(') |
| @@ -1489,7 +1492,7 @@ static int expr_preprocess(TCCState *s1) · 25 unmodified lines | ||
| 1489 | 1492 | expect("')'"); |
| 1490 | 1493 | tok = TOK_CINT; |
| 1491 | 1494 | tokc.i = c; |
| 1492 | − } else if (tok >= TOK_IDENT) { | |
| 1495 | + } else { | |
| 1493 | 1496 | /* if undefined macro, replace with zero, check for func-like */ |
| 1494 | 1497 | t = tok; |
| 1495 | 1498 | tok = TOK_CINT; |
| @@ -209,9 +209,8 @@ TF_TYPE(thread_test_complex, vn) · 208 unmodified lines | ||
| 209 | 209 | sleep_ms(2); |
| 210 | 210 | ret = tcc_add_file(s, argv[0]); |
| 211 | 211 | sleep_ms(3); |
| 212 | − if (ret < 0) | |
| 213 | − exit(1); | |
| 214 | − tcc_run(s, argc, argv); | |
| 212 | + if (ret == 0) | |
| 213 | + tcc_run(s, argc, argv); | |
| 215 | 214 | tcc_delete(s); |
| 216 | 215 | fflush(stdout); |
| 217 | 216 | return 0; |
File mode changed from 100755 to 100644.