diff --git a/arm-gen.c b/arm-gen.c index 011ba4d5..11b258ad 100644 --- a/arm-gen.c +++ b/arm-gen.c @@ -161,7 +161,7 @@ static int leaffunc; #if defined(CONFIG_TCC_BCHECK) static addr_t func_bound_offset; static unsigned long func_bound_ind; -static int func_bound_add_epilog; +ST_DATA int func_bound_add_epilog; #endif #if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP) @@ -763,14 +763,6 @@ static void gcall_or_jmp(int is_jmp) greloc(cur_text_section, vtop->sym, ind, R_ARM_ABS32); o(vtop->c.i); } -#ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check && - (vtop->sym->v == TOK_setjmp || - vtop->sym->v == TOK__setjmp || - vtop->sym->v == TOK_sigsetjmp || - vtop->sym->v == TOK___sigsetjmp)) - func_bound_add_epilog = 1; -#endif }else{ if(!is_jmp) o(0xE28FE004); // add lr,pc,#4 diff --git a/arm64-gen.c b/arm64-gen.c index 3cadcdf0..737c8264 100644 --- a/arm64-gen.c +++ b/arm64-gen.c @@ -84,7 +84,7 @@ ST_DATA const int reg_classes[NB_REGS] = { #if defined(CONFIG_TCC_BCHECK) static addr_t func_bound_offset; static unsigned long func_bound_ind; -static int func_bound_add_epilog; +ST_DATA int func_bound_add_epilog; #endif #define IS_FREG(x) ((x) >= TREG_F(0)) @@ -606,14 +606,6 @@ static void arm64_gen_bl_or_b(int b) greloca(cur_text_section, vtop->sym, ind, b ? R_AARCH64_JUMP26 : R_AARCH64_CALL26, 0); o(0x14000000 | (uint32_t)!b << 31); // b/bl . -#ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check && - (vtop->sym->v == TOK_setjmp || - vtop->sym->v == TOK__setjmp || - vtop->sym->v == TOK_sigsetjmp || - vtop->sym->v == TOK___sigsetjmp)) - func_bound_add_epilog = 1; -#endif } else { #ifdef CONFIG_TCC_BCHECK diff --git a/i386-asm.c b/i386-asm.c index 4e62c3c8..3f7c1df9 100644 --- a/i386-asm.c +++ b/i386-asm.c @@ -1202,7 +1202,7 @@ ST_FUNC int asm_parse_regvar (int t) { const char *s; Operand op; - if (t < TOK_IDENT) + if (t < TOK_IDENT || (t & SYM_FIELD)) return -1; s = table_ident[t - TOK_IDENT]->str; if (s[0] != '%') diff --git a/i386-gen.c b/i386-gen.c index 21866bb2..5fcc3748 100644 --- a/i386-gen.c +++ b/i386-gen.c @@ -97,7 +97,7 @@ static int func_ret_sub; #ifdef CONFIG_TCC_BCHECK static addr_t func_bound_offset; static unsigned long func_bound_ind; -static int func_bound_add_epilog; +ST_DATA int func_bound_add_epilog; static void gen_bounds_prolog(void); static void gen_bounds_epilog(void); #endif @@ -359,18 +359,6 @@ static void gcall_or_jmp(int is_jmp) /* constant and relocation case */ greloc(cur_text_section, vtop->sym, ind + 1, R_386_PC32); oad(0xe8 + is_jmp, vtop->c.i - 4); /* call/jmp im */ -#ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check && - (vtop->sym->v == TOK_alloca || - vtop->sym->v == TOK_setjmp || - vtop->sym->v == TOK__setjmp -#ifndef TCC_TARGET_PE - || vtop->sym->v == TOK_sigsetjmp - || vtop->sym->v == TOK___sigsetjmp -#endif - )) - func_bound_add_epilog = 1; -#endif } else { /* otherwise, indirect call */ r = gv(RC_INT); @@ -429,6 +417,16 @@ ST_FUNC void gfunc_call(int nb_args) /* align to stack align size */ size = (size + 3) & ~3; /* allocate the necessary size on stack */ +#ifdef TCC_TARGET_PE + if (size >= 0x4096) { + o(0x5250); + oad(0x68, size); + vpush_global_sym(&func_old_type, TOK_alloca); + gcall_or_jmp(0); + vtop--; + o(0x58585a); + } else +#endif oad(0xec81, size); /* sub $xxx, %esp */ /* generate structure store */ r = get_reg(RC_INT); diff --git a/libtcc.c b/libtcc.c index 9cbdc12b..fbbbd16c 100644 --- a/libtcc.c +++ b/libtcc.c @@ -967,14 +967,13 @@ LIBTCCAPI TCCState *tcc_new(void) tcc_define_symbol(s, "_FORTIFY_SOURCE", "0"); #endif /* ndef TCC_TARGET_MACHO */ - if (PTR_SIZE == 4) { - tcc_define_symbol(s, "__SIZEOF_LONG__", "4"); - tcc_define_symbol(s, "__LONG_MAX__", "0x7fffffffL"); - } - else { - tcc_define_symbol(s, "__SIZEOF_LONG__", "8"); - tcc_define_symbol(s, "__LONG_MAX__", "0x7fffffffffffffffL"); - } +#if LONG_SIZE == 4 + tcc_define_symbol(s, "__SIZEOF_LONG__", "4"); + tcc_define_symbol(s, "__LONG_MAX__", "0x7fffffffL"); +#else + tcc_define_symbol(s, "__SIZEOF_LONG__", "8"); + tcc_define_symbol(s, "__LONG_MAX__", "0x7fffffffffffffffL"); +#endif tcc_define_symbol(s, "__SIZEOF_INT__", "4"); tcc_define_symbol(s, "__SIZEOF_LONG_LONG__", "8"); tcc_define_symbol(s, "__CHAR_BIT__", "8"); diff --git a/riscv64-gen.c b/riscv64-gen.c index 0907b5c7..8c3486df 100644 --- a/riscv64-gen.c +++ b/riscv64-gen.c @@ -66,7 +66,7 @@ ST_DATA const int reg_classes[NB_REGS] = { #if defined(CONFIG_TCC_BCHECK) static addr_t func_bound_offset; static unsigned long func_bound_ind; -static int func_bound_add_epilog; +ST_DATA int func_bound_add_epilog; #endif static int ireg(int r) @@ -387,14 +387,6 @@ static void gcall_or_jmp(int docall) R_RISCV_CALL_PLT, (int)vtop->c.i); o(0x17 | (tr << 7)); // auipc TR, 0 %call(func) EI(0x67, 0, tr, tr, 0);// jalr TR, r(TR) -#ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check && - (vtop->sym->v == TOK_setjmp || - vtop->sym->v == TOK__setjmp || - vtop->sym->v == TOK_sigsetjmp || - vtop->sym->v == TOK___sigsetjmp)) - func_bound_add_epilog = 1; -#endif } else if (vtop->r < VT_CONST) { int r = ireg(vtop->r); EI(0x67, 0, tr, r, 0); // jalr TR, 0(R) diff --git a/tcc.h b/tcc.h index 8dde0969..63bec3a4 100644 --- a/tcc.h +++ b/tcc.h @@ -643,7 +643,6 @@ typedef struct AttributeDef { struct FuncAttr f; struct Section *section; Sym *cleanup_func; - int alias_target; /* token */ int asm_label; /* associated asm label */ char attr_mode; /* __attribute__((__mode__(...))) */ } AttributeDef; @@ -1475,6 +1474,7 @@ ST_FUNC int classify_x86_64_va_arg(CType *ty); #endif #ifdef CONFIG_TCC_BCHECK ST_FUNC void gbound_args(int nb_args); +ST_DATA int func_bound_add_epilog; #endif /* ------------ tccelf.c ------------ */ diff --git a/tccgen.c b/tccgen.c index c6ed80e3..5e4ffe19 100644 --- a/tccgen.c +++ b/tccgen.c @@ -80,7 +80,7 @@ ST_DATA int func_var; /* true if current function is variadic (used by return in ST_DATA int func_vc; static int last_line_num, new_file, func_ind; /* debug info control */ ST_DATA const char *funcname; -ST_DATA CType int_type, func_old_type, char_pointer_type; +ST_DATA CType int_type, func_old_type, char_type, char_pointer_type; static CString initstr; #if PTR_SIZE == 4 @@ -771,8 +771,13 @@ ST_FUNC void tccgen_init(TCCState *s1) /* define some often used types */ int_type.t = VT_INT; - char_pointer_type.t = VT_BYTE; + + char_type.t = VT_BYTE; + if (s1->char_is_unsigned) + char_type.t |= VT_UNSIGNED; + char_pointer_type = char_type; mk_pointer(&char_pointer_type); + func_old_type.t = VT_FUNC; func_old_type.ref = sym_push(SYM_FIELD, &int_type, 0, 0); func_old_type.ref->f.func_call = FUNC_CDECL; @@ -886,66 +891,9 @@ ST_FUNC void put_extern_sym2(Sym *sym, int sh_num, ElfSym *esym; const char *name; char buf1[256]; -#ifdef CONFIG_TCC_BCHECK - char buf[32]; -#endif + if (!sym->c) { name = get_tok_str(sym->v, NULL); -#ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check) { - /* XXX: avoid doing that for statics ? */ - /* if bound checking is activated, we change some function - names by adding the "__bound" prefix */ -#if defined(TCC_TARGET_ARM) && defined(TCC_ARM_EABI) - if (strcmp (name, "memcpy") == 0 || - strcmp (name, "memmove") == 0 || - strcmp (name, "memset") == 0) - goto add_bound; -#endif - switch(sym->v) { -#ifdef TCC_TARGET_PE - /* XXX: we rely only on malloc hooks */ - case TOK_malloc: - case TOK_free: - case TOK_realloc: - case TOK_memalign: - case TOK_calloc: -#endif - case TOK_memcpy: - case TOK_memmove: -#if defined(TCC_TARGET_ARM) && defined(TCC_ARM_EABI) - case TOK_memmove4: - case TOK_memmove8: -#endif - case TOK_memset: - case TOK_memcmp: - case TOK_strlen: - case TOK_strcpy: - case TOK_strncpy: - case TOK_strcmp: - case TOK_strncmp: - case TOK_strcat: - case TOK_strchr: - case TOK_strdup: -#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 - case TOK_alloca: -#endif - case TOK_mmap: - case TOK_munmap: - case TOK_longjmp: -#ifndef TCC_TARGET_PE - case TOK_siglongjmp: -#endif -#if defined(TCC_TARGET_ARM) && defined(TCC_ARM_EABI) -add_bound: -#endif - strcpy(buf, "__bound_"); - strcat(buf, name); - name = buf; - break; - } - } -#endif t = sym->type.t; if ((t & VT_BTYPE) == VT_FUNC) { sym_type = STT_FUNC; @@ -959,6 +907,7 @@ add_bound: else sym_bind = STB_GLOBAL; other = 0; + #ifdef TCC_TARGET_PE if (sym_type == STT_FUNC && sym->type.ref) { Sym *ref = sym->type.ref; @@ -973,13 +922,20 @@ add_bound: } } #endif + + if (sym->asm_label) { + name = get_tok_str(sym->asm_label & ~SYM_FIELD, NULL); + /* with SYM_FIELD it was __attribute__((alias("..."))) actually */ + if (!(sym->asm_label & SYM_FIELD)) + can_add_underscore = 0; + } + if (tcc_state->leading_underscore && can_add_underscore) { buf1[0] = '_'; pstrcpy(buf1 + 1, sizeof(buf1) - 1, name); name = buf1; } - if (sym->asm_label) - name = get_tok_str(sym->asm_label, NULL); + info = ELFW(ST_INFO)(sym_bind, sym_type); sym->c = put_elf_sym(symtab_section, value, size, info, other, sh_num, name); @@ -1553,8 +1509,6 @@ static void merge_attr(AttributeDef *ad, AttributeDef *ad1) if (ad1->section) ad->section = ad1->section; - if (ad1->alias_target) - ad->alias_target = ad1->alias_target; if (ad1->asm_label) ad->asm_label = ad1->asm_label; if (ad1->attr_mode) @@ -1940,13 +1894,34 @@ static void gbound(void) args into registers */ ST_FUNC void gbound_args(int nb_args) { - int i; + int i, v; + SValue *sv; + for (i = 1; i <= nb_args; ++i) if (vtop[1 - i].r & VT_MUSTBOUND) { vrotb(i); gbound(); vrott(i); } + + sv = vtop - nb_args; + if (sv->r & VT_SYM) { + v = sv->sym->v; + if (v == TOK_setjmp + || v == TOK__setjmp +#ifndef TCC_TARGET_PE + || v == TOK_sigsetjmp + || v == TOK___sigsetjmp +#endif + ) { + vpush_global_sym(&func_old_type, TOK___bound_setjmp); + vpushv(sv + 1); + gfunc_call(1); + func_bound_add_epilog = 1; + } + if (v == TOK_alloca) + func_bound_add_epilog = 1; + } } /* Add bounds for local symbols from S to E (via ->prev) */ @@ -4099,8 +4074,8 @@ redo: case TOK_ALIAS2: skip('('); parse_mult_str(&astr, "alias(\"target\")"); - ad->alias_target = /* save string as token, for later */ - tok_alloc((char*)astr.data, astr.size-1)->tok; + ad->asm_label = /* save string as token, for later */ + tok_alloc((char*)astr.data, astr.size-1)->tok | SYM_FIELD; skip(')'); cstr_free(&astr); break; @@ -5365,43 +5340,39 @@ static void parse_builtin_params(int nc, const char *args) while ((c = *args++)) { skip(sep); sep = ','; + if (c == 't') { + parse_type(&type); + vpush(&type); + continue; + } + expr_eq(); + type.ref = NULL; + type.t = 0; switch (c) { - case 'e': expr_eq(); - continue; - case 't': parse_type(&type); - vpush(&type); - continue; + case 'e': + continue; + case 'V': + type.t = VT_CONSTANT; case 'v': - case 'V': expr_eq(); - type.t = VT_VOID; - if (c == 'V') type.t |= VT_CONSTANT; - type.ref = NULL; - mk_pointer (&type); - gen_assign_cast(&type); - continue; + type.t |= VT_VOID; + mk_pointer (&type); + break; + case 'S': + type.t = VT_CONSTANT; case 's': - case 'S': expr_eq(); - type.t = VT_BYTE; - if (tcc_state->char_is_unsigned) - type.t |= VT_UNSIGNED; - if (c == 'S') type.t |= VT_CONSTANT; - type.ref = NULL; - mk_pointer (&type); - gen_assign_cast(&type); - continue; - case 'i': expr_eq(); - type.t = VT_INT; - type.ref = NULL; - gen_assign_cast(&type); - continue; - case 'l': expr_eq(); - type.t = VT_SIZE_T; - type.ref = NULL; - gen_assign_cast(&type); - continue; - default: tcc_error("internal error"); - break; + type.t |= char_type.t; + mk_pointer (&type); + break; + case 'i': + type.t = VT_INT; + break; + case 'l': + type.t = VT_SIZE_T; + break; + default: + tcc_error("internal error"); } + gen_assign_cast(&type); } skip(')'); if (nc) @@ -5780,196 +5751,6 @@ ST_FUNC void unary(void) break; } #endif - case TOK___builtin_abort: - vpush_global_sym(&func_old_type, TOK_abort); - parse_builtin_params(0, ""); - gfunc_call(0); -builtin_void_return: - vpushi(0); - type.t = VT_VOID; - type.ref = NULL; - vtop->type = type; - vtop->r = R_RET(type.t); - break; - case TOK___builtin_memcpy: - t = TOK_memcpy; -#ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check) t = TOK___bound_memcpy; -#endif - vpush_global_sym(&func_old_type, t); - parse_builtin_params(0, "vVl"); - gfunc_call(3); -builtin_void_ptr_return: - vpushi(0); - type.t = VT_VOID; - type.ref = NULL; - mk_pointer (&type); - vtop->type = type; - vtop->r = R_RET(type.t); - break; - case TOK___builtin_memcmp: - t = TOK_memcmp; -#ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check) t = TOK___bound_memcmp; -#endif - vpush_global_sym(&func_old_type, t); - parse_builtin_params(0, "VVl"); - gfunc_call(3); -builtin_int_return: - vpushi(0); - type.t = VT_INT; - type.ref = NULL; - vtop->type = type; - vtop->r = R_RET(type.t); - break; - case TOK___builtin_memmove: - t = TOK_memmove; -#ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check) t = TOK___bound_memmove; -#endif - vpush_global_sym(&func_old_type, t); - parse_builtin_params(0, "vVl"); - gfunc_call(3); - goto builtin_void_ptr_return; - case TOK___builtin_memset: - t = TOK_memset; -#ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check) t = TOK___bound_memset; -#endif - vpush_global_sym(&func_old_type, t); - parse_builtin_params(0, "vil"); - gfunc_call(3); - goto builtin_void_ptr_return; - case TOK___builtin_strlen: - t = TOK_strlen; -#ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check) t = TOK___bound_strlen; -#endif - vpush_global_sym(&func_old_type, t); - parse_builtin_params(0, "S"); - gfunc_call(1); - vpushi(0); - type.t = VT_SIZE_T; - type.ref = NULL; - vtop->type = type; - vtop->r = R_RET(type.t); - break; - case TOK___builtin_strcpy: - t = TOK_strcpy; -#ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check) t = TOK___bound_strcpy; -#endif - vpush_global_sym(&func_old_type, t); - parse_builtin_params(0, "sS"); - gfunc_call(2); -builtin_string_ptr_return: - vpushi(0); - type.t = VT_BYTE; - if (tcc_state->char_is_unsigned) - type.t |= VT_UNSIGNED; - type.ref = NULL; - mk_pointer (&type); - vtop->type = type; - vtop->r = R_RET(type.t); - break; - case TOK___builtin_strncpy: - t = TOK_strncpy; -#ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check) t = TOK___bound_strncpy; -#endif - vpush_global_sym(&func_old_type, t); - parse_builtin_params(0, "sSl"); - gfunc_call(3); - goto builtin_string_ptr_return; - case TOK___builtin_strcmp: - t = TOK_strcmp; -#ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check) t = TOK___bound_strcmp; -#endif - vpush_global_sym(&func_old_type, t); - parse_builtin_params(0, "SS"); - gfunc_call(2); - goto builtin_int_return; - case TOK___builtin_strncmp: - t = TOK_strncmp; -#ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check) t = TOK___bound_strncmp; -#endif - vpush_global_sym(&func_old_type, t); - parse_builtin_params(0, "SSl"); - gfunc_call(3); - goto builtin_int_return; - case TOK___builtin_strcat: - t = TOK_strcat; -#ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check) t = TOK___bound_strcat; -#endif - vpush_global_sym(&func_old_type, t); - parse_builtin_params(0, "sS"); - gfunc_call(2); - goto builtin_string_ptr_return; - case TOK___builtin_strchr: - t = TOK_strchr; -#ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check) t = TOK___bound_strchr; -#endif - vpush_global_sym(&func_old_type, t); - parse_builtin_params(0, "Si"); - gfunc_call(2); - goto builtin_string_ptr_return; - case TOK___builtin_strdup: - t = TOK_strdup; -#ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check) t = TOK___bound_strdup; -#endif - vpush_global_sym(&func_old_type, t); - parse_builtin_params(0, "S"); - gfunc_call(1); - goto builtin_string_ptr_return; - case TOK___builtin_malloc: - t = TOK_malloc; -#if defined(CONFIG_TCC_BCHECK) && defined(TCC_TARGET_PE) - if (tcc_state->do_bounds_check) t = TOK___bound_malloc; -#endif - vpush_global_sym(&func_old_type, t); - parse_builtin_params(0, "l"); - gfunc_call(1); - goto builtin_void_ptr_return; - case TOK___builtin_realloc: - t = TOK_realloc; -#if defined(CONFIG_TCC_BCHECK) && defined(TCC_TARGET_PE) - if (tcc_state->do_bounds_check) t = TOK___bound_realloc; -#endif - vpush_global_sym(&func_old_type, t); - parse_builtin_params(0, "vl"); - gfunc_call(2); - goto builtin_void_ptr_return; - case TOK___builtin_calloc: - t = TOK_calloc; -#if defined(CONFIG_TCC_BCHECK) && defined(TCC_TARGET_PE) - if (tcc_state->do_bounds_check) t = TOK___bound_calloc; -#endif - vpush_global_sym(&func_old_type, t); - parse_builtin_params(0, "ll"); - gfunc_call(2); - goto builtin_void_ptr_return; - case TOK___builtin_free: - t = TOK_free; -#if defined(CONFIG_TCC_BCHECK) && defined(TCC_TARGET_PE) - if (tcc_state->do_bounds_check) t = TOK___bound_free; -#endif - vpush_global_sym(&func_old_type, t); - parse_builtin_params(0, "v"); - gfunc_call(1); - goto builtin_void_return; -#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 - case TOK_alloca: - case TOK___builtin_alloca: - vpush_global_sym(&func_old_type, TOK_alloca); - parse_builtin_params(0, "l"); - gfunc_call(1); - goto builtin_void_ptr_return; -#endif /* pre operations */ case TOK_INC: @@ -6276,24 +6057,6 @@ special_math_val: if (sa) tcc_error("too few arguments to function"); skip(')'); -#ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check && - (nb_args == 1 || nb_args == 2) && - (vtop[-nb_args].r & VT_SYM) && - (vtop[-nb_args].sym->v == TOK_setjmp || - vtop[-nb_args].sym->v == TOK__setjmp -#ifndef TCC_TARGET_PE - || vtop[-nb_args].sym->v == TOK_sigsetjmp - || vtop[-nb_args].sym->v == TOK___sigsetjmp -#endif - )) { - vpush_global_sym(&func_old_type, TOK___bound_setjmp); - vpushv(vtop - nb_args); - if (nb_args == 2) - vpushv(vtop - nb_args); - gfunc_call(nb_args); - } -#endif gfunc_call(nb_args); if (ret_nregs < 0) { @@ -8602,15 +8365,6 @@ found: /* external variable or function */ type.t |= VT_EXTERN; sym = external_sym(v, &type, r, &ad); - if (ad.alias_target) { - ElfSym *esym; - Sym *alias_target; - alias_target = sym_find(ad.alias_target); - esym = elfsym(alias_target); - if (!esym) - tcc_error("unsupported forward __alias__ attribute"); - put_extern_sym2(sym, esym->st_shndx, esym->st_value, esym->st_size, 0); - } } else { if (type.t & VT_STATIC) r |= VT_CONST; diff --git a/tccpp.c b/tccpp.c index 94f8b02a..e5283c66 100644 --- a/tccpp.c +++ b/tccpp.c @@ -3625,10 +3625,13 @@ ST_INLN void unget_tok(int last_tok) static void tcc_predefs(CString *cstr) { cstr_cat(cstr, + + //"#include \n" + #if defined TCC_TARGET_X86_64 #ifndef TCC_TARGET_PE - /* GCC compatible definition of va_list. This should be in sync - with the declaration in our lib/libtcc1.c */ + /* GCC compatible definition of va_list. */ + /* This should be in sync with the declaration in our lib/libtcc1.c */ "typedef struct{\n" "unsigned gp_offset,fp_offset;\n" "union{\n" @@ -3644,7 +3647,6 @@ static void tcc_predefs(CString *cstr) #else /* TCC_TARGET_PE */ "typedef char*__builtin_va_list;\n" "#define __builtin_va_arg(ap,t) ((sizeof(t)>8||(sizeof(t)&(sizeof(t)-1)))?**(t**)((ap+=8)-8):*(t*)((ap+=8)-8))\n" - "#define __builtin_va_copy(dest,src) (dest)=(src)\n" #endif #elif defined TCC_TARGET_ARM "typedef char*__builtin_va_list;\n" @@ -3652,26 +3654,69 @@ static void tcc_predefs(CString *cstr) "#define _tcc_align(addr,type) (((unsigned)addr+_tcc_alignof(type)-1)&~(_tcc_alignof(type)-1))\n" "#define __builtin_va_start(ap,last) (ap=((char*)&(last))+((sizeof(last)+3)&~3))\n" "#define __builtin_va_arg(ap,type) (ap=(void*)((_tcc_align(ap,type)+sizeof(type)+3)&~3),*(type*)(ap-((sizeof(type)+3)&~3)))\n" - "#define __builtin_va_copy(dest,src) (dest)=(src)\n" #elif defined TCC_TARGET_ARM64 "typedef struct{\n" "void*__stack,*__gr_top,*__vr_top;\n" "int __gr_offs,__vr_offs;\n" "}__builtin_va_list;\n" - "#define __builtin_va_copy(dest,src) (dest)=(src)\n" #elif defined TCC_TARGET_RISCV64 "typedef char*__builtin_va_list;\n" "#define __va_reg_size (__riscv_xlen>>3)\n" "#define _tcc_align(addr,type) (((unsigned long)addr+__alignof__(type)-1)&-(__alignof__(type)))\n" "#define __builtin_va_arg(ap,type) (*(sizeof(type)>(2*__va_reg_size)?*(type**)((ap+=__va_reg_size)-__va_reg_size):(ap=(va_list)(_tcc_align(ap,type)+(sizeof(type)+__va_reg_size-1)&-__va_reg_size),(type*)(ap-((sizeof(type)+__va_reg_size-1)&-__va_reg_size)))))\n" - "#define __builtin_va_copy(dest,src) (dest)=(src)\n" #else /* TCC_TARGET_I386 */ "typedef char*__builtin_va_list;\n" "#define __builtin_va_start(ap,last) (ap=((char*)&(last))+((sizeof(last)+3)&~3))\n" "#define __builtin_va_arg(ap,t) (*(t*)((ap+=(sizeof(t)+3)&~3)-((sizeof(t)+3)&~3)))\n" - "#define __builtin_va_copy(dest,src) (dest)=(src)\n" #endif "#define __builtin_va_end(ap) (void)(ap)\n" + "#ifndef __builtin_va_copy\n" + "#define __builtin_va_copy(dest,src) (dest)=(src)\n" + "#endif\n" + /* TCC BBUILTIN AND BOUNDS ALIASES */ + "#ifdef __BOUNDS_CHECKING_ON\n" + "#define __BUILTIN(ret,name,params) ret __builtin_##name params __attribute__((alias(\"__bound_\"#name)));\n" + "#define __BOUND(ret,name,params) ret name params __attribute__((alias(\"__bound_\"#name)));\n" + "#else\n" + "#define __BUILTIN(ret,name,params) ret __builtin_##name params __attribute__((alias(#name)));\n" + "#define __BOUND(ret,name,params)\n" + "#endif\n" + "#define __BOTH(ret,name,params) __BUILTIN(ret,name,params)__BOUND(ret,name,params)\n" + "__BOTH(void*,memcpy,(void*,const void*,__SIZE_TYPE__))\n" + "__BOTH(void*,memmove,(void*,const void*,__SIZE_TYPE__))\n" + "__BOTH(void*,memset,(void*,int,__SIZE_TYPE__))\n" + "__BOTH(int,memcmp,(const void*,const void*,__SIZE_TYPE__))\n" + "__BOTH(__SIZE_TYPE__,strlen,(const char*))\n" + "__BOTH(char*,strcpy,(char*,const char*))\n" + "__BOTH(char*,strncpy,(char*,const char*,__SIZE_TYPE__))\n" + "__BOTH(int,strcmp,(const char*,const char*))\n" + "__BOTH(int,strncmp,(const char*,const char*,__SIZE_TYPE__))\n" + "__BOTH(char*,strcat,(char*,const char*))\n" + "__BOTH(char*,strchr,(const char*,int))\n" + "__BOTH(char*,strdup,(const char*))\n" +#ifdef TCC_TARGET_PE + "#define __MAYBE_REDIR __BOTH\n" +#else // HAVE MALLOC_REDIR + "#define __MAYBE_REDIR __BUILTIN\n" +#endif + "__MAYBE_REDIR(void*,malloc,(__SIZE_TYPE__))\n" + "__MAYBE_REDIR(void*,realloc,(void*,__SIZE_TYPE__))\n" + "__MAYBE_REDIR(void*,calloc,(__SIZE_TYPE__,__SIZE_TYPE__))\n" + "__MAYBE_REDIR(void*,memalign,(__SIZE_TYPE__,__SIZE_TYPE__))\n" + "__MAYBE_REDIR(void,free,(void*))\n" +#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 + "__BOTH(void*,alloca,(__SIZE_TYPE__))\n" +#endif + "__BUILTIN(void,abort,(void))\n" + "__BOUND(int,longjmp,())\n" +#ifndef TCC_TARGET_PE + "__BOUND(void*,mmap,())\n" + "__BOUND(void*,munmap,())\n" +#endif + "#undef __BUILTIN\n" + "#undef __BOUND\n" + "#undef __BOTH\n" + "#undef __MAYBE_REDIR\n" , -1); } diff --git a/tcctok.h b/tcctok.h index 63b55655..1e9bc4ab 100644 --- a/tcctok.h +++ b/tcctok.h @@ -314,68 +314,13 @@ # ifdef TCC_TARGET_X86_64 DEF(TOK___bound_alloca_nr, "__bound_alloca_nr") # endif - DEF(TOK_memalign, "memalign") # else DEF(TOK_sigsetjmp, "sigsetjmp") DEF(TOK___sigsetjmp, "__sigsetjmp") DEF(TOK_siglongjmp, "siglongjmp") # endif - DEF(TOK_mmap, "mmap") - DEF(TOK_munmap, "munmap") DEF(TOK_setjmp, "setjmp") DEF(TOK__setjmp, "_setjmp") - DEF(TOK_longjmp, "longjmp") - DEF(TOK___bound_memcpy, "__bound_memcpy") - DEF(TOK___bound_memcmp, "__bound_memcmp") - DEF(TOK___bound_memmove, "__bound_memmove") - DEF(TOK___bound_memset, "__bound_memset") - DEF(TOK___bound_strlen, "__bound_strlen") - DEF(TOK___bound_strcpy, "__bound_strcpy") - DEF(TOK___bound_strncpy, "__bound_strncpy") - DEF(TOK___bound_strcmp, "__bound_strcmp") - DEF(TOK___bound_strncmp, "__bound_strncmp") - DEF(TOK___bound_strcat, "__bound_strcat") - DEF(TOK___bound_strchr, "__bound_strchr") - DEF(TOK___bound_strdup, "__bound_strdup") - DEF(TOK___bound_malloc, "__bound_malloc") - DEF(TOK___bound_free, "__bound_free") - DEF(TOK___bound_realloc, "__bound_realloc") - DEF(TOK___bound_calloc, "__bound_calloc") -#endif - DEF(TOK_abort, "abort") - DEF(TOK_memcmp, "memcmp") - DEF(TOK_strlen, "strlen") - DEF(TOK_strcpy, "strcpy") - DEF(TOK_strncpy, "strncpy") - DEF(TOK_strcmp, "strcmp") - DEF(TOK_strncmp, "strncmp") - DEF(TOK_strcat, "strcat") - DEF(TOK_strchr, "strchr") - DEF(TOK_strdup, "strdup") - DEF(TOK_malloc, "malloc") - DEF(TOK_free, "free") - DEF(TOK_realloc, "realloc") - DEF(TOK_calloc, "calloc") - - DEF(TOK___builtin_abort, "__builtin_abort") - DEF(TOK___builtin_memcpy, "__builtin_memcpy") - DEF(TOK___builtin_memcmp, "__builtin_memcmp") - DEF(TOK___builtin_memmove, "__builtin_memmove") - DEF(TOK___builtin_memset, "__builtin_memset") - DEF(TOK___builtin_strlen, "__builtin_strlen") - DEF(TOK___builtin_strcpy, "__builtin_strcpy") - DEF(TOK___builtin_strncpy, "__builtin_strncpy") - DEF(TOK___builtin_strcmp, "__builtin_strcmp") - DEF(TOK___builtin_strncmp, "__builtin_strncmp") - DEF(TOK___builtin_strcat, "__builtin_strcat") - DEF(TOK___builtin_strchr, "__builtin_strchr") - DEF(TOK___builtin_strdup, "__builtin_strdup") - DEF(TOK___builtin_malloc, "__builtin_malloc") - DEF(TOK___builtin_free, "__builtin_free") - DEF(TOK___builtin_realloc, "__builtin_realloc") - DEF(TOK___builtin_calloc, "__builtin_calloc") -#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 - DEF(TOK___builtin_alloca, "__builtin_alloca") #endif /* Tiny Assembler */ diff --git a/tests/misc/c2str.c b/tests/misc/c2str.c new file mode 100644 index 00000000..01d18db1 --- /dev/null +++ b/tests/misc/c2str.c @@ -0,0 +1,112 @@ +#include +#include + +int isid(int c) +{ + return (c >= 'a' && c <= 'z') + || (c >= 'A' && c <= 'Z') + || (c >= '0' && c <= '9') + || c == '_'; +} + +int isspc(int c) +{ + return c == ' ' || c == '\t'; +} + +int main(int argc, char **argv) +{ + char l[1000], *p, l2[1000], *q; + FILE *fp, *op; + int c, e, f; + + if (argc < 3) + return 1; + + fp = fopen(argv[1], "rb"); + op = fopen(argv[2], "wb"); + if (!fp || !op) { + fprintf(stderr, "c2str: file error\n"); + return 1; + } + + for (;;) { + p = l; + append: + if (fgets(p, sizeof l - (p - l), fp)) { + p = strchr(p, 0); + while (p > l && p[-1] == '\n') + --p; + *p = 0; + } else if (p == l) + break; + if (p > l && p[-1] == '\\') { + --p; + goto append; + } + + if (l[0] == 0) + continue; + p = l, q = l2, f = e = 0; + while (*p && isspc(*p)) + ++p, ++f; + + if (f < 4) { + do { + static const char *sr[] = { + "__x86_64__", "TCC_TARGET_X86_64", + "_WIN64", "TCC_TARGET_PE", + "_WIN32", "TCC_TARGET_PE", + "__arm__", "TCC_TARGET_ARM", + "__aarch64__", "TCC_TARGET_ARM64", + "__riscv", "TCC_TARGET_RISCV64", + "__i386__", "TCC_TARGET_I386", 0 }; + for (f = 0; sr[f]; f += 2) { + c = strlen(sr[f]); + if (0 == memcmp(p, sr[f], c)) { + p += c, ++f; + q = strchr(strcpy(q, sr[f]), 0); + break; + } + + } + if (sr[f]) + continue; + } while (!!(*q++ = *p++)); + + fprintf(op, "%s\n", l2); + + } else if (*p == '/') { + strcpy(q, p); + fprintf(op, " %s\n", l2); + + } else { + f = 0; + for (;;) { + c = *p++; + if (isspc(c)) { + if (q == l2 || isspc(q[-1])) + continue; + if ((f > 2 || e) || (q[-1] != ')' && *p != '(')) { + if (!isid(q[-1]) || !isid(*p)) + continue; + } + } + if (c == '(') + ++e, ++f; + if (c == ')') + --e, ++f; + if (c == '\\' || c == '\"') + *q++ = '\\'; + *q++ = c; + if (c == 0) + break; + } + fprintf(op, " \"%s\\n\"\n", l2); + } + } + + fclose(fp); + fclose(op); + return 0; +} diff --git a/tests/misc/tcc_predefs.h b/tests/misc/tcc_predefs.h new file mode 100644 index 00000000..bbba4254 --- /dev/null +++ b/tests/misc/tcc_predefs.h @@ -0,0 +1,111 @@ +#if defined __x86_64__ +#ifndef _WIN64 + /* GCC compatible definition of va_list. */ + /* This should be in sync with the declaration in our lib/libtcc1.c */ + typedef struct { + unsigned gp_offset, fp_offset; + union { + unsigned overflow_offset; + char *overflow_arg_area; + }; + char *reg_save_area; + } __builtin_va_list[1]; + + void *__va_arg(__builtin_va_list ap, int arg_type, int size, int align); + #define __builtin_va_start(ap, last) \ + (*(ap) = *(__builtin_va_list)((char*)__builtin_frame_address(0) - 24)) + #define __builtin_va_arg(ap, t) \ + (*(t *)(__va_arg(ap, __builtin_va_arg_types(t), sizeof(t), __alignof__(t)))) + #define __builtin_va_copy(dest, src) (*(dest) = *(src)) + +#else /* _WIN64 */ + typedef char *__builtin_va_list; + #define __builtin_va_arg(ap, t) ((sizeof(t) > 8 || (sizeof(t) & (sizeof(t) - 1))) \ + ? **(t **)((ap += 8) - 8) : *(t *)((ap += 8) - 8)) +#endif + +#elif defined __arm__ + typedef char *__builtin_va_list; + #define _tcc_alignof(type) ((int)&((struct {char c;type x;} *)0)->x) + #define _tcc_align(addr,type) (((unsigned)addr + _tcc_alignof(type) - 1) \ + & ~(_tcc_alignof(type) - 1)) + #define __builtin_va_start(ap,last) (ap = ((char *)&(last)) + ((sizeof(last)+3)&~3)) + #define __builtin_va_arg(ap,type) (ap = (void *) ((_tcc_align(ap,type)+sizeof(type)+3) \ + &~3), *(type *)(ap - ((sizeof(type)+3)&~3))) + +#elif defined __aarch64__ + typedef struct { + void *__stack, *__gr_top, *__vr_top; + int __gr_offs, __vr_offs; + } __builtin_va_list; + +#elif defined __riscv + typedef char *__builtin_va_list; + #define __va_reg_size (__riscv_xlen >> 3) + #define _tcc_align(addr,type) (((unsigned long)addr + __alignof__(type) - 1) \ + & -(__alignof__(type))) + #define __builtin_va_arg(ap,type) (*(sizeof(type) > (2*__va_reg_size) ? *(type **)((ap += __va_reg_size) - __va_reg_size) : (ap = (va_list)(_tcc_align(ap,type) + (sizeof(type)+__va_reg_size - 1)& -__va_reg_size), (type *)(ap - ((sizeof(type)+ __va_reg_size - 1)& -__va_reg_size))))) + +#else /* __i386__ */ + typedef char *__builtin_va_list; + #define __builtin_va_start(ap,last) (ap = ((char *)&(last)) + ((sizeof(last)+3)&~3)) + #define __builtin_va_arg(ap,t) (*(t*)((ap+=(sizeof(t)+3)&~3)-((sizeof(t)+3)&~3))) + +#endif + #define __builtin_va_end(ap) (void)(ap) + #ifndef __builtin_va_copy + # define __builtin_va_copy(dest, src) (dest) = (src) + #endif + + + /* TCC BBUILTIN AND BOUNDS ALIASES */ + #ifdef __BOUNDS_CHECKING_ON + # define __BUILTIN(ret,name,params) \ + ret __builtin_##name params __attribute__((alias("__bound_" #name))); + # define __BOUND(ret,name,params) \ + ret name params __attribute__((alias("__bound_" #name))); + #else + # define __BUILTIN(ret,name,params) \ + ret __builtin_##name params __attribute__((alias(#name))); + # define __BOUND(ret,name,params) + #endif + # define __BOTH(ret,name,params) \ + __BUILTIN(ret,name,params) __BOUND(ret,name,params) + + __BOTH(void*, memcpy, (void *, const void*, __SIZE_TYPE__)) + __BOTH(void*, memmove, (void *, const void*, __SIZE_TYPE__)) + __BOTH(void*, memset, (void *, int, __SIZE_TYPE__)) + __BOTH(int, memcmp, (const void *, const void*, __SIZE_TYPE__)) + __BOTH(__SIZE_TYPE__, strlen, (const char *)) + __BOTH(char*, strcpy, (char *, const char *)) + __BOTH(char*, strncpy, (char *, const char*, __SIZE_TYPE__)) + __BOTH(int, strcmp, (const char*, const char*)) + __BOTH(int, strncmp, (const char*, const char*, __SIZE_TYPE__)) + __BOTH(char*, strcat, (char*, const char*)) + __BOTH(char*, strchr, (const char*, int)) + __BOTH(char*, strdup, (const char*)) + +#ifdef _WIN32 + #define __MAYBE_REDIR __BOTH +#else // HAVE MALLOC_REDIR + #define __MAYBE_REDIR __BUILTIN +#endif + __MAYBE_REDIR(void*, malloc, (__SIZE_TYPE__)) + __MAYBE_REDIR(void*, realloc, (void *, __SIZE_TYPE__)) + __MAYBE_REDIR(void*, calloc, (__SIZE_TYPE__, __SIZE_TYPE__)) + __MAYBE_REDIR(void*, memalign, (__SIZE_TYPE__, __SIZE_TYPE__)) + __MAYBE_REDIR(void, free, (void*)) + +#if defined __i386__ || defined __x86_64__ + __BOTH(void*, alloca, (__SIZE_TYPE__)) +#endif + __BUILTIN(void, abort, (void)) + __BOUND(int, longjmp, ()) +#ifndef _WIN32 + __BOUND(void*, mmap, ()) + __BOUND(void*, munmap, ()) +#endif + #undef __BUILTIN + #undef __BOUND + #undef __BOTH + #undef __MAYBE_REDIR diff --git a/tests/tcctest.c b/tests/tcctest.c index d158950e..921b0eba 100644 --- a/tests/tcctest.c +++ b/tests/tcctest.c @@ -2,10 +2,11 @@ * TCC auto test program */ #include "config.h" + +/* identify the configured reference compiler in use */ #define CC_gcc 1 #define CC_clang 2 #define CC_tcc 3 -#define CC_msvc 4 /* cannot compile this file */ /* Unfortunately, gcc version < 3 does not handle that! */ #define ALL_ISOC99 @@ -13,15 +14,9 @@ /* only gcc 3 handles _Bool correctly */ #define BOOL_ISOC99 -/* gcc 2.95.3 does not handle correctly CR in strings or after strays */ -#define CORRECT_CR_HANDLING - /* __VA_ARGS__ and __func__ support */ #define C99_MACROS -/* deprecated and no longer supported in gcc 3.3 */ -//#define ACCEPT_CR_IN_STRINGS - #ifndef __TINYC__ typedef __SIZE_TYPE__ uintptr_t; #endif @@ -81,61 +76,6 @@ typedef __SIZE_TYPE__ uintptr_t; #include incname #include stringify(funnyname) -void intdiv_test(); -void string_test(); -void expr_test(); -void macro_test(); -void recursive_macro_test(); -void scope_test(); -void scope_test2(); -void forward_test(); -void funcptr_test(); -void if_test(); -void loop_test(); -void switch_test(); -void goto_test(); -void enum_test(); -void typedef_test(); -void struct_test(); -void array_test(); -void expr_ptr_test(); -void bool_test(); -void optimize_out(); -void expr2_test(); -void constant_expr_test(); -void expr_cmp_test(); -void char_short_test(); -void init_test(void); -void compound_literal_test(void); -int kr_test(); -void struct_assign_test(void); -void cast_test(void); -void bitfield_test(void); -void c99_bool_test(void); -void float_test(void); -void longlong_test(void); -void manyarg_test(void); -void stdarg_test(void); -void whitespace_test(void); -void relocation_test(void); -void old_style_function(void); -void alloca_test(void); -void c99_vla_test(int size1, int size2); -void sizeof_test(void); -void typeof_test(void); -void local_label_test(void); -void statement_expr_test(void); -void asm_test(void); -void builtin_test(void); -void weak_test(void); -void global_data_test(void); -void cmp_comparison_test(void); -void math_cmp_test(void); -void callsave_test(void); -void builtin_frame_address_test(void); -void attrib_test(void); -void bounds_check1_test(void); - int fib(int n); void num(int n); void forward_ref(void); @@ -146,8 +86,6 @@ int isid(int c); void funny_line_continuation (int, ..\ . ); -char via_volatile (char); - #define A 2 #define N 1234 + A #define pf printf @@ -207,74 +145,8 @@ int qq(int x) #define wq_spin_lock spin_lock #define TEST2() wq_spin_lock(a) -#define UINT_MAX ((unsigned) -1) - -void intdiv_test(void) -{ - printf("18/21=%u\n", 18/21); - printf("18%%21=%u\n", 18%21); - printf("41/21=%u\n", 41/21); - printf("41%%21=%u\n", 41%21); - printf("42/21=%u\n", 42/21); - printf("42%%21=%u\n", 42%21); - printf("43/21=%u\n", 43/21); - printf("43%%21=%u\n", 43%21); - printf("126/21=%u\n", 126/21); - printf("126%%21=%u\n", 126%21); - printf("131/21=%u\n", 131/21); - printf("131%%21=%u\n", 131%21); - printf("(UINT_MAX/2+3)/2=%u\n", (UINT_MAX/2+3)/2); - printf("(UINT_MAX/2+3)%%2=%u\n", (UINT_MAX/2+3)%2); - - printf("18/-21=%u\n", 18/-21); - printf("18%%-21=%u\n", 18%-21); - printf("41/-21=%u\n", 41/-21); - printf("41%%-21=%u\n", 41%-21); - printf("42/-21=%u\n", 42/-21); - printf("42%%-21=%u\n", 42%-21); - printf("43/-21=%u\n", 43/-21); - printf("43%%-21=%u\n", 43%-21); - printf("126/-21=%u\n", 126/-21); - printf("126%%-21=%u\n", 126%-21); - printf("131/-21=%u\n", 131/-21); - printf("131%%-21=%u\n", 131%-21); - printf("(UINT_MAX/2+3)/-2=%u\n", (UINT_MAX/2+3)/-2); - printf("(UINT_MAX/2+3)%%-2=%u\n", (UINT_MAX/2+3)%-2); - - printf("-18/21=%u\n", -18/21); - printf("-18%%21=%u\n", -18%21); - printf("-41/21=%u\n", -41/21); - printf("-41%%21=%u\n", -41%21); - printf("-42/21=%u\n", -42/21); - printf("-42%%21=%u\n", -42%21); - printf("-43/21=%u\n", -43/21); - printf("-43%%21=%u\n", -43%21); - printf("-126/21=%u\n", -126/21); - printf("-126%%21=%u\n", -126%21); - printf("-131/21=%u\n", -131/21); - printf("-131%%21=%u\n", -131%21); - printf("-(UINT_MAX/2+3)/2=%u\n", (0-(UINT_MAX/2+3))/2); - printf("-(UINT_MAX/2+3)%%2=%u\n", (0-(UINT_MAX/2+3))%2); - - printf("-18/-21=%u\n", -18/-21); - printf("-18%%-21=%u\n", -18%-21); - printf("-41/-21=%u\n", -41/-21); - printf("-41%%-21=%u\n", -41%-21); - printf("-42/-21=%u\n", -42/-21); - printf("-42%%-21=%u\n", -42%-21); - printf("-43/-21=%u\n", -43/-21); - printf("-43%%-21=%u\n", -43%-21); - printf("-126/-21=%u\n", -126/-21); - printf("-126%%-21=%u\n", -126%-21); - printf("-131/-21=%u\n", -131/-21); - printf("-131%%-21=%u\n", -131%-21); - printf("-(UINT_MAX/2+3)/-2=%u\n", (0-(UINT_MAX/2+3))/-2); - printf("-(UINT_MAX/2+3)%%-2=%u\n", (0-(UINT_MAX/2+3))%-2); -} - void macro_test(void) { - printf("macro:\n"); pf("N=%d\n", N); printf("aaa=%d\n", AAA); @@ -349,22 +221,6 @@ void macro_test(void) MACRO_NOARGS(); -#ifdef __LINE__ - printf("__LINE__ defined\n"); -#endif - - printf("__LINE__=%d __FILE__=%s\n", - __LINE__, __FILE__); -#if 0 -#line 200 - printf("__LINE__=%d __FILE__=%s\n", - __LINE__, __FILE__); -#line 203 "test" - printf("__LINE__=%d __FILE__=%s\n", - __LINE__, __FILE__); -#line 227 "tcctest.c" -#endif - /* not strictly preprocessor, but we test it there */ #ifdef C99_MACROS printf("__func__ = %s\n", __func__); @@ -677,7 +533,7 @@ void goto_test() int i; static void *label_table[3] = { &&label1, &&label2, &&label3 }; - printf("goto:\n"); + printf("\ngoto:\n"); i = 0; /* This needs to parse as label, not as start of decl. */ typedef_and_label x; @@ -745,8 +601,7 @@ void enum_test() /* The following should give no warning */ unsigned *p = &b1; struct S_enum s = {E7}; - printf("enum: %d\n", s.e); - printf("enum:\n%d %d %d %d %d %d\n", + printf("%d %d %d %d %d %d %d\n", s.e, E0, E1, E2, E3, E4, E5); b1 = 1; printf("b1=%d\n", b1); @@ -775,7 +630,6 @@ void typedef_test() a = &b; *a = 1234; - printf("typedef:\n"); printf("a=%d\n", *a); mytype2 = 2; printf("mytype2=%d\n", mytype2); @@ -783,7 +637,6 @@ void typedef_test() void forward_test() { - printf("forward:\n"); forward_ref(); forward_ref(); } @@ -821,69 +674,6 @@ struct empty_mem { int x; }; -int main(int argc, char **argv) -{ - string_test(); - expr_test(); - macro_test(); - recursive_macro_test(); - scope_test(); - scope_test2(); - forward_test(); - funcptr_test(); - if_test(); - loop_test(); - switch_test(); - goto_test(); - enum_test(); - typedef_test(); - struct_test(); - array_test(); - expr_ptr_test(); - bool_test(); - optimize_out(); - expr2_test(); - constant_expr_test(); - expr_cmp_test(); - char_short_test(); - init_test(); - compound_literal_test(); - kr_test(); - struct_assign_test(); - cast_test(); - bitfield_test(); - c99_bool_test(); - float_test(); - longlong_test(); - manyarg_test(); - stdarg_test(); - whitespace_test(); - relocation_test(); - old_style_function(); - alloca_test(); - c99_vla_test(5, 2); - sizeof_test(); - typeof_test(); - statement_expr_test(); - local_label_test(); - asm_test(); - builtin_test(); -#ifndef _WIN32 - weak_test(); -#endif - global_data_test(); - cmp_comparison_test(); - math_cmp_test(); - callsave_test(); - builtin_frame_address_test(); - intdiv_test(); - if (via_volatile (42) != 42) - printf ("via_volatile broken\n"); - attrib_test(); - bounds_check1_test(); - return 0; -} - int tab[3]; int tab2[3][2]; @@ -896,7 +686,6 @@ void f1(g) void scope_test() { - printf("scope:\n"); g = 2; f1(1); printf("g2=%d\n", g); @@ -915,7 +704,7 @@ void scope_test() int st2_i; int *st2_p = &st2_i; -void scope_test2() +void scope2_test() { char a[50]; st2_i = 42; @@ -941,7 +730,6 @@ void array_test() { int i, j, a[4]; - printf("array:\n"); printf("sizeof(a) = %d\n", sizeof(a)); printf("sizeof(\"a\") = %d\n", sizeof("a")); #ifdef C99_MACROS @@ -1046,7 +834,6 @@ void expr2_test() { int a, b; - printf("expr2:\n"); vstack_ptr = vstack; vpush(1432432, 2); vstack_ptr[-2] &= ~0xffffff80; @@ -1059,7 +846,6 @@ int const_len_ar[sizeof(1/0)]; /* div-by-zero, but in unevaluated context */ void constant_expr_test() { int a; - printf("constant_expr:\n"); a = 3; printf("%d\n", a * 16); printf("%d\n", a * 1); @@ -1074,7 +860,6 @@ void expr_ptr_test() int *p, *q; int i = -1; - printf("expr_ptr:\n"); p = tab4; q = tab4 + 10; printf("diff=%d\n", q - p); @@ -1130,7 +915,6 @@ void expr_ptr_test() void expr_cmp_test() { int a, b; - printf("constant_expr:\n"); a = -1; b = 1; printf("%d\n", a == a); @@ -1250,7 +1034,6 @@ void struct_test() union union2 u; struct Large ls; - printf("struct:\n"); printf("sizes: %d %d %d %d\n", sizeof(struct struct1), sizeof(struct struct2), @@ -1326,8 +1109,6 @@ void char_short_test() signed char var3; long long var4; - printf("char_short:\n"); - var1 = 0x01020304; var2 = 0xfffefdfc; printf("s8=%d %d\n", @@ -1495,7 +1276,7 @@ static inline void refer_to_undefined(void) undefined_function(); } -void optimize_out(void) +void optimize_out_test(void) { int i = 0 ? undefined_function() : defined_function(); printf ("oo:%d\n", i); @@ -1636,8 +1417,6 @@ void compound_literal_test(void) int *p, i; char *q, *q3; - printf("compound_test:\n"); - p = (int []){1, 2, 3}; for(i=0;i<3;i++) printf(" %d", p[i]); @@ -1689,7 +1468,6 @@ int kr_func2(a, b) kr_test() { - printf("kr_test:\n"); printf("func1=%d\n", kr_func1(3, 4)); printf("func2=%d\n", kr_func2(3, 4)); return 0; @@ -1745,8 +1523,6 @@ void struct_assign_test(void) ps = &s; ps->i = 4; #if 0 - printf("struct_assign_test:\n"); - s.lsta1.f1 = 1; s.lsta1.f2 = 2; printf("%d %d\n", s.lsta1.f1, s.lsta1.f2); @@ -1792,7 +1568,6 @@ void cast_test() unsigned long ul = 0x80000000UL; p -= 0x700000000042; - printf("cast_test:\n"); a = 0xfffff; cast1(a, a, a, a); a = 0xffffe; @@ -1833,7 +1608,7 @@ void cast_test() printf("sizeof(-(char)'a') = %d\n", sizeof(-(char)'a')); printf("sizeof(~(char)'a') = %d\n", sizeof(-(char)'a')); -#if CC_NAME != CC_clang /* doesn't like non-portable conversions */ +#if CC_NAME != CC_clang /* clang doesn't support non-portable conversions */ /* from pointer to integer types */ printf("%d %d %ld %ld %lld %lld\n", (int)p, (unsigned int)p, @@ -1972,8 +1747,6 @@ void init_test(void) /* Addresses on non-weak symbols are non-zero, but not the access itself */ int linit18[2] = {&zero ? 1 : -1, zero ? -1 : 1 }; - printf("init_test:\n"); - printf("sinit1=%d\n", sinit1); printf("sinit2=%d\n", sinit2); printf("sinit3=%d %d %d %d\n", @@ -2194,7 +1967,6 @@ void c99_bool_test(void) int a; _Bool b, b2; - printf("bool_test:\n"); printf("sizeof(_Bool) = %d\n", sizeof(_Bool)); a = 3; printf("cast: %d %d %d\n", (_Bool)10, (_Bool)0, (_Bool)a); @@ -2222,7 +1994,6 @@ void bitfield_test(void) int f4 : 7; unsigned int f5 : 7; } st1; - printf("bitfield_test:"); printf("sizeof(st1) = %d\n", sizeof(st1)); st1.f1 = 3; @@ -2442,7 +2213,6 @@ void float_test(void) static double inf1 = 1.0/0.0; static double inf2 = 1e5000; - printf("float_test:\n"); printf("sizeof(float) = %d\n", sizeof(float)); printf("sizeof(double) = %d\n", sizeof(double)); printf("sizeof(long double) = %d\n", sizeof(LONG_DOUBLE)); @@ -2490,7 +2260,6 @@ void funcptr_test() } st1; long diff; - printf("funcptr:\n"); func = # (*func)(12345); func = num; @@ -2648,7 +2417,6 @@ void longlong_test(void) long long a, b, c; int ia; unsigned int ua; - printf("longlong_test:\n"); printf("sizeof(long long) = %d\n", sizeof(long long)); ia = -1; ua = -2; @@ -2728,7 +2496,6 @@ void longlong_test(void) void manyarg_test(void) { LONG_DOUBLE ld = 1234567891234LL; - printf("manyarg_test:\n"); printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f\n", 1, 2, 3, 4, 5, 6, 7, 8, 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0); @@ -2912,38 +2679,6 @@ void stdarg_test(void) stdarg_syntax(1, 17); } -void whitespace_test(void) -{ - char *str; - - #if 1 - pri\ -ntf("whitspace:\n"); -#endif - pf("N=%d\n", 2); - -#ifdef CORRECT_CR_HANDLING - pri\ -ntf("aaa=%d\n", 3); -#endif - - pri\ -\ -ntf("min=%d\n", 4); - -#ifdef ACCEPT_CR_IN_STRINGS - printf("len1=%d\n", strlen(" -")); -#ifdef CORRECT_CR_HANDLING - str = " -"; - printf("len1=%d str[0]=%d\n", strlen(str), str[0]); -#endif - printf("len1=%d\n", strlen(" a -")); -#endif /* ACCEPT_CR_IN_STRINGS */ -} - int reltab[3] = { 1, 2, 3 }; int *rel1 = &reltab[1]; @@ -3000,7 +2735,7 @@ int cmpfn(); printf("cmpfn=%lx\n", (long)cmpfn); } -void old_style_function(void) +void old_style_function_test(void) { old_style_f((void *)1, 2, 3.0); decl_func1(NULL); @@ -3027,7 +2762,7 @@ void *bounds_checking_is_enabled() typedef int constant_negative_array_size_as_compile_time_assertion_idiom[(1 ? 2 : 0) - 1]; -void c99_vla_test(int size1, int size2) +void c99_vla_test_1(int size1, int size2) { #if defined __i386__ || defined __x86_64__ int size = size1 * size2; @@ -3078,6 +2813,12 @@ void c99_vla_test(int size1, int size2) #endif } +void c99_vla_test(void) +{ + c99_vla_test_1(5, 2); +} + + void sizeof_test(void) { int a; @@ -3750,8 +3491,6 @@ void asm_test(void) #endif register int regvar asm("%esi"); - printf("inline asm:\n"); - // parse 0x1E-1 as 3 tokens in asm mode asm volatile ("mov $0x1E-1,%eax"); @@ -3902,7 +3641,9 @@ void builtin_test(void) //printf("bera: %p\n", __builtin_extract_return_addr((void*)43)); } -#ifndef _WIN32 +#ifdef _WIN32 +void weak_test(void) {} +#else extern int __attribute__((weak)) weak_f1(void); extern int __attribute__((weak)) weak_f2(void); extern int weak_f3(void); @@ -4170,6 +3911,14 @@ char via_volatile (char i) return vi; } +void volatile_test(void) +{ + if (via_volatile (42) != 42) + printf (" broken\n"); + else + printf (" ok\n"); +} + struct __attribute__((__packed__)) Spacked { char a; short b; @@ -4250,3 +3999,122 @@ void bounds_check1_test (void) pv(x); pv(y); } + +/* gcc 2.95.3 does not handle correctly CR in strings or after strays */ +#define CORRECT_CR_HANDLING + +/* deprecated and no longer supported in gcc 3.3 */ +#ifdef __TINYC__ +# define ACCEPT_CR_IN_STRINGS +#endif + +/* keep this as the last test because GCC messes up line-numbers + with the ^L^K^M characters below */ +void whitespace_test(void) +{ + char *str; + + #if 1 + pri\ +ntf("whitspace:\n"); +#endif + pf("N=%d\n", 2); + +#ifdef CORRECT_CR_HANDLING + pri\ +ntf("aaa=%d\n", 3); +#endif + + pri\ +\ +ntf("min=%d\n", 4); + +#ifdef ACCEPT_CR_IN_STRINGS + printf("len1=%d\n", strlen(" +")); +#ifdef CORRECT_CR_HANDLING + str = " +"; + printf("len1=%d str[0]=%d\n", strlen(str), str[0]); +#endif + printf("len1=%d\n", strlen(" a +")); +#else + printf("len1=1\nlen1=1 str[0]=10\nlen1=3\n"); +#endif /* ACCEPT_CR_IN_STRINGS */ + +#ifdef __LINE__ + printf("__LINE__ defined\n"); +#endif + +#if 0 + /* wrong with GCC */ + printf("__LINE__=%d __FILE__=%s\n", __LINE__, __FILE__); +#line 1111 + printf("__LINE__=%d __FILE__=%s\n", __LINE__, __FILE__); +#line 2222 "test" + printf("__LINE__=%d __FILE__=%s\n", __LINE__, __FILE__); +#endif +} + +#define RUN(test) puts("---- " #test " ----"), test(), puts("") + +int main(int argc, char **argv) +{ + RUN(whitespace_test); + RUN(macro_test); + RUN(recursive_macro_test); + RUN(string_test); + RUN(expr_test); + RUN(scope_test); + RUN(scope2_test); + RUN(forward_test); + RUN(funcptr_test); + RUN(if_test); + RUN(loop_test); + RUN(switch_test); + RUN(goto_test); + RUN(enum_test); + RUN(typedef_test); + RUN(struct_test); + RUN(array_test); + RUN(expr_ptr_test); + RUN(bool_test); + RUN(optimize_out_test); + RUN(expr2_test); + RUN(constant_expr_test); + RUN(expr_cmp_test); + RUN(char_short_test); + RUN(init_test); + RUN(compound_literal_test); + RUN(kr_test); + RUN(struct_assign_test); + RUN(cast_test); + RUN(bitfield_test); + RUN(c99_bool_test); + RUN(float_test); + RUN(longlong_test); + RUN(manyarg_test); + RUN(stdarg_test); + RUN(relocation_test); + RUN(old_style_function_test); + RUN(alloca_test); + RUN(c99_vla_test); + RUN(sizeof_test); + RUN(typeof_test); + RUN(statement_expr_test); + RUN(local_label_test); + RUN(asm_test); + RUN(builtin_test); + RUN(weak_test); + RUN(global_data_test); + RUN(cmp_comparison_test); + RUN(math_cmp_test); + RUN(callsave_test); + RUN(builtin_frame_address_test); + RUN(volatile_test); + RUN(attrib_test); + RUN(bounds_check1_test); + + return 0; +} diff --git a/tests/tests2/61_integers.c b/tests/tests2/61_integers.c new file mode 100644 index 00000000..de29b3ce --- /dev/null +++ b/tests/tests2/61_integers.c @@ -0,0 +1,70 @@ +#include + +/* This was first introduced to test the ARM port */ + +#define UINT_MAX ((unsigned) -1) + +int main() +{ + printf("18/21=%u\n", 18/21); + printf("18%%21=%u\n", 18%21); + printf("41/21=%u\n", 41/21); + printf("41%%21=%u\n", 41%21); + printf("42/21=%u\n", 42/21); + printf("42%%21=%u\n", 42%21); + printf("43/21=%u\n", 43/21); + printf("43%%21=%u\n", 43%21); + printf("126/21=%u\n", 126/21); + printf("126%%21=%u\n", 126%21); + printf("131/21=%u\n", 131/21); + printf("131%%21=%u\n", 131%21); + printf("(UINT_MAX/2+3)/2=%u\n", (UINT_MAX/2+3)/2); + printf("(UINT_MAX/2+3)%%2=%u\n", (UINT_MAX/2+3)%2); + + printf("18/-21=%u\n", 18/-21); + printf("18%%-21=%u\n", 18%-21); + printf("41/-21=%u\n", 41/-21); + printf("41%%-21=%u\n", 41%-21); + printf("42/-21=%u\n", 42/-21); + printf("42%%-21=%u\n", 42%-21); + printf("43/-21=%u\n", 43/-21); + printf("43%%-21=%u\n", 43%-21); + printf("126/-21=%u\n", 126/-21); + printf("126%%-21=%u\n", 126%-21); + printf("131/-21=%u\n", 131/-21); + printf("131%%-21=%u\n", 131%-21); + printf("(UINT_MAX/2+3)/-2=%u\n", (UINT_MAX/2+3)/-2); + printf("(UINT_MAX/2+3)%%-2=%u\n", (UINT_MAX/2+3)%-2); + + printf("-18/21=%u\n", -18/21); + printf("-18%%21=%u\n", -18%21); + printf("-41/21=%u\n", -41/21); + printf("-41%%21=%u\n", -41%21); + printf("-42/21=%u\n", -42/21); + printf("-42%%21=%u\n", -42%21); + printf("-43/21=%u\n", -43/21); + printf("-43%%21=%u\n", -43%21); + printf("-126/21=%u\n", -126/21); + printf("-126%%21=%u\n", -126%21); + printf("-131/21=%u\n", -131/21); + printf("-131%%21=%u\n", -131%21); + printf("-(UINT_MAX/2+3)/2=%u\n", (0-(UINT_MAX/2+3))/2); + printf("-(UINT_MAX/2+3)%%2=%u\n", (0-(UINT_MAX/2+3))%2); + + printf("-18/-21=%u\n", -18/-21); + printf("-18%%-21=%u\n", -18%-21); + printf("-41/-21=%u\n", -41/-21); + printf("-41%%-21=%u\n", -41%-21); + printf("-42/-21=%u\n", -42/-21); + printf("-42%%-21=%u\n", -42%-21); + printf("-43/-21=%u\n", -43/-21); + printf("-43%%-21=%u\n", -43%-21); + printf("-126/-21=%u\n", -126/-21); + printf("-126%%-21=%u\n", -126%-21); + printf("-131/-21=%u\n", -131/-21); + printf("-131%%-21=%u\n", -131%-21); + printf("-(UINT_MAX/2+3)/-2=%u\n", (0-(UINT_MAX/2+3))/-2); + printf("-(UINT_MAX/2+3)%%-2=%u\n", (0-(UINT_MAX/2+3))%-2); + + return 0; +} diff --git a/tests/tests2/61_integers.expect b/tests/tests2/61_integers.expect new file mode 100644 index 00000000..22c8d1b9 --- /dev/null +++ b/tests/tests2/61_integers.expect @@ -0,0 +1,56 @@ +18/21=0 +18%21=18 +41/21=1 +41%21=20 +42/21=2 +42%21=0 +43/21=2 +43%21=1 +126/21=6 +126%21=0 +131/21=6 +131%21=5 +(UINT_MAX/2+3)/2=1073741825 +(UINT_MAX/2+3)%2=0 +18/-21=0 +18%-21=18 +41/-21=4294967295 +41%-21=20 +42/-21=4294967294 +42%-21=0 +43/-21=4294967294 +43%-21=1 +126/-21=4294967290 +126%-21=0 +131/-21=4294967290 +131%-21=5 +(UINT_MAX/2+3)/-2=0 +(UINT_MAX/2+3)%-2=2147483650 +-18/21=0 +-18%21=4294967278 +-41/21=4294967295 +-41%21=4294967276 +-42/21=4294967294 +-42%21=0 +-43/21=4294967294 +-43%21=4294967295 +-126/21=4294967290 +-126%21=0 +-131/21=4294967290 +-131%21=4294967291 +-(UINT_MAX/2+3)/2=1073741823 +-(UINT_MAX/2+3)%2=0 +-18/-21=0 +-18%-21=4294967278 +-41/-21=1 +-41%-21=4294967276 +-42/-21=2 +-42%-21=0 +-43/-21=2 +-43%-21=4294967295 +-126/-21=6 +-126%-21=0 +-131/-21=6 +-131%-21=4294967291 +-(UINT_MAX/2+3)/-2=0 +-(UINT_MAX/2+3)%-2=2147483646 diff --git a/x86_64-gen.c b/x86_64-gen.c index ee0b18e6..208669f1 100644 --- a/x86_64-gen.c +++ b/x86_64-gen.c @@ -149,7 +149,7 @@ static int func_ret_sub; #if defined(CONFIG_TCC_BCHECK) static addr_t func_bound_offset; static unsigned long func_bound_ind; -static int func_bound_add_epilog; +ST_DATA int func_bound_add_epilog; #endif #ifdef TCC_TARGET_PE @@ -639,18 +639,6 @@ static void gcall_or_jmp(int is_jmp) greloca(cur_text_section, vtop->sym, ind + 1, R_X86_64_PLT32, (int)(vtop->c.i-4)); #endif oad(0xe8 + is_jmp, 0); /* call/jmp im */ -#ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check && - (vtop->sym->v == TOK_alloca || - vtop->sym->v == TOK_setjmp || - vtop->sym->v == TOK__setjmp -#ifndef TCC_TARGET_PE - || vtop->sym->v == TOK_sigsetjmp - || vtop->sym->v == TOK___sigsetjmp -#endif - )) - func_bound_add_epilog = 1; -#endif } else { /* otherwise, indirect call */ r = TREG_R11;