diff options
| -rw-r--r-- | lib/libtcc1.c | 397 | ||||
| -rw-r--r-- | libtcc.c | 13 | ||||
| -rw-r--r-- | tcc.h | 11 | ||||
| -rw-r--r-- | tccgen.c | 179 | ||||
| -rw-r--r-- | tccpp.c | 303 | ||||
| -rw-r--r-- | tcctok.h | 2 | ||||
| -rw-r--r-- | tests/Makefile | 2 | ||||
| -rw-r--r-- | tests/abitest.c | 59 | ||||
| -rw-r--r-- | tests/tcctest.c | 270 | ||||
| -rw-r--r-- | tests/tests2/66_macro_concat_end.expect | 2 | ||||
| -rw-r--r-- | x86_64-gen.c | 6 |
11 files changed, 485 insertions, 759 deletions
diff --git a/lib/libtcc1.c b/lib/libtcc1.c index b944f4f..284965e 100644 --- a/lib/libtcc1.c +++ b/lib/libtcc1.c @@ -54,29 +54,29 @@ typedef long double XFtype; #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) /* the following deal with IEEE single-precision numbers */ -#define EXCESS 126 -#define SIGNBIT 0x80000000 -#define HIDDEN (1 << 23) -#define SIGN(fp) ((fp) & SIGNBIT) -#define EXP(fp) (((fp) >> 23) & 0xFF) -#define MANT(fp) (((fp) & 0x7FFFFF) | HIDDEN) -#define PACK(s,e,m) ((s) | ((e) << 23) | (m)) +#define EXCESS 126 +#define SIGNBIT 0x80000000 +#define HIDDEN (1 << 23) +#define SIGN(fp) ((fp) & SIGNBIT) +#define EXP(fp) (((fp) >> 23) & 0xFF) +#define MANT(fp) (((fp) & 0x7FFFFF) | HIDDEN) +#define PACK(s,e,m) ((s) | ((e) << 23) | (m)) /* the following deal with IEEE double-precision numbers */ -#define EXCESSD 1022 -#define HIDDEND (1 << 20) -#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF) -#define SIGND(fp) ((fp.l.upper) & SIGNBIT) -#define MANTD(fp) (((((fp.l.upper) & 0xFFFFF) | HIDDEND) << 10) | \ - (fp.l.lower >> 22)) -#define HIDDEND_LL ((long long)1 << 52) -#define MANTD_LL(fp) ((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL) -#define PACKD_LL(s,e,m) (((long long)((s)+((e)<<20))<<32)|(m)) +#define EXCESSD 1022 +#define HIDDEND (1 << 20) +#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF) +#define SIGND(fp) ((fp.l.upper) & SIGNBIT) +#define MANTD(fp) (((((fp.l.upper) & 0xFFFFF) | HIDDEND) << 10) | \ + (fp.l.lower >> 22)) +#define HIDDEND_LL ((long long)1 << 52) +#define MANTD_LL(fp) ((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL) +#define PACKD_LL(s,e,m) (((long long)((s)+((e)<<20))<<32)|(m)) /* the following deal with x86 long double-precision numbers */ -#define EXCESSLD 16382 -#define EXPLD(fp) (fp.l.upper & 0x7fff) -#define SIGNLD(fp) ((fp.l.upper) & 0x8000) +#define EXCESSLD 16382 +#define EXPLD(fp) (fp.l.upper & 0x7fff) +#define SIGNLD(fp) ((fp.l.upper) & 0x8000) /* only for x86 */ union ldouble_long { @@ -114,32 +114,32 @@ union float_long { /* XXX: use gcc/tcc intrinsic ? */ #if defined(TCC_TARGET_I386) #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("subl %5,%1\n\tsbbl %3,%0" \ - : "=r" ((USItype) (sh)), \ - "=&r" ((USItype) (sl)) \ - : "0" ((USItype) (ah)), \ - "g" ((USItype) (bh)), \ - "1" ((USItype) (al)), \ - "g" ((USItype) (bl))) + __asm__ ("subl %5,%1\n\tsbbl %3,%0" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "0" ((USItype) (ah)), \ + "g" ((USItype) (bh)), \ + "1" ((USItype) (al)), \ + "g" ((USItype) (bl))) #define umul_ppmm(w1, w0, u, v) \ - __asm__ ("mull %3" \ - : "=a" ((USItype) (w0)), \ - "=d" ((USItype) (w1)) \ - : "%0" ((USItype) (u)), \ - "rm" ((USItype) (v))) + __asm__ ("mull %3" \ + : "=a" ((USItype) (w0)), \ + "=d" ((USItype) (w1)) \ + : "%0" ((USItype) (u)), \ + "rm" ((USItype) (v))) #define udiv_qrnnd(q, r, n1, n0, dv) \ - __asm__ ("divl %4" \ - : "=a" ((USItype) (q)), \ - "=d" ((USItype) (r)) \ - : "0" ((USItype) (n0)), \ - "1" ((USItype) (n1)), \ - "rm" ((USItype) (dv))) + __asm__ ("divl %4" \ + : "=a" ((USItype) (q)), \ + "=d" ((USItype) (r)) \ + : "0" ((USItype) (n0)), \ + "1" ((USItype) (n1)), \ + "rm" ((USItype) (dv))) #define count_leading_zeros(count, x) \ - do { \ - USItype __cbtmp; \ - __asm__ ("bsrl %1,%0" \ - : "=r" (__cbtmp) : "rm" ((USItype) (x))); \ - (count) = __cbtmp ^ 31; \ + do { \ + USItype __cbtmp; \ + __asm__ ("bsrl %1,%0" \ + : "=r" (__cbtmp) : "rm" ((USItype) (x))); \ + (count) = __cbtmp ^ 31; \ } while (0) #else #error unsupported CPU type @@ -168,33 +168,33 @@ static UDWtype __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp) if (d1 == 0) { if (d0 > n1) - { - /* 0q = nn / 0D */ + { + /* 0q = nn / 0D */ - udiv_qrnnd (q0, n0, n1, n0, d0); - q1 = 0; + udiv_qrnnd (q0, n0, n1, n0, d0); + q1 = 0; - /* Remainder in n0. */ - } + /* Remainder in n0. */ + } else - { - /* qq = NN / 0d */ + { + /* qq = NN / 0d */ - if (d0 == 0) - d0 = 1 / d0; /* Divide intentionally by zero. */ + if (d0 == 0) + d0 = 1 / d0; /* Divide intentionally by zero. */ - udiv_qrnnd (q1, n1, 0, n1, d0); - udiv_qrnnd (q0, n0, n1, n0, d0); + udiv_qrnnd (q1, n1, 0, n1, d0); + udiv_qrnnd (q0, n0, n1, n0, d0); - /* Remainder in n0. */ - } + /* Remainder in n0. */ + } if (rp != 0) - { - rr.s.low = n0; - rr.s.high = 0; - *rp = rr.ll; - } + { + rr.s.low = n0; + rr.s.high = 0; + *rp = rr.ll; + } } #else /* UDIV_NEEDS_NORMALIZATION */ @@ -202,160 +202,160 @@ static UDWtype __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp) if (d1 == 0) { if (d0 > n1) - { - /* 0q = nn / 0D */ + { + /* 0q = nn / 0D */ - count_leading_zeros (bm, d0); + count_leading_zeros (bm, d0); - if (bm != 0) - { - /* Normalize, i.e. make the most significant bit of the - denominator set. */ + if (bm != 0) + { + /* Normalize, i.e. make the most significant bit of the + denominator set. */ - d0 = d0 << bm; - n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm)); - n0 = n0 << bm; - } + d0 = d0 << bm; + n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm)); + n0 = n0 << bm; + } - udiv_qrnnd (q0, n0, n1, n0, d0); - q1 = 0; + udiv_qrnnd (q0, n0, n1, n0, d0); + q1 = 0; - /* Remainder in n0 >> bm. */ - } + /* Remainder in n0 >> bm. */ + } else - { - /* qq = NN / 0d */ + { + /* qq = NN / 0d */ - if (d0 == 0) - d0 = 1 / d0; /* Divide intentionally by zero. */ + if (d0 == 0) + d0 = 1 / d0; /* Divide intentionally by zero. */ - count_leading_zeros (bm, d0); + count_leading_zeros (bm, d0); - if (bm == 0) - { - /* From (n1 >= d0) /\ (the most significant bit of d0 is set), - conclude (the most significant bit of n1 is set) /\ (the - leading quotient digit q1 = 1). + if (bm == 0) + { + /* From (n1 >= d0) /\ (the most significant bit of d0 is set), + conclude (the most significant bit of n1 is set) /\ (the + leading quotient digit q1 = 1). - This special case is necessary, not an optimization. - (Shifts counts of W_TYPE_SIZE are undefined.) */ + This special case is necessary, not an optimization. + (Shifts counts of W_TYPE_SIZE are undefined.) */ - n1 -= d0; - q1 = 1; - } - else - { - /* Normalize. */ + n1 -= d0; + q1 = 1; + } + else + { + /* Normalize. */ - b = W_TYPE_SIZE - bm; + b = W_TYPE_SIZE - bm; - d0 = d0 << bm; - n2 = n1 >> b; - n1 = (n1 << bm) | (n0 >> b); - n0 = n0 << bm; + d0 = d0 << bm; + n2 = n1 >> b; + n1 = (n1 << bm) | (n0 >> b); + n0 = n0 << bm; - udiv_qrnnd (q1, n1, n2, n1, d0); - } + udiv_qrnnd (q1, n1, n2, n1, d0); + } - /* n1 != d0... */ + /* n1 != d0... */ - udiv_qrnnd (q0, n0, n1, n0, d0); + udiv_qrnnd (q0, n0, n1, n0, d0); - /* Remainder in n0 >> bm. */ - } + /* Remainder in n0 >> bm. */ + } if (rp != 0) - { - rr.s.low = n0 >> bm; - rr.s.high = 0; - *rp = rr.ll; - } + { + rr.s.low = n0 >> bm; + rr.s.high = 0; + *rp = rr.ll; + } } #endif /* UDIV_NEEDS_NORMALIZATION */ else { if (d1 > n1) - { - /* 00 = nn / DD */ + { + /* 00 = nn / DD */ - q0 = 0; - q1 = 0; + q0 = 0; + q1 = 0; - /* Remainder in n1n0. */ - if (rp != 0) - { - rr.s.low = n0; - rr.s.high = n1; - *rp = rr.ll; - } - } + /* Remainder in n1n0. */ + if (rp != 0) + { + rr.s.low = n0; + rr.s.high = n1; + *rp = rr.ll; + } + } else - { - /* 0q = NN / dd */ + { + /* 0q = NN / dd */ - count_leading_zeros (bm, d1); - if (bm == 0) - { - /* From (n1 >= d1) /\ (the most significant bit of d1 is set), - conclude (the most significant bit of n1 is set) /\ (the - quotient digit q0 = 0 or 1). + count_leading_zeros (bm, d1); + if (bm == 0) + { + /* From (n1 >= d1) /\ (the most significant bit of d1 is set), + conclude (the most significant bit of n1 is set) /\ (the + quotient digit q0 = 0 or 1). - This special case is necessary, not an optimization. */ + This special case is necessary, not an optimization. */ - /* The condition on the next line takes advantage of that - n1 >= d1 (true due to program flow). */ - if (n1 > d1 || n0 >= d0) - { - q0 = 1; - sub_ddmmss (n1, n0, n1, n0, d1, d0); - } - else - q0 = 0; + /* The condition on the next line takes advantage of that + n1 >= d1 (true due to program flow). */ + if (n1 > d1 || n0 >= d0) + { + q0 = 1; + sub_ddmmss (n1, n0, n1, n0, d1, d0); + } + else + q0 = 0; - q1 = 0; + q1 = 0; - if (rp != 0) - { - rr.s.low = n0; - rr.s.high = n1; - *rp = rr.ll; - } - } - else - { - UWtype m1, m0; - /* Normalize. */ + if (rp != 0) + { + rr.s.low = n0; + rr.s.high = n1; + *rp = rr.ll; + } + } + else + { + UWtype m1, m0; + /* Normalize. */ - b = W_TYPE_SIZE - bm; + b = W_TYPE_SIZE - bm; - d1 = (d1 << bm) | (d0 >> b); - d0 = d0 << bm; - n2 = n1 >> b; - n1 = (n1 << bm) | (n0 >> b); - n0 = n0 << bm; + d1 = (d1 << bm) | (d0 >> b); + d0 = d0 << bm; + n2 = n1 >> b; + n1 = (n1 << bm) | (n0 >> b); + n0 = n0 << bm; - udiv_qrnnd (q0, n1, n2, n1, d1); - umul_ppmm (m1, m0, q0, d0); + udiv_qrnnd (q0, n1, n2, n1, d1); + umul_ppmm (m1, m0, q0, d0); - if (m1 > n1 || (m1 == n1 && m0 > n0)) - { - q0--; - sub_ddmmss (m1, m0, m1, m0, d1, d0); - } + if (m1 > n1 || (m1 == n1 && m0 > n0)) + { + q0--; + sub_ddmmss (m1, m0, m1, m0, d1, d0); + } - q1 = 0; + q1 = 0; - /* Remainder in (n1n0 - m1m0) >> bm. */ - if (rp != 0) - { - sub_ddmmss (n1, n0, n1, n0, m1, m0); - rr.s.low = (n1 << b) | (n0 >> bm); - rr.s.high = n1 >> bm; - *rp = rr.ll; - } - } - } + /* Remainder in (n1n0 - m1m0) >> bm. */ + if (rp != 0) + { + sub_ddmmss (n1, n0, n1, n0, m1, m0); + rr.s.low = (n1 << b) | (n0 >> bm); + rr.s.high = n1 >> bm; + *rp = rr.ll; + } + } + } } ww.s.low = q0; @@ -533,22 +533,21 @@ unsigned long long __fixunssfdi (float a1) register union float_long fl1; register int exp; register unsigned long l; - int s; + fl1.f = a1; if (fl1.l == 0) - return 0; + return (0); exp = EXP (fl1.l) - EXCESS - 24; l = MANT(fl1.l); - s = SIGN(fl1.l)? -1: 1; - if (exp >= 64) - return (unsigned long long)-1; + if (exp >= 41) + return (unsigned long long)-1; else if (exp >= 0) - return ((unsigned long long)l << exp)*s; + return (unsigned long long)l << exp; else if (exp >= -23) - return (l >> -exp)*s; + return l >> -exp; else return 0; } @@ -558,22 +557,22 @@ unsigned long long __fixunsdfdi (double a1) register union double_long dl1; register int exp; register unsigned long long l; - int s; + dl1.d = a1; if (dl1.ll == 0) - return (0); + return (0); exp = EXPD (dl1) - EXCESSD - 53; l = MANTD_LL(dl1); - s = SIGND(dl1)? -1: 1; - if (exp >= 64) - return (unsigned long long)-1; + + if (exp >= 12) + return (unsigned long long)-1; else if (exp >= 0) - return (l << exp)*s; + return l << exp; else if (exp >= -52) - return (l >> -exp)*s; + return l >> -exp; else return 0; } @@ -583,22 +582,20 @@ unsigned long long __fixunsxfdi (long double a1) register union ldouble_long dl1; register int exp; register unsigned long long l; - int s; + dl1.ld = a1; if (dl1.l.lower == 0 && dl1.l.upper == 0) - return (0); + return (0); exp = EXPLD (dl1) - EXCESSLD - 64; - s = SIGNLD(dl1)? -1: 1; + l = dl1.l.lower; - if (exp >= 64) - return (unsigned long long)-1; - else if (exp >= 0) - return ((unsigned long long)l << exp)*s; - else if (exp >= -64) - return (l >> -exp)*s; + if (exp > 0) + return (unsigned long long)-1; + else if (exp >= -63) + return l >> -exp; else return 0; } @@ -640,7 +637,7 @@ extern void abort(void); #endif enum __va_arg_type { - __va_gen_reg, __va_float_reg, __va_stack + __va_gen_reg, __va_float_reg, __va_stack }; //This should be in sync with the declaration on our include/stdarg.h @@ -576,15 +576,12 @@ static void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap) for (f = file; f && f->filename[0] == ':'; f = f->prev) ; if (f) { - int line_num = f->line_num; for(pf = s1->include_stack; pf < s1->include_stack_ptr; pf++) strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n", (*pf)->filename, (*pf)->line_num); - if (line_num > 0) { - if(tok == TOK_LINEFEED || (tok == CH_EOF && line_num > 1)) - line_num--; + if (f->line_num > 0) { strcat_printf(buf, sizeof(buf), "%s:%d: ", - f->filename, line_num); + f->filename, f->line_num); } else { strcat_printf(buf, sizeof(buf), "%s: ", f->filename); @@ -871,7 +868,6 @@ LIBTCCAPI void tcc_undefine_symbol(TCCState *s1, const char *sym) static void tcc_cleanup(void) { int i, n; - CSym *def; if (NULL == tcc_state) return; tcc_state = NULL; @@ -881,11 +877,8 @@ static void tcc_cleanup(void) /* free tokens */ n = tok_ident - TOK_IDENT; - for(i = 0; i < n; i++){ - def = &table_ident[i]->sym_define; - tcc_free(def->data); + for(i = 0; i < n; i++) tcc_free(table_ident[i]); - } tcc_free(table_ident); /* free sym_pools */ @@ -303,22 +303,15 @@ #define VSTACK_SIZE 256 #define STRING_MAX_SIZE 1024 #define PACK_STACK_SIZE 8 -#define MACRO_STACK_SIZE 8 #define TOK_HASH_SIZE 8192 /* must be a power of two */ #define TOK_ALLOC_INCR 512 /* must be a power of two */ #define TOK_MAX_SIZE 4 /* token max size in int unit when stored in string */ -typedef struct CSym { - int off; - int size;/* size in *sym */ - struct Sym **data; /* if non NULL, data has been malloced */ -} CSym; - /* token symbol management */ typedef struct TokenSym { struct TokenSym *hash_next; - struct CSym sym_define; /* direct pointer to define */ + struct Sym *sym_define; /* direct pointer to define */ struct Sym *sym_label; /* direct pointer to label */ struct Sym *sym_struct; /* direct pointer to structure */ struct Sym *sym_identifier; /* direct pointer to identifier */ @@ -1131,7 +1124,7 @@ ST_DATA TokenSym **table_ident; token. line feed is also returned at eof */ #define PARSE_FLAG_ASM_COMMENTS 0x0008 /* '#' can be used for line comment */ -#define PARSE_FLAG_SPACES 0x0010 /* next() returns space tokens (for -E) */ +#define PARSE_FLAG_SPACES 0x0010 /* next() returns space tokens (for -E) */ ST_FUNC TokenSym *tok_alloc(const char *str, int len); ST_FUNC char *get_tok_str(int v, CValue *cv); @@ -90,9 +90,6 @@ static void vla_runtime_type_size(CType *type, int *a); static void vla_sp_save(void); static int is_compatible_parameter_types(CType *type1, CType *type2); static void expr_type(CType *type); -static int is_putz; -static int is_force; - ST_FUNC void vpush64(int ty, unsigned long long v); ST_FUNC void vpush(CType *type); ST_FUNC int gvtst(int inv, int t); @@ -1020,7 +1017,6 @@ ST_FUNC void lexpand_nr(void) } #endif -#ifndef TCC_TARGET_X86_64 /* build a long long from two ints */ static void lbuild(int t) { @@ -1029,7 +1025,6 @@ static void lbuild(int t) vtop[-1].type.t = t; vpop(); } -#endif /* rotate n first stack elements to the bottom I1 ... In -> I2 ... In I1 [top is right] @@ -1091,8 +1086,8 @@ static void gv_dup(void) { int rc, t, r, r1; SValue sv; + t = vtop->type.t; -#ifndef TCC_TARGET_X86_64 if ((t & VT_BTYPE) == VT_LLONG) { lexpand(); gv_dup(); @@ -1102,14 +1097,15 @@ static void gv_dup(void) vrotb(4); /* stack: H L L1 H1 */ lbuild(t); - vrott(3); + vrotb(3); + vrotb(3); vswap(); lbuild(t); vswap(); - } else -#endif - { + } else { /* duplicate value */ + rc = RC_INT; + sv.type.t = VT_INT; if (is_float(t)) { rc = RC_FLOAT; #ifdef TCC_TARGET_X86_64 @@ -1117,9 +1113,8 @@ static void gv_dup(void) rc = RC_ST0; } #endif - }else - rc = RC_INT; - sv.type.t = t; + sv.type.t = t; + } r = gv(rc); r1 = get_reg(rc); sv.r = r; @@ -1989,30 +1984,11 @@ static void gen_cast(CType *type) ; #endif else if (dbt != VT_LLONG) { - int s, dt, warr = 0; - long long ll; - dt = dbt & VT_BTYPE; - ll = vtop->c.ll; - if (dt == VT_BYTE){ - if((ll != (unsigned char)ll) && (ll != (char)ll)) - warr = 1; + int s = 0; + if ((dbt & VT_BTYPE) == VT_BYTE) s = 24; - }else if (dt == VT_SHORT){ - if((ll != (unsigned short)ll) && (ll != (short)ll)) - warr = 1; + else if ((dbt & VT_BTYPE) == VT_SHORT) s = 16; - }else{ - if((ll != (unsigned int)ll) && (ll != (int)ll)) - warr = 1; - s = 0; - } - if(warr && !is_force){ - if(dt == VT_ENUM){ - tcc_warning("large integer implicitly truncated to unsigned type"); - dbt = VT_UNSIGNED; - }else - tcc_warning("overflow in implicit constant conversion"); - } if(dbt & VT_UNSIGNED) vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s; else @@ -2465,8 +2441,6 @@ static void gen_assign_cast(CType *dt) if (sbt == VT_PTR || sbt == VT_FUNC) { tcc_warning("assignment makes integer from pointer without a cast"); } - if (sbt == VT_STRUCT) - goto error; /* XXX: more tests */ break; case VT_STRUCT: @@ -2489,15 +2463,14 @@ static void gen_assign_cast(CType *dt) /* store vtop in lvalue pushed on stack */ ST_FUNC void vstore(void) { - int sbt, dbt, ft, cc, r, t, size, align, bit_size, bit_pos, rc, delayed_cast; + int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast; ft = vtop[-1].type.t; sbt = vtop->type.t & VT_BTYPE; dbt = ft & VT_BTYPE; - cc = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) || (sbt == VT_INT && dbt == VT_SHORT)) - && !(vtop->type.t & VT_BITFIELD) && !cc) { + && !(vtop->type.t & VT_BITFIELD)) { /* optimize char/short casts */ delayed_cast = VT_MUSTCAST; vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT))); @@ -2591,6 +2564,7 @@ ST_FUNC void vstore(void) /* pop off shifted source from "duplicate source..." above */ vpop(); + } else { #ifdef CONFIG_TCC_BCHECK /* bound check case */ @@ -2865,7 +2839,7 @@ static void struct_decl(CType *type, int u, int tdef) s = struct_find(v); if (s) { if (s->type.t != a) - tcc_error("invalid type: '%s'", get_tok_str(v, NULL)); + tcc_error("invalid type"); goto do_decl; } else if (tok >= TOK_IDENT && !tdef) tcc_error("unknown struct/union/enum"); @@ -2937,7 +2911,7 @@ static void struct_decl(CType *type, int u, int tdef) if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT) expect("identifier"); if (type_size(&type1, &align) < 0) { - if ((a == TOK_STRUCT) && (type1.t & VT_ARRAY)) + if ((a == TOK_STRUCT) && (type1.t & VT_ARRAY) && c) flexible = 1; else tcc_error("field '%s' has incomplete type", @@ -3056,8 +3030,6 @@ static void struct_decl(CType *type, int u, int tdef) skip(';'); } skip('}'); - if (!c && flexible) - tcc_error("flexible array member '%s' in otherwise empty struct", get_tok_str(v, NULL)); /* store size and alignment */ s->c = (c + maxalign - 1) & -maxalign; s->r = maxalign; @@ -3742,9 +3714,7 @@ ST_FUNC void unary(void) return; } unary(); - is_force = 1; gen_cast(&type); - is_force = 0; } } else if (tok == '{') { /* save all registers */ @@ -3823,8 +3793,6 @@ ST_FUNC void unary(void) if (!(type.t & VT_VLA)) { if (size < 0) tcc_error("sizeof applied to an incomplete type"); - if(type.t & VT_BITFIELD) - tcc_error("'%s' applied to a bit-field", get_tok_str(t, NULL)); vpushs(size); } else { vla_runtime_type_size(&type, &align); @@ -3999,7 +3967,7 @@ ST_FUNC void unary(void) #endif ) tcc_warning("implicit declaration of function '%s'", name); - s = external_sym(t, &func_old_type, 0, NULL); + s = external_global_sym(t, &func_old_type, 0); } if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) == (VT_STATIC | VT_INLINE | VT_FUNC)) { @@ -5048,11 +5016,11 @@ static void decl_designator(CType *type, Section *sec, unsigned long c, nb_elems = 1; if (gnu_ext && (l = is_label()) != 0) goto struct_field; - s = type->ref; while (tok == '[' || tok == '.') { if (tok == '[') { if (!(type->t & VT_ARRAY)) expect("array type"); + s = type->ref; next(); index = expr_const(); if (index < 0 || (s->c >= 0 && index >= s->c)) @@ -5086,6 +5054,7 @@ static void decl_designator(CType *type, Section *sec, unsigned long c, struct_field: if ((type->t & VT_BTYPE) != VT_STRUCT) expect("struct/union type"); + s = type->ref; l |= SYM_FIELD; f = s->next; while (f) { @@ -5115,30 +5084,17 @@ static void decl_designator(CType *type, Section *sec, unsigned long c, } else { if (type->t & VT_ARRAY) { index = *cur_index; - if (s->c >= 0 && index >= s->c){ - if(!size_only) - tcc_warning("excess elements in array initializer"); - type = NULL; - size_only = 1; - }else{ - type = pointed_type(type); - c += index * type_size(type, &align); - } + type = pointed_type(type); + c += index * type_size(type, &align); } else { f = *cur_field; - if (f){ - /* XXX: fix this mess by using explicit storage field */ - type1 = f->type; - type1.t |= (type->t & ~VT_TYPE); - type = &type1; - c += f->c; - }else{ - if(!size_only) - tcc_warning("excess elements in %s initializer", - get_tok_str(s->type.t, NULL)); - type = NULL; - size_only = 1; - } + if (!f) + tcc_error("too many field init"); + /* XXX: fix this mess by using explicit storage field */ + type1 = f->type; + type1.t |= (type->t & ~VT_TYPE); + type = &type1; + c += f->c; } } decl_initializer(type, sec, c, 0, size_only); @@ -5298,8 +5254,6 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, Sym *s, *f; CType *t1; - if(!type) - goto Ignore; if (type->t & VT_VLA) { int a; @@ -5390,10 +5344,14 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, index = 0; while (tok != '}') { decl_designator(type, sec, c, &index, NULL, size_only); + if (n >= 0 && index >= n) + tcc_error("index too large"); /* must put zero in holes (note that doing it that way ensures that it even works with designators) */ - if (!is_putz && array_length < index) - is_putz = 1; + if (!size_only && array_length < index) { + init_putz(t1, sec, c + array_length * size1, + (index - array_length) * size1); + } index++; if (index > array_length) array_length = index; @@ -5410,8 +5368,10 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, if (!no_oblock) skip('}'); /* put zeros at the end */ - if (!is_putz && n >= 0 && array_length < n) - is_putz = 1; + if (!size_only && n >= 0 && array_length < n) { + init_putz(t1, sec, c + array_length * size1, + (n - array_length) * size1); + } /* patch type size if needed */ if (n < 0) s->c = array_length; @@ -5457,44 +5417,46 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, n = s->c; while (tok != '}') { decl_designator(type, sec, c, NULL, &f, size_only); - if(f){ - index = f->c; - if (!is_putz && array_length < index) - is_putz = 1; - index = index + type_size(&f->type, &align1); - if (index > array_length) - array_length = index; + index = f->c; + if (!size_only && array_length < index) { + init_putz(type, sec, c + array_length, + index - array_length); + } + index = index + type_size(&f->type, &align1); + if (index > array_length) + array_length = index; - /* gr: skip fields from same union - ugly. */ - while (f->next) { - ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t); - /* test for same offset */ - if (f->next->c != f->c) + /* gr: skip fields from same union - ugly. */ + while (f->next) { + ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t); + /* test for same offset */ + if (f->next->c != f->c) + break; + /* if yes, test for bitfield shift */ + if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) { + int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f; + int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f; + //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2); + if (bit_pos_1 != bit_pos_2) break; - /* if yes, test for bitfield shift */ - if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) { - int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f; - int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f; - //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2); - if (bit_pos_1 != bit_pos_2) - break; - } - f = f->next; } - f = f->next; - if (no_oblock && f == NULL) - break; } + + f = f->next; + if (no_oblock && f == NULL) + break; if (tok == '}') break; skip(','); } + /* put zeros at the end */ + if (!size_only && array_length < n) { + init_putz(type, sec, c + array_length, + n - array_length); + } if (!no_oblock) skip('}'); - /* put zeros at the end */ - if (!is_putz && array_length < n) - is_putz = 1; while (par_count) { skip(')'); par_count--; @@ -5504,7 +5466,6 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, decl_initializer(type, sec, c, first, size_only); skip('}'); } else if (size_only) { -Ignore: /* just skip expression */ parlevel = parlevel1 = 0; while ((parlevel > 0 || parlevel1 > 0 || @@ -5549,7 +5510,6 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, Sym *flexible_array; flexible_array = NULL; - is_putz = 0; if ((type->t & VT_BTYPE) == VT_STRUCT) { Sym *field = type->ref->next; if (field) { @@ -5568,8 +5528,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, literals). It also simplifies local initializers handling */ tok_str_new(&init_str); - if (size < 0 || ((((type->t & VT_BTYPE) == VT_STRUCT) || (type->t & VT_ARRAY)) && - has_init && (tok < TOK_IDENT))){ + if (size < 0 || (flexible_array && has_init)) { if (!has_init) tcc_error("unknown type size"); /* get all init string */ @@ -5760,8 +5719,6 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, #endif } if (has_init || (type->t & VT_VLA)) { - if(is_putz) - init_putz(type, sec, addr, size); decl_initializer(type, sec, addr, 1, 0); /* restore parse state if needed */ if (init_str.str) { @@ -61,7 +61,6 @@ static TokenSym *hash_ident[TOK_HASH_SIZE]; static char token_buf[STRING_MAX_SIZE + 1]; /* true if isid(c) || isnum(c) */ static unsigned char isidnum_table[256-CH_EOF]; -static int token_seen; static const char tcc_keywords[] = #define DEF(id, str) str "\0" @@ -235,10 +234,7 @@ static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len) ts = tcc_malloc(sizeof(TokenSym) + len); table_ident[i] = ts; ts->tok = tok_ident++; - ts->sym_define.data = tcc_malloc(sizeof(Sym*)); - ts->sym_define.off = 0; - ts->sym_define.data[0] = NULL; - ts->sym_define.size = 1; + ts->sym_define = NULL; ts->sym_label = NULL; ts->sym_struct = NULL; ts->sym_identifier = NULL; @@ -1057,62 +1053,52 @@ static int macro_is_equal(const int *a, const int *b) ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg) { Sym *s; - CSym *def; + s = define_find(v); if (s && !macro_is_equal(s->d, str)) tcc_warning("%s redefined", get_tok_str(v, NULL)); + s = sym_push2(&define_stack, v, macro_type, 0); s->d = str; s->next = first_arg; - def = &table_ident[v - TOK_IDENT]->sym_define; - def->data[def->off] = s; + table_ident[v - TOK_IDENT]->sym_define = s; } /* undefined a define symbol. Its name is just set to zero */ ST_FUNC void define_undef(Sym *s) { int v; - CSym *def; - v = s->v - TOK_IDENT; - if ((unsigned)v < (unsigned)(tok_ident - TOK_IDENT)){ - def = &table_ident[v]->sym_define; - def->data[def->off] = NULL; - } + v = s->v; + if (v >= TOK_IDENT && v < tok_ident) + table_ident[v - TOK_IDENT]->sym_define = NULL; + s->v = 0; } ST_INLN Sym *define_find(int v) { - CSym *def; v -= TOK_IDENT; if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT)) return NULL; - def = &table_ident[v]->sym_define; - return def->data[def->off]; + return table_ident[v]->sym_define; } /* free define stack until top reaches 'b' */ ST_FUNC void free_defines(Sym *b) { - Sym *top, *tmp; + Sym *top, *top1; int v; - CSym *def; top = define_stack; while (top != b) { - tmp = top->prev; + top1 = top->prev; /* do not free args or predefined defines */ if (top->d) tok_str_free(top->d); - v = top->v - TOK_IDENT; - if ((unsigned)v < (unsigned)(tok_ident - TOK_IDENT)){ - def = &table_ident[v]->sym_define; - if(def->off) - def->off = 0; - if(def->data[0]) - def->data[0] = NULL; - } + v = top->v; + if (v >= TOK_IDENT && v < tok_ident) + table_ident[v - TOK_IDENT]->sym_define = NULL; sym_free(top); - top = tmp; + top = top1; } define_stack = b; } @@ -1353,18 +1339,66 @@ static inline void add_cached_include(TCCState *s1, const char *filename, int if s1->cached_includes_hash[h] = s1->nb_cached_includes; } +static void pragma_parse(TCCState *s1) +{ + int val; + + next(); + if (tok == TOK_pack) { + /* + This may be: + #pragma pack(1) // set + #pragma pack() // reset to default + #pragma pack(push,1) // push & set + #pragma pack(pop) // restore previous + */ + next(); + skip('('); + if (tok == TOK_ASM_pop) { + next(); + if (s1->pack_stack_ptr <= s1->pack_stack) { + stk_error: + tcc_error("out of pack stack"); + } + s1->pack_stack_ptr--; + } else { + val = 0; + if (tok != ')') { + if (tok == TOK_ASM_push) { + next(); + if (s1->pack_stack_ptr >= s1->pack_stack + PACK_STACK_SIZE - 1) + goto stk_error; + s1->pack_stack_ptr++; + skip(','); + } + if (tok != TOK_CINT) { + pack_error: + tcc_error("invalid pack pragma"); + } + val = tokc.i; + if (val < 1 || val > 16 || (val & (val - 1)) != 0) + goto pack_error; + next(); + } + *s1->pack_stack_ptr = val; + skip(')'); + } + } +} + /* is_bof is true if first non space token at beginning of file */ ST_FUNC void preprocess(int is_bof) { TCCState *s1 = tcc_state; int i, c, n, saved_parse_flags; - uint8_t buf[1024], *p; + char buf[1024], *q; Sym *s; saved_parse_flags = parse_flags; - parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_LINEFEED; + parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | + PARSE_FLAG_LINEFEED; next_nomacro(); -redo: + redo: switch(tok) { case TOK_DEFINE: next_nomacro(); @@ -1387,21 +1421,19 @@ redo: goto read_name; } else if (ch == '\"') { c = ch; -read_name: + read_name: inp(); - p = buf; + q = buf; while (ch != c && ch != '\n' && ch != CH_EOF) { - if ((p - buf) < sizeof(buf) - 1) - *p++ = ch; + if ((q - buf) < sizeof(buf) - 1) + *q++ = ch; if (ch == '\\') { if (handle_stray_noerror() == 0) - --p; + --q; } else inp(); } - if (ch != c) - goto include_syntax; - *p = '\0'; + *q = '\0'; minp(); #if 0 /* eat all spaces and comments after include */ @@ -1439,8 +1471,6 @@ read_name: c = '>'; } } - if(!buf[0]) - tcc_error(" empty filename in #include"); if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE) tcc_error("#include recursion too deep"); @@ -1507,7 +1537,8 @@ include_trynext: printf("%s: including %s\n", file->prev->filename, file->filename); #endif /* update target deps */ - dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps, tcc_strdup(buf1)); + dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps, + tcc_strdup(buf1)); /* push current file in stack */ ++s1->include_stack_ptr; /* add include file debug info */ @@ -1540,7 +1571,7 @@ include_done: file->ifndef_macro = tok; } } - c = !!define_find(tok) ^ c; + c = (define_find(tok) != 0) ^ c; do_if: if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE) tcc_error("memory full (ifdef)"); @@ -1564,12 +1595,12 @@ include_done: goto skip; c = expr_preprocess(); s1->ifdef_stack_ptr[-1] = c; -test_else: + test_else: if (s1->ifdef_stack_ptr == file->ifdef_stack_ptr + 1) file->ifndef_macro = 0; -test_skip: + test_skip: if (!(c & 1)) { -skip: + skip: preprocess_skip(); is_bof = 0; goto redo; @@ -1587,11 +1618,11 @@ skip: /* need to set to zero to avoid false matches if another #ifndef at middle of file */ file->ifndef_macro = 0; + while (tok != TOK_LINEFEED) + next_nomacro(); tok_flags |= TOK_FLAG_ENDIF; + goto the_end; } - next_nomacro(); - if (tok != TOK_LINEFEED) - tcc_warning("Ignoring: %s", get_tok_str(tok, &tokc)); break; case TOK_LINE: next(); @@ -1602,7 +1633,8 @@ skip: if (tok != TOK_LINEFEED) { if (tok != TOK_STR) tcc_error("#line"); - pstrcpy(file->filename, sizeof(file->filename), (char *)tokc.cstr->data); + pstrcpy(file->filename, sizeof(file->filename), + (char *)tokc.cstr->data); } break; case TOK_ERROR: @@ -1610,158 +1642,24 @@ skip: c = tok; ch = file->buf_ptr[0]; skip_spaces(); - p = buf; + q = buf; while (ch != '\n' && ch != CH_EOF) { - if ((p - buf) < sizeof(buf) - 1) - *p++ = ch; + if ((q - buf) < sizeof(buf) - 1) + *q++ = ch; if (ch == '\\') { if (handle_stray_noerror() == 0) - --p; + --q; } else inp(); } - *p = '\0'; + *q = '\0'; if (c == TOK_ERROR) tcc_error("#error %s", buf); else tcc_warning("#warning %s", buf); break; case TOK_PRAGMA: - next(); - if (tok == TOK_pack && s1->output_type != TCC_OUTPUT_PREPROCESS) { - /* - This may be: - #pragma pack(1) // set - #pragma pack() // reset to default - #pragma pack(push,1) // push & set - #pragma pack(pop) // restore previous - */ - next(); - skip('('); - if (tok == TOK_ASM_pop) { - next(); - if (s1->pack_stack_ptr <= s1->pack_stack) { -stk_error: - tcc_error("out of pack stack"); - } - s1->pack_stack_ptr--; - } else { - int val = 0; - if (tok != ')') { - if (tok == TOK_ASM_push) { - next(); - s1->pack_stack_ptr++; - if (s1->pack_stack_ptr >= s1->pack_stack + PACK_STACK_SIZE) - goto stk_error; - skip(','); - } - if (tok != TOK_CINT) { -pack_error: - tcc_error("invalid pack pragma"); - } - val = tokc.i; - if (val < 1 || val > 16) - goto pack_error; - if (val < 1 || val > 16) - tcc_error("Value must be greater than 1 is less than or equal to 16"); - if ((val & (val - 1)) != 0) - tcc_error("Value must be a power of 2 curtain"); - next(); - } - *s1->pack_stack_ptr = val; - skip(')'); - } - }else if (tok == TOK_PUSH_MACRO || tok == TOK_POP_MACRO) { - TokenSym *ts; - CSym *def; - uint8_t *p1; - int len, t; - t = tok; - ch = file->buf_ptr[0]; - skip_spaces(); - if (ch != '(') - goto macro_xxx_syntax; - /* XXX: incorrect if comments : use next_nomacro with a special mode */ - inp(); - skip_spaces(); - if (ch == '\"'){ - inp(); - p = buf; - while (ch != '\"' && ch != '\n' && ch != CH_EOF) { - if ((p - buf) < sizeof(buf) - 1) - *p++ = ch; - if (ch == CH_EOB) { - --p; - handle_stray(); - }else - inp(); - } - if(ch != '\"') - goto macro_xxx_syntax; - *p = '\0'; - minp(); - next(); - }else{ - /* computed #pragma macro_xxx for #define xxx */ - next(); - buf[0] = '\0'; - while (tok != ')') { - if (tok != TOK_STR) { - macro_xxx_syntax: - tcc_error("'macro_xxx' expects (\"NAME\")"); - } - pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data); - next(); - } - } - skip (')'); - if(!buf[0]) - tcc_error(" empty string in #pragma"); - /* find TokenSym */ - p = buf; - while (is_space(*p)) - p++; - p1 = p; - for(;;){ - if (!isidnum_table[p[0] - CH_EOF]) - break; - ++p; - } - len = p - p1; - while (is_space(*p)) - p++; - if(!p) //'\0' - tcc_error("unrecognized string: %s", buf); - ts = tok_alloc(p1, len); - if(ts){ - def = &ts->sym_define; - if(t == TOK_PUSH_MACRO){ - void *tmp = def->data[def->off]; - def->off++; - if(def->off >= def->size){ - int size = def->size; - size *= 2; - if (size > MACRO_STACK_SIZE) - tcc_error("stack full"); - def->data = tcc_realloc(def->data, size*sizeof(Sym*)); - def->size = size; - } - def->data[def->off] = tmp; - }else{ - if(def->off){ - --def->off; - } - } - } - }else if(s1->output_type == TCC_OUTPUT_PREPROCESS){ - fputs("#pragma ", s1->ppfp); - while (tok != TOK_LINEFEED){ - fputs(get_tok_str(tok, &tokc), s1->ppfp); - next(); - } - token_seen = 0;//printf '\n' - goto the_end; - } + pragma_parse(s1); break; default: if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_PPNUM) { @@ -1781,7 +1679,7 @@ pack_error: /* ignore other preprocess commands or #! for C scripts */ while (tok != TOK_LINEFEED) next_nomacro(); -the_end: + the_end: parse_flags = saved_parse_flags; } @@ -3230,7 +3128,7 @@ ST_FUNC int tcc_preprocess(TCCState *s1) Sym *define_start; BufferedFile *file_ref, **iptr, **iptr_new; - int line_ref, d; + int token_seen, line_ref, d; const char *s; preprocess_init(s1); @@ -3238,12 +3136,12 @@ ST_FUNC int tcc_preprocess(TCCState *s1) ch = file->buf_ptr[0]; tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; parse_flags = PARSE_FLAG_ASM_COMMENTS | PARSE_FLAG_PREPROCESS | - PARSE_FLAG_LINEFEED | PARSE_FLAG_SPACES; + PARSE_FLAG_LINEFEED | PARSE_FLAG_SPACES; + token_seen = 0; line_ref = 0; file_ref = NULL; iptr = s1->include_stack_ptr; - tok = TOK_LINEFEED; /* print line */ - goto print_line; + for (;;) { next(); if (tok == TOK_EOF) { @@ -3251,11 +3149,11 @@ ST_FUNC int tcc_preprocess(TCCState *s1) } else if (file != file_ref) { goto print_line; } else if (tok == TOK_LINEFEED) { - if (token_seen) + if (!token_seen) continue; ++line_ref; - token_seen = 1; - } else if (token_seen) { + token_seen = 0; + } else if (!token_seen) { d = file->line_num - line_ref; if (file != file_ref || d < 0 || d >= 8) { print_line: @@ -3263,7 +3161,8 @@ print_line: s = iptr_new > iptr ? " 1" : iptr_new < iptr ? " 2" : iptr_new > s1->include_stack ? " 3" - : ""; + : "" + ; iptr = iptr_new; fprintf(s1->ppfp, "# %d \"%s\"%s\n", file->line_num, file->filename, s); } else { @@ -3271,8 +3170,8 @@ print_line: fputs("\n", s1->ppfp), --d; } line_ref = (file_ref = file)->line_num; - token_seen = tok == TOK_LINEFEED; - if (token_seen) + token_seen = tok != TOK_LINEFEED; + if (!token_seen) continue; } fputs(get_tok_str(tok, &tokc), s1->ppfp); @@ -138,8 +138,6 @@ /* pragma */ DEF(TOK_pack, "pack") - DEF(TOK_PUSH_MACRO, "push_macro") - DEF(TOK_POP_MACRO, "pop_macro") #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_X86_64) /* already defined for assembler */ DEF(TOK_ASM_push, "push") diff --git a/tests/Makefile b/tests/Makefile index 9ace5b0..e3824ba 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -70,7 +70,7 @@ ifdef LIBTCC1 LIBTCC1:=$(TOP)/$(LIBTCC1) endif -all test : clean $(TESTS) +all test : $(TESTS) hello-exe: ../examples/ex1.c @echo ------------ $@ ------------ diff --git a/tests/abitest.c b/tests/abitest.c index e2978b0..d3e151f 100644 --- a/tests/abitest.c +++ b/tests/abitest.c @@ -88,7 +88,7 @@ static int ret_2float_test_callback(void *ptr) { ret_2float_test_type a = {10, 35}; ret_2float_test_type r; r = f(a); - return ((r.x == a.x*5) && (r.y == a.y*3) && (f(a).x == a.x*5) && (f(a).y == a.y*3)) ? 0 : -1; + return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1; } static int ret_2float_test(void) { @@ -116,7 +116,7 @@ static int ret_2double_test_callback(void *ptr) { ret_2double_test_type a = {10, 35}; ret_2double_test_type r; r = f(a); - return ((r.x == a.x*5) && (r.y == a.y*3) && (f(a).x == a.x*5) && (f(a).y == a.y*3)) ? 0 : -1; + return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1; } static int ret_2double_test(void) { @@ -130,50 +130,6 @@ static int ret_2double_test(void) { return run_callback(src, ret_2double_test_callback); } -typedef struct ret_longdouble_test_type_s2 {LONG_DOUBLE x;} ret_longdouble_test_type; -typedef ret_longdouble_test_type (*ret_longdouble_test_function_type) (ret_longdouble_test_type); - -static int ret_longdouble_test_callback2(void *ptr) { - ret_longdouble_test_function_type f = (ret_longdouble_test_function_type)ptr; - ret_longdouble_test_type a = {10}; - ret_longdouble_test_type r; - r = f(a); - return ((r.x == a.x*5) && (f(a).x == a.x*5)) ? 0 : -1; -} - -static int ret_longdouble_test2(void) { - const char *src = - "typedef struct ret_longdouble_test_type_s2 {long double x;} ret_longdouble_test_type;" - "ret_longdouble_test_type f(ret_longdouble_test_type a) {\n" - " ret_longdouble_test_type r = {a.x*5};\n" - " return r;\n" - "}\n"; - - return run_callback(src, ret_longdouble_test_callback2); -} - -typedef struct ret_longlong_test_type_s2 {int x[4];} ret_longlong_test_type; -typedef ret_longlong_test_type (*ret_longlong_test_function_type) (ret_longlong_test_type); - -static int ret_longlong_test_callback2(void *ptr) { - ret_longlong_test_function_type f = (ret_longlong_test_function_type)ptr; - ret_longlong_test_type a = {{10,11,12,13}}; - ret_longlong_test_type r; - r = f(a); - return ((r.x[2] == a.x[2]*5) && (f(a).x[2] == a.x[2]*5)) ? 0 : -1; -} - -static int ret_longlong_test2(void) { - const char *src = - "typedef struct ret_longlong_test_type_s2 {int x[4];} ret_longlong_test_type;" - "ret_longlong_test_type f(ret_longlong_test_type a) {\n" - " ret_longlong_test_type r = {.x[2] = a.x[2]*5};\n" - " return r;\n" - "}\n"; - - return run_callback(src, ret_longlong_test_callback2); -} - /* * reg_pack_test: return a small struct which should be packed into * registers (Win32) during return. @@ -186,7 +142,7 @@ static int reg_pack_test_callback(void *ptr) { reg_pack_test_type a = {10, 35}; reg_pack_test_type r; r = f(a); - return ((r.x == a.x*5) && (r.y == a.y*3) && (f(a).x == a.x*5) && (f(a).y == a.y*3)) ? 0 : -1; + return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1; } static int reg_pack_test(void) { @@ -212,7 +168,7 @@ static int reg_pack_longlong_test_callback(void *ptr) { reg_pack_longlong_test_type a = {10, 35}; reg_pack_longlong_test_type r; r = f(a); - return ((r.x == a.x*5) && (r.y == a.y*3) && (f(a).x == a.x*5) && (f(a).y == a.y*3)) ? 0 : -1; + return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1; } static int reg_pack_longlong_test(void) { @@ -292,7 +248,7 @@ static int two_member_union_test_callback(void *ptr) { two_member_union_test_type a, b; a.x = 34; b = f(a); - return ((b.x == a.x*2) && (f(a).x == a.x*2)) ? 0 : -1; + return (b.x == a.x*2) ? 0 : -1; } static int two_member_union_test(void) { @@ -485,11 +441,6 @@ int main(int argc, char **argv) { RUN_TEST(ret_longdouble_test); RUN_TEST(ret_2float_test); RUN_TEST(ret_2double_test); - RUN_TEST(ret_longlong_test2); -#if !defined _WIN32 || !defined __GNUC__ - /* on win32, 'long double' is 10-byte with gcc, but is 'double' with tcc/msvc */ - RUN_TEST(ret_longdouble_test2); -#endif RUN_TEST(reg_pack_test); RUN_TEST(reg_pack_longlong_test); RUN_TEST(sret_test); diff --git a/tests/tcctest.c b/tests/tcctest.c index 22a8278..cc8ffd8 100644 --- a/tests/tcctest.c +++ b/tests/tcctest.c @@ -155,8 +155,8 @@ static int onetwothree = 123; #define B3 4 #endif -#define __INT64_C(c) c ## LL -#define INT64_MIN (-__INT64_C(9223372036854775807)-1) +#define __INT64_C(c) c ## LL +#define INT64_MIN (-__INT64_C(9223372036854775807)-1) int qq(int x) { @@ -235,7 +235,7 @@ void intdiv_test(void) void macro_test(void) { - printf("macro:\n"); + printf("macro:\n");
pf("N=%d\n", N); printf("aaa=%d\n", AAA); @@ -379,55 +379,6 @@ comment /* And again when the name and parenthes are separated by a comment. */ TEST2 /* the comment */ (); - - /* macro_push and macro_pop test */ - #undef MACRO_TEST - #ifdef MACRO_TEST - printf("define MACRO_TEST\n"); - #else - printf("undef MACRO_TEST\n"); - #endif - - #pragma push_macro("MACRO_TEST") - #define MACRO_TEST - #pragma push_macro("MACRO_TEST") - #undef MACRO_TEST - #pragma push_macro("MACRO_TEST") - - #pragma pop_macro("MACRO_TEST") - #ifdef MACRO_TEST - printf("define MACRO_TEST\n"); - #else - printf("undef MACRO_TEST\n"); - #endif - - #pragma pop_macro("MACRO_TEST") - #ifdef MACRO_TEST - printf("define MACRO_TEST\n"); - #else - printf("undef MACRO_TEST\n"); - #endif - - #pragma pop_macro("MACRO_TEST") - #ifdef MACRO_TEST - printf("define MACRO_TEST\n"); - #else - printf("undef MACRO_TEST\n"); - #endif - - /* pack test */ - #pragma pack(push,8) - #pragma pack(pop) - -/* gcc does not support - #define MACRO_TEST_MACRO "MACRO_TEST" - #pragma push_macro(MACRO_TEST_MACRO) - #undef MACRO_TEST - #define MACRO_TEST "macro_test3\n" - printf(MACRO_TEST); - #pragma pop_macro(MACRO_TEST_MACRO) - printf(MACRO_TEST); -*/ } @@ -1444,30 +1395,30 @@ struct complexinit { const static struct complexinit cix[] = { [0] = { - .a = 2000, - .b = (const struct complexinit0[]) { - { 2001, 2002 }, - { 2003, 2003 }, - {} - } + .a = 2000, + .b = (const struct complexinit0[]) { + { 2001, 2002 }, + { 2003, 2003 }, + {} + } } }; struct complexinit2 { - int a; - int b[]; + int a; + int b[]; }; struct complexinit2 cix20; struct complexinit2 cix21 = { - .a = 3000, - .b = { 3001, 3002, 3003 } + .a = 3000, + .b = { 3001, 3002, 3003 } }; struct complexinit2 cix22 = { - .a = 4000, - .b = { 4001, 4002, 4003, 4004, 4005, 4006 } + .a = 4000, + .b = { 4001, 4002, 4003, 4004, 4005, 4006 } }; void init_test(void) @@ -1564,10 +1515,10 @@ void init_test(void) printf("\n"); /* complex init check */ printf("cix: %d %d %d %d %d %d %d\n", - cix[0].a, - cix[0].b[0].a, cix[0].b[0].b, - cix[0].b[1].a, cix[0].b[1].b, - cix[0].b[2].a, cix[0].b[2].b); + cix[0].a, + cix[0].b[0].a, cix[0].b[0].b, + cix[0].b[1].a, cix[0].b[1].b, + cix[0].b[2].a, cix[0].b[2].b); printf("cix2: %d %d\n", cix21.b[2], cix22.b[5]); printf("sizeof cix20 %d, cix21 %d, sizeof cix22 %d\n", sizeof cix20, sizeof cix21, sizeof cix22); } @@ -1729,6 +1680,7 @@ void prefix ## fcast(type a)\ printf("ftof: %f %f %Lf\n", fa, da, la);\ ia = (int)a;\ llia = (long long)a;\ + a = (a >= 0) ? a : -a;\ ua = (unsigned int)a;\ llua = (unsigned long long)a;\ printf("ftoi: %d %u %lld %llu\n", ia, ua, llia, llua);\ @@ -1758,18 +1710,6 @@ void prefix ## call(void)\ printf("strto%s: %f\n", #prefix, (double)strto ## prefix("1.2", NULL));\ }\ \ -void prefix ## calc(type x, type y)\ -{\ - x=x*x;y=y*y;\ - printf("%d, %d\n", (int)x, (int)y);\ - x=x-y;y=y-x;\ - printf("%d, %d\n", (int)x, (int)y);\ - x=x/y;y=y/x;\ - printf("%d, %d\n", (int)x, (int)y);\ - x=x+x;y=y+y;\ - printf("%d, %d\n", (int)x, (int)y);\ -}\ -\ void prefix ## signed_zeros(void) \ {\ type x = 0.0, y = -0.0, n, p;\ @@ -1792,7 +1732,7 @@ void prefix ## signed_zeros(void) \ 1.0 / x != 1.0 / p);\ else\ printf ("x != +y; this is wrong!\n");\ - p = -y;\ + p = -y;\ if (x == p)\ printf ("Test 1.0 / x != 1.0 / -y returns %d (should be 0).\n",\ 1.0 / x != 1.0 / p);\ @@ -1808,7 +1748,6 @@ void prefix ## test(void)\ prefix ## fcast(234.6);\ prefix ## fcast(-2334.6);\ prefix ## call();\ - prefix ## calc(1, 1.0000000000000001);\ prefix ## signed_zeros();\ } @@ -2216,15 +2155,14 @@ void whitespace_test(void) { char *str; - -#if 1 +
#if 1 pri\ -ntf("whitspace:\n"); +ntf("whitspace:\n");
#endif pf("N=%d\n", 2); #ifdef CORRECT_CR_HANDLING - pri\ + pri\
ntf("aaa=%d\n", 3); #endif @@ -2236,12 +2174,11 @@ ntf("min=%d\n", 4); printf("len1=%d\n", strlen(" ")); #ifdef CORRECT_CR_HANDLING - str = " + str = "
"; printf("len1=%d str[0]=%d\n", strlen(str), str[0]); #endif - printf("len1=%d\n", strlen(" -a + printf("len1=%d\n", strlen("
a ")); #endif /* ACCEPT_CR_IN_STRINGS */ } @@ -2466,21 +2403,21 @@ static char * strncat1(char * dest,const char * src,size_t count) { int d0, d1, d2, d3; __asm__ __volatile__( - "repne\n\t" - "scasb\n\t" - "decl %1\n\t" - "movl %8,%3\n" - "1:\tdecl %3\n\t" - "js 2f\n\t" - "lodsb\n\t" - "stosb\n\t" - "testb %%al,%%al\n\t" - "jne 1b\n" - "2:\txorl %2,%2\n\t" - "stosb" - : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3) - : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count) - : "memory"); + "repne\n\t" + "scasb\n\t" + "decl %1\n\t" + "movl %8,%3\n" + "1:\tdecl %3\n\t" + "js 2f\n\t" + "lodsb\n\t" + "stosb\n\t" + "testb %%al,%%al\n\t" + "jne 1b\n" + "2:\txorl %2,%2\n\t" + "stosb" + : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3) + : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count) + : "memory"); return dest; } @@ -2488,20 +2425,20 @@ static char * strncat2(char * dest,const char * src,size_t count) { int d0, d1, d2, d3; __asm__ __volatile__( - "repne scasb\n\t" /* one-line repne prefix + string op */ - "decl %1\n\t" - "movl %8,%3\n" - "1:\tdecl %3\n\t" - "js 2f\n\t" - "lodsb\n\t" - "stosb\n\t" - "testb %%al,%%al\n\t" - "jne 1b\n" - "2:\txorl %2,%2\n\t" - "stosb" - : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3) - : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count) - : "memory"); + "repne scasb\n\t" /* one-line repne prefix + string op */ + "decl %1\n\t" + "movl %8,%3\n" + "1:\tdecl %3\n\t" + "js 2f\n\t" + "lodsb\n\t" + "stosb\n\t" + "testb %%al,%%al\n\t" + "jne 1b\n" + "2:\txorl %2,%2\n\t" + "stosb" + : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3) + : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count) + : "memory"); return dest; } @@ -2509,17 +2446,17 @@ static inline void * memcpy1(void * to, const void * from, size_t n) { int d0, d1, d2; __asm__ __volatile__( - "rep ; movsl\n\t" - "testb $2,%b4\n\t" - "je 1f\n\t" - "movsw\n" - "1:\ttestb $1,%b4\n\t" - "je 2f\n\t" - "movsb\n" - "2:" - : "=&c" (d0), "=&D" (d1), "=&S" (d2) - :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from) - : "memory"); + "rep ; movsl\n\t" + "testb $2,%b4\n\t" + "je 1f\n\t" + "movsw\n" + "1:\ttestb $1,%b4\n\t" + "je 2f\n\t" + "movsb\n" + "2:" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from) + : "memory"); return (to); } @@ -2527,38 +2464,38 @@ static inline void * memcpy2(void * to, const void * from, size_t n) { int d0, d1, d2; __asm__ __volatile__( - "rep movsl\n\t" /* one-line rep prefix + string op */ - "testb $2,%b4\n\t" - "je 1f\n\t" - "movsw\n" - "1:\ttestb $1,%b4\n\t" - "je 2f\n\t" - "movsb\n" - "2:" - : "=&c" (d0), "=&D" (d1), "=&S" (d2) - :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from) - : "memory"); + "rep movsl\n\t" /* one-line rep prefix + string op */ + "testb $2,%b4\n\t" + "je 1f\n\t" + "movsw\n" + "1:\ttestb $1,%b4\n\t" + "je 2f\n\t" + "movsb\n" + "2:" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from) + : "memory"); return (to); } static __inline__ void sigaddset1(unsigned int *set, int _sig) { - __asm__("btsl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc"); + __asm__("btsl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc"); } static __inline__ void sigdelset1(unsigned int *set, int _sig) { - asm("btrl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc"); + asm("btrl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc"); } static __inline__ __const__ unsigned int swab32(unsigned int x) { - __asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */ - "rorl $16,%0\n\t" /* swap words */ - "xchgb %b0,%h0" /* swap higher bytes */ - :"=q" (x) - : "0" (x)); - return x; + __asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */ + "rorl $16,%0\n\t" /* swap words */ + "xchgb %b0,%h0" /* swap higher bytes */ + :"=q" (x) + : "0" (x)); + return x; } static __inline__ unsigned long long mul64(unsigned int a, unsigned int b) @@ -2635,6 +2572,7 @@ int constant_p_var; void builtin_test(void) { +#if GCC_MAJOR >= 3 COMPAT_TYPE(int, int); COMPAT_TYPE(int, unsigned int); COMPAT_TYPE(int, char); @@ -2644,9 +2582,9 @@ void builtin_test(void) COMPAT_TYPE(int *, void *); COMPAT_TYPE(int *, const int *); COMPAT_TYPE(char *, unsigned char *); - COMPAT_TYPE(char, unsigned char); /* space is needed because tcc preprocessor introduces a space between each token */ - COMPAT_TYPE(char **, void *); + COMPAT_TYPE(char * *, void *); +#endif printf("res = %d\n", __builtin_constant_p(1)); printf("res = %d\n", __builtin_constant_p(1 + 2)); printf("res = %d\n", __builtin_constant_p(&constant_p_var)); @@ -2686,23 +2624,23 @@ int weak_toolate() { return 0; } void __attribute__((weak)) weak_test(void) { - printf("weak_f1=%d\n", weak_f1 ? weak_f1() : 123); - printf("weak_f2=%d\n", weak_f2 ? weak_f2() : 123); - printf("weak_f3=%d\n", weak_f3 ? weak_f3() : 123); - printf("weak_v1=%d\n",&weak_v1 ? weak_v1 : 123); - printf("weak_v2=%d\n",&weak_v2 ? weak_v2 : 123); - printf("weak_v3=%d\n",&weak_v3 ? weak_v3 : 123); + printf("weak_f1=%d\n", weak_f1 ? weak_f1() : 123); + printf("weak_f2=%d\n", weak_f2 ? weak_f2() : 123); + printf("weak_f3=%d\n", weak_f3 ? weak_f3() : 123); + printf("weak_v1=%d\n",&weak_v1 ? weak_v1 : 123); + printf("weak_v2=%d\n",&weak_v2 ? weak_v2 : 123); + printf("weak_v3=%d\n",&weak_v3 ? weak_v3 : 123); - printf("weak_fpa=%d\n",&weak_fpa ? weak_fpa() : 123); - printf("weak_fpb=%d\n",&weak_fpb ? weak_fpb() : 123); - printf("weak_fpc=%d\n",&weak_fpc ? weak_fpc() : 123); - - printf("weak_asm_f1=%d\n", weak_asm_f1 != NULL); - printf("weak_asm_f2=%d\n", weak_asm_f2 != NULL); - printf("weak_asm_f3=%d\n", weak_asm_f3 != NULL); - printf("weak_asm_v1=%d\n",&weak_asm_v1 != NULL); - printf("weak_asm_v2=%d\n",&weak_asm_v2 != NULL); - printf("weak_asm_v3=%d\n",&weak_asm_v3 != NULL); + printf("weak_fpa=%d\n",&weak_fpa ? weak_fpa() : 123); + printf("weak_fpb=%d\n",&weak_fpb ? weak_fpb() : 123); + printf("weak_fpc=%d\n",&weak_fpc ? weak_fpc() : 123); + + printf("weak_asm_f1=%d\n", weak_asm_f1 != NULL); + printf("weak_asm_f2=%d\n", weak_asm_f2 != NULL); + printf("weak_asm_f3=%d\n", weak_asm_f3 != NULL); + printf("weak_asm_v1=%d\n",&weak_asm_v1 != NULL); + printf("weak_asm_v2=%d\n",&weak_asm_v2 != NULL); + printf("weak_asm_v3=%d\n",&weak_asm_v3 != NULL); } int __attribute__((weak)) weak_f2() { return 222; } diff --git a/tests/tests2/66_macro_concat_end.expect b/tests/tests2/66_macro_concat_end.expect index 8dbf5bb..224e5c9 100644 --- a/tests/tests2/66_macro_concat_end.expect +++ b/tests/tests2/66_macro_concat_end.expect @@ -1 +1 @@ -66_macro_concat_end.c:1: error: '##' invalid at end of macro +66_macro_concat_end.c:2: error: '##' invalid at end of macro diff --git a/x86_64-gen.c b/x86_64-gen.c index c9829f0..c8fed85 100644 --- a/x86_64-gen.c +++ b/x86_64-gen.c @@ -985,7 +985,7 @@ static X86_64_Mode classify_x86_64_inner(CType *ty) return x86_64_mode_memory; mode = x86_64_mode_none; - for (f = f->next; f; f = f->next) + for (; f; f = f->next) mode = classify_x86_64_merge(mode, classify_x86_64_inner(&f->type)); return mode; @@ -1276,7 +1276,7 @@ void gfunc_call(int nb_args) g(0x00); args_size += size; } else { - //assert(mode == x86_64_mode_memory); + assert(mode == x86_64_mode_memory); /* allocate the necessary size on stack */ o(0x48); @@ -1408,7 +1408,7 @@ void gfunc_prolog(CType *func_type) break; case x86_64_mode_integer: - if (seen_reg_num + reg_count <= REGN) { + if (seen_reg_num + reg_count <= 8) { seen_reg_num += reg_count; } else { seen_reg_num = 8; |
