From a01d83d78380e84b04d62ca34a142a7e3d8e390d Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Mon, 6 Jan 2014 11:09:06 +0800 Subject: Don't enable bound check if libgcc is used Bound check rely on some functions provided by libtcc. It should therefore not be enabled when libgcc is used. --- tcc-doc.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tcc-doc.texi') diff --git a/tcc-doc.texi b/tcc-doc.texi index dbfbb4a..fbb0220 100644 --- a/tcc-doc.texi +++ b/tcc-doc.texi @@ -338,7 +338,7 @@ Generate additional support code to check memory allocations and array/pointer bounds. @option{-g} is implied. Note that the generated code is slower and bigger in this case. -Note: @option{-b} is only available on i386 for the moment. +Note: @option{-b} is only available on i386 when using libtcc for the moment. @item -bt N Display N callers in stack traces. This is useful with @option{-g} or -- cgit v1.3.1 From 58f3b7781b899c26d181003c7a5f15a067ebcf8d Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Tue, 7 Jan 2014 17:50:08 +0800 Subject: Don't say compiler flags are warning options --- tcc-doc.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tcc-doc.texi') diff --git a/tcc-doc.texi b/tcc-doc.texi index fbb0220..540b4b6 100644 --- a/tcc-doc.texi +++ b/tcc-doc.texi @@ -217,7 +217,7 @@ Undefine preprocessor symbol @samp{sym}. Compilation flags: -Note: each of the following warning options has a negative form beginning with +Note: each of the following options has a negative form beginning with @option{-fno-}. @table @option -- cgit v1.3.1 From b6247d1f3c34e93e8603fddf5fc6da8dc6b81d00 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Tue, 7 Jan 2014 15:23:54 +0800 Subject: Add support for runtime selection of float ABI --- Changelog | 1 + arm-gen.c | 131 ++++++++++++++++++++++++++++++++--------------------------- libtcc.c | 23 ++++++++++- tcc-doc.texi | 3 ++ tcc.c | 2 +- tcc.h | 21 +++++++--- tccelf.c | 2 +- 7 files changed, 113 insertions(+), 70 deletions(-) (limited to 'tcc-doc.texi') diff --git a/Changelog b/Changelog index 52f8a10..9a497cf 100644 --- a/Changelog +++ b/Changelog @@ -18,6 +18,7 @@ Features: - improved variable length array support (James Lyon) - add the possibility to use noname functions by ordinal (YX Hao) - add a install-strip target to install tcc (Thomas Preud'homme) +- add runtime selection of float ABI on ARM (Thomas Preud'homme) Platforms: - support Debian GNU/kfreeBSD 64bit userspace (Thomas Preud'homme) diff --git a/arm-gen.c b/arm-gen.c index 05bccb0..bc24f70 100644 --- a/arm-gen.c +++ b/arm-gen.c @@ -141,6 +141,13 @@ enum { #define ELF_START_ADDR 0x00008000 #define ELF_PAGE_SIZE 0x1000 +enum float_abi { + ARM_SOFTFP_FLOAT, + ARM_HARD_FLOAT, +}; + +enum float_abi float_abi; + /******************************************************/ #else /* ! TARGET_DEFS_ONLY */ /******************************************************/ @@ -169,7 +176,7 @@ static int leaffunc; #if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP) static CType float_type, double_type, func_float_type, func_double_type; -ST_FUNC void arm_init_types(void) +ST_FUNC void arm_init(struct TCCState *s) { float_type.t = VT_FLOAT; double_type.t = VT_DOUBLE; @@ -177,12 +184,14 @@ ST_FUNC void arm_init_types(void) func_float_type.ref = sym_push(SYM_FIELD, &float_type, FUNC_CDECL, FUNC_OLD); func_double_type.t = VT_FUNC; func_double_type.ref = sym_push(SYM_FIELD, &double_type, FUNC_CDECL, FUNC_OLD); + + float_abi = s->float_abi; } #else #define func_float_type func_old_type #define func_double_type func_old_type #define func_ldouble_type func_old_type -ST_FUNC void arm_init_types(void) {} +ST_FUNC void arm_init(void) {} #endif static int two2mask(int a,int b) { @@ -195,6 +204,16 @@ static int regmask(int r) { /******************************************************/ +#ifdef TCC_ARM_EABI +char *default_elfinterp(struct TCCState *s) +{ + if (s->float_abi == ARM_HARD_FLOAT) + return "/lib/ld-linux-armhf.so.3"; + else + return "/lib/ld-linux.so.3"; +} +#endif + void o(uint32_t i) { /* this is a good place to start adding big-endian support*/ @@ -841,22 +860,19 @@ ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align) { #ifdef TCC_ARM_EABI int size, align; size = type_size(vt, &align); -#ifdef TCC_ARM_HARDFLOAT - if (!variadic && (is_float(vt->t) || is_hgen_float_aggr(vt))) { + if (float_abi == ARM_HARD_FLOAT && !variadic && + (is_float(vt->t) || is_hgen_float_aggr(vt))) { *ret_align = 8; ret->ref = NULL; ret->t = VT_DOUBLE; return (size + 7) >> 3; - } else -#endif - if (size > 4) { - return 0; - } else { + } else if (size <= 4) { *ret_align = 4; ret->ref = NULL; ret->t = VT_INT; return 1; - } + } else + return 0; #else return 0; #endif @@ -1171,9 +1187,11 @@ void gfunc_call(int nb_args) int todo; struct plan plan; -#ifdef TCC_ARM_HARDFLOAT - variadic = (vtop[-nb_args].type.ref->c == FUNC_ELLIPSIS); - corefloat = variadic || floats_in_core_regs(&vtop[-nb_args]); +#ifdef TCC_ARM_EABI + if (float_abi == ARM_HARD_FLOAT) { + variadic = (vtop[-nb_args].type.ref->c == FUNC_ELLIPSIS); + corefloat = variadic || floats_in_core_regs(&vtop[-nb_args]); + } #endif /* cannot let cpu flags if other instruction are generated. Also avoid leaving VT_JMP anywhere except on the top of the stack because it would complicate @@ -1199,9 +1217,9 @@ void gfunc_call(int nb_args) gcall_or_jmp(0); if (args_size) gadd_sp(args_size); /* pop all parameters passed on the stack */ -#ifdef TCC_ARM_EABI -#ifdef TCC_ARM_VFP - if(corefloat && is_float(vtop->type.ref->type.t)) { +#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP) + if(float_abi == ARM_SOFTFP_FLOAT && corefloat && + is_float(vtop->type.ref->type.t)) { if((vtop->type.ref->type.t & VT_BTYPE) == VT_FLOAT) { o(0xEE000A10); /*vmov s0, r0 */ } else { @@ -1209,7 +1227,6 @@ void gfunc_call(int nb_args) o(0xEE201B10); /* vmov.32 d0[1], r1 */ } } -#endif #endif vtop -= nb_args + 1; /* Pop all params and fct address from value stack */ leaffunc = 0; /* we are calling a function, so we aren't in a leaf function */ @@ -1220,9 +1237,8 @@ void gfunc_prolog(CType *func_type) { Sym *sym,*sym2; int n, nf, size, align, struct_ret = 0; -#ifdef TCC_ARM_HARDFLOAT + int addr, pn, sn; /* pn=core, sn=stack */ struct avail_regs avregs = AVAIL_REGS_INITIALIZER; -#endif CType ret_type; sym = func_type->ref; @@ -1237,11 +1253,11 @@ void gfunc_prolog(CType *func_type) struct_ret = 1; func_vc = 12; /* Offset from fp of the place to store the result */ } - for(sym2=sym->next;sym2 && (n<4 || nf<16);sym2=sym2->next) { + for(sym2 = sym->next; sym2 && (n < 4 || nf < 16); sym2 = sym2->next) { size = type_size(&sym2->type, &align); -#ifdef TCC_ARM_HARDFLOAT - if (!func_var && (is_float(sym2->type.t) - || is_hgen_float_aggr(&sym2->type))) { +#ifdef TCC_ARM_EABI + if (float_abi == ARM_HARD_FLOAT && !func_var && + (is_float(sym2->type.t) || is_hgen_float_aggr(&sym2->type))) { int tmpnf = assign_vfpreg(&avregs, align, size); tmpnf += (size + 3) / 4; nf = (tmpnf > nf) ? tmpnf : nf; @@ -1270,50 +1286,49 @@ void gfunc_prolog(CType *func_type) o(0xE92D5800); /* save fp, ip, lr */ o(0xE1A0B00D); /* mov fp, sp */ func_sub_sp_offset = ind; - o(0xE1A00000); /* nop, leave space for stack adjustment in epilogue */ - { - int addr, pn = struct_ret, sn = 0; /* pn=core, sn=stack */ + o(0xE1A00000); /* nop, leave space for stack adjustment in epilog */ -#ifdef TCC_ARM_HARDFLOAT +#ifdef TCC_ARM_EABI + if (float_abi == ARM_HARD_FLOAT) { func_vc += nf * 4; avregs = AVAIL_REGS_INITIALIZER; + } #endif - while ((sym = sym->next)) { - CType *type; - type = &sym->type; - size = type_size(type, &align); - size = (size + 3) >> 2; - align = (align + 3) & ~3; -#ifdef TCC_ARM_HARDFLOAT - if (!func_var && (is_float(sym->type.t) - || is_hgen_float_aggr(&sym->type))) { - int fpn = assign_vfpreg(&avregs, align, size << 2); - if (fpn >= 0) { - addr = fpn * 4; - } else - goto from_stack; - } else + pn = struct_ret, sn = 0; + while ((sym = sym->next)) { + CType *type; + type = &sym->type; + size = type_size(type, &align); + size = (size + 3) >> 2; + align = (align + 3) & ~3; +#ifdef TCC_ARM_EABI + if (float_abi == ARM_HARD_FLOAT && !func_var && (is_float(sym->type.t) + || is_hgen_float_aggr(&sym->type))) { + int fpn = assign_vfpreg(&avregs, align, size << 2); + if (fpn >= 0) + addr = fpn * 4; + else + goto from_stack; + } else #endif - if (pn < 4) { + if (pn < 4) { #ifdef TCC_ARM_EABI pn = (pn + (align-1)/4) & -(align/4); #endif - addr = (nf + pn) * 4; - pn += size; - if (!sn && pn > 4) - sn = (pn - 4); - } else { -#ifdef TCC_ARM_HARDFLOAT + addr = (nf + pn) * 4; + pn += size; + if (!sn && pn > 4) + sn = (pn - 4); + } else { from_stack: -#endif #ifdef TCC_ARM_EABI sn = (sn + (align-1)/4) & -(align/4); #endif - addr = (n + nf + sn) * 4; - sn += size; - } - sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | lvalue_type(type->t), addr+12); + addr = (n + nf + sn) * 4; + sn += size; } + sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | lvalue_type(type->t), + addr + 12); } last_itod_magic=0; leaffunc = 1; @@ -1327,12 +1342,8 @@ void gfunc_epilog(void) int diff; /* Copy float return value to core register if base standard is used and float computation is made with VFP */ -#ifdef TCC_ARM_EABI - if ( -#ifdef TCC_ARM_HARDFLOAT - func_var && -#endif - is_float(func_vt.t)) { +#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP) + if ((float_abi == ARM_SOFTFP_FLOAT || func_var) && is_float(func_vt.t)) { if((func_vt.t & VT_BTYPE) == VT_FLOAT) o(0xEE100A10); /* fmrs r0, s0 */ else { diff --git a/libtcc.c b/libtcc.c index 154a266..127806f 100644 --- a/libtcc.c +++ b/libtcc.c @@ -757,7 +757,7 @@ static int tcc_compile(TCCState *s1) func_old_type.t = VT_FUNC; func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD); #ifdef TCC_TARGET_ARM - arm_init_types(); + arm_init(s1); #endif #if 0 @@ -945,9 +945,12 @@ LIBTCCAPI TCCState *tcc_new(void) tcc_define_symbol(s, "__ARMEL__", NULL); #if defined(TCC_ARM_EABI) tcc_define_symbol(s, "__ARM_EABI__", NULL); +#endif #if defined(TCC_ARM_HARDFLOAT) + s->float_abi = ARM_HARD_FLOAT; tcc_define_symbol(s, "__ARM_PCS_VFP", NULL); -#endif +#else + s->float_abi = ARM_SOFTFP_FLOAT; #endif #endif @@ -1628,6 +1631,7 @@ enum { TCC_OPTION_b, TCC_OPTION_g, TCC_OPTION_c, + TCC_OPTION_float_abi, TCC_OPTION_static, TCC_OPTION_shared, TCC_OPTION_soname, @@ -1680,6 +1684,9 @@ static const TCCOption tcc_options[] = { #endif { "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, { "c", TCC_OPTION_c, 0 }, +#ifdef TCC_TARGET_ARM + { "mfloat-abi", TCC_OPTION_float_abi, TCC_OPTION_HAS_ARG }, +#endif { "static", TCC_OPTION_static, 0 }, { "shared", TCC_OPTION_shared, 0 }, { "soname", TCC_OPTION_soname, TCC_OPTION_HAS_ARG }, @@ -1817,6 +1824,18 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) case TCC_OPTION_c: s->output_type = TCC_OUTPUT_OBJ; break; +#ifdef TCC_TARGET_ARM + case TCC_OPTION_float_abi: + /* tcc doesn't support soft float yet */ + if (!strcmp(optarg, "softfp")) { + s->float_abi = ARM_SOFTFP_FLOAT; + tcc_undefine_symbol(s, "__ARM_PCS_VFP"); + } else if (!strcmp(optarg, "hard")) + s->float_abi = ARM_HARD_FLOAT; + else + tcc_error("unsupported float abi '%s'", optarg); + break; +#endif case TCC_OPTION_static: s->static_link = 1; break; diff --git a/tcc-doc.texi b/tcc-doc.texi index 540b4b6..e8832f6 100644 --- a/tcc-doc.texi +++ b/tcc-doc.texi @@ -176,6 +176,9 @@ In a script, it gives the following header: #!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11 @end example +@item -mfloat-abi (ARM only) +Select the float ABI. Possible values: @code{softfp} and @code{hard} + @item -dumpversion Print only the compiler version and nothing else. diff --git a/tcc.c b/tcc.c index 58f9007..9b5ca2e 100644 --- a/tcc.c +++ b/tcc.c @@ -224,7 +224,7 @@ static void display_info(TCCState *s, int what) print_paths("crt", s->crt_paths, s->nb_crt_paths); print_paths("libraries", s->library_paths, s->nb_library_paths); print_paths("include", s->sysinclude_paths, s->nb_sysinclude_paths); - printf("elfinterp:\n %s\n", CONFIG_TCC_ELFINTERP); + printf("elfinterp:\n %s\n", DEFAULT_ELFINTERP(s)); break; } } diff --git a/tcc.h b/tcc.h index f3d868f..73285ae 100644 --- a/tcc.h +++ b/tcc.h @@ -221,21 +221,24 @@ # endif # elif defined __GNU__ # define CONFIG_TCC_ELFINTERP "/lib/ld.so" -# elif defined TCC_ARM_HARDFLOAT -# define CONFIG_TCC_ELFINTERP "/lib/ld-linux-armhf.so.3" -# elif defined TCC_ARM_EABI -# define CONFIG_TCC_ELFINTERP "/lib/ld-linux.so.3" # elif defined(TCC_TARGET_X86_64) # define CONFIG_TCC_ELFINTERP "/lib64/ld-linux-x86-64.so.2" # elif defined(TCC_UCLIBC) # define CONFIG_TCC_ELFINTERP "/lib/ld-uClibc.so.0" # elif defined(TCC_TARGET_PE) # define CONFIG_TCC_ELFINTERP "-" -# else +# elif !defined(TCC_ARM_EABI) # define CONFIG_TCC_ELFINTERP "/lib/ld-linux.so.2" # endif #endif +/* var elf_interp dans *-gen.c */ +#ifdef CONFIG_TCC_ELFINTERP +# define DEFAULT_ELFINTERP(s) CONFIG_TCC_ELFINTERP +#else +# define DEFAULT_ELFINTERP(s) default_elfinterp(s) +#endif + /* library to use with CONFIG_USE_LIBGCC instead of libtcc1.a */ #define TCC_LIBGCC USE_MUADIR(CONFIG_SYSROOT "/" CONFIG_LDDIR) "/libgcc_s.so.1" @@ -561,6 +564,9 @@ struct TCCState { /* compile with built-in memory and bounds checker */ int do_bounds_check; #endif +#ifdef TCC_TARGET_ARM + enum float_abi float_abi; /* float ABI of the generated code*/ +#endif addr_t text_addr; /* address of text section */ int has_text_addr; @@ -1329,7 +1335,10 @@ ST_FUNC void gen_opl(int op); /* ------------ arm-gen.c ------------ */ #ifdef TCC_TARGET_ARM -ST_FUNC void arm_init_types(void); +#ifdef TCC_ARM_EABI +ST_FUNC char *default_elfinterp(struct TCCState *s); +#endif +ST_FUNC void arm_init(struct TCCState *s); ST_FUNC uint32_t encbranch(int pos, int addr, int fail); ST_FUNC void gen_cvt_itof1(int t); #endif diff --git a/tccelf.c b/tccelf.c index aa3daac..43a8086 100644 --- a/tccelf.c +++ b/tccelf.c @@ -1592,7 +1592,7 @@ static int elf_output_file(TCCState *s1, const char *filename) /* allow override the dynamic loader */ const char *elfint = getenv("LD_SO"); if (elfint == NULL) - elfint = CONFIG_TCC_ELFINTERP; + elfint = DEFAULT_ELFINTERP(s1); /* add interpreter section only if executable */ interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC); interp->sh_addralign = 1; -- cgit v1.3.1 From b0b5165d1668373c5d7b7933da599426f33e723b Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Thu, 6 Feb 2014 20:51:47 +0800 Subject: Def signedness != signed != unsigned for char When checking for exact compatibility between types (such as in __builtin_types_compatible_p) consider the case of default signedness to be incompatible with both of the explicit signedness for char. That is, char is incompatible with signed char *and* unsigned char, no matter what the default signedness for char is. --- Changelog | 1 + tcc-doc.texi | 2 +- tcc.h | 2 +- tccgen.c | 36 +++++++++++++++++++++++------------- 4 files changed, 26 insertions(+), 15 deletions(-) (limited to 'tcc-doc.texi') diff --git a/Changelog b/Changelog index b7ddd42..af206e3 100644 --- a/Changelog +++ b/Changelog @@ -68,6 +68,7 @@ Bug fixes: - fix integer to double conversion on ARM (Thomas Preud'homme) - fix parameter passing of (unsigned) long long bitfield (Thomas Preud'homme) - fix relocation of Thumb branch to ARM function (Thomas Preud'homme) +- fix char wrong compatibility with [un]signed char (Thomas Preud'homme) version 0.9.26: diff --git a/tcc-doc.texi b/tcc-doc.texi index e8832f6..3a1c7df 100644 --- a/tcc-doc.texi +++ b/tcc-doc.texi @@ -970,7 +970,7 @@ be the best solution. #define VT_BITFIELD 0x0040 /* bitfield modifier */ #define VT_CONSTANT 0x0800 /* const modifier */ #define VT_VOLATILE 0x1000 /* volatile modifier */ -#define VT_SIGNED 0x2000 /* signed type */ +#define VT_DEFSIGN 0x2000 /* signed type */ #define VT_STRUCT_SHIFT 18 /* structure/enum name shift (14 bits left) */ @end example diff --git a/tcc.h b/tcc.h index 73285ae..476cdf7 100644 --- a/tcc.h +++ b/tcc.h @@ -745,7 +745,7 @@ struct TCCState { #define VT_BITFIELD 0x0040 /* bitfield modifier */ #define VT_CONSTANT 0x0800 /* const modifier */ #define VT_VOLATILE 0x1000 /* volatile modifier */ -#define VT_SIGNED 0x2000 /* signed type */ +#define VT_DEFSIGN 0x2000 /* signed type */ #define VT_VLA 0x00020000 /* VLA type (also has VT_PTR and VT_ARRAY) */ /* storage */ diff --git a/tccgen.c b/tccgen.c index 03a446a..2f5b366 100644 --- a/tccgen.c +++ b/tccgen.c @@ -949,7 +949,7 @@ static void lexpand(void) { int u; - u = vtop->type.t & VT_UNSIGNED; + u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED); gv(RC_INT); vdup(); vtop[0].r = vtop[-1].r2; @@ -965,7 +965,7 @@ ST_FUNC void lexpand_nr(void) { int u,v; - u = vtop->type.t & VT_UNSIGNED; + u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED); vdup(); vtop->r2 = VT_CONST; vtop->type.t = VT_INT | u; @@ -1621,8 +1621,8 @@ static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op) return; tmp_type1 = *type1; tmp_type2 = *type2; - tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); - tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); + tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); + tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); if (!is_compatible_types(&tmp_type1, &tmp_type2)) { /* gcc-like error if '-' is used */ if (op == '-') @@ -2212,6 +2212,11 @@ static int compare_types(CType *type1, CType *type2, int unqualified) t1 &= ~(VT_CONSTANT | VT_VOLATILE); t2 &= ~(VT_CONSTANT | VT_VOLATILE); } + /* Default Vs explicit signedness only matters for char */ + if ((t1 & VT_BTYPE) != VT_BYTE) { + t1 &= ~VT_DEFSIGN; + t2 &= ~VT_DEFSIGN; + } /* XXX: bitfields ? */ if (t1 != t2) return 0; @@ -2264,8 +2269,10 @@ static void type_to_str(char *buf, int buf_size, pstrcat(buf, buf_size, "const "); if (t & VT_VOLATILE) pstrcat(buf, buf_size, "volatile "); - if (t & VT_UNSIGNED) + if (t & (VT_DEFSIGN | VT_UNSIGNED)) pstrcat(buf, buf_size, "unsigned "); + else if (t & VT_DEFSIGN) + pstrcat(buf, buf_size, "signed "); switch(bt) { case VT_VOID: tstr = "void"; @@ -2385,8 +2392,10 @@ static void gen_assign_cast(CType *dt) /* exact type match, except for unsigned */ tmp_type1 = *type1; tmp_type2 = *type2; - tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); - tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); + tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | + VT_VOLATILE); + tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | + VT_VOLATILE); if (!is_compatible_types(&tmp_type1, &tmp_type2)) tcc_warning("assignment from incompatible pointer type"); } @@ -3081,8 +3090,10 @@ static int parse_btype(CType *type, AttributeDef *ad) case TOK_SIGNED1: case TOK_SIGNED2: case TOK_SIGNED3: + if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == (VT_DEFSIGN|VT_UNSIGNED)) + tcc_error("signed and unsigned modifier"); typespec_found = 1; - t |= VT_SIGNED; + t |= VT_DEFSIGN; next(); break; case TOK_REGISTER: @@ -3093,7 +3104,9 @@ static int parse_btype(CType *type, AttributeDef *ad) next(); break; case TOK_UNSIGNED: - t |= VT_UNSIGNED; + if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == VT_DEFSIGN) + tcc_error("signed and unsigned modifier"); + t |= VT_DEFSIGN | VT_UNSIGNED; next(); typespec_found = 1; break; @@ -3160,13 +3173,10 @@ static int parse_btype(CType *type, AttributeDef *ad) type_found = 1; } the_end: - if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED)) - tcc_error("signed and unsigned modifier"); if (tcc_state->char_is_unsigned) { - if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE) + if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE) t |= VT_UNSIGNED; } - t &= ~VT_SIGNED; /* long is never used as type */ if ((t & VT_BTYPE) == VT_LONG) -- cgit v1.3.1 From d09a46d655f18e88b848e95ddf7fed7ac20bfc36 Mon Sep 17 00:00:00 2001 From: Vincent Lefevre Date: Mon, 7 Apr 2014 13:20:49 +0200 Subject: corrected a typo --- tcc-doc.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tcc-doc.texi') diff --git a/tcc-doc.texi b/tcc-doc.texi index 3a1c7df..68bac65 100644 --- a/tcc-doc.texi +++ b/tcc-doc.texi @@ -1080,7 +1080,7 @@ are used when bound checking is activated @item stab_section @itemx stabstr_section -are used when debugging is actived to store debug information +are used when debugging is active to store debug information @item symtab_section @itemx strtab_section -- cgit v1.3.1