History

'long' review

add some features for more complete 'long' support tcc.h: - use LONG_SIZE=4/8 instead of TCC_LONG_ARE_64_BIT tccgen.c: - add ptrdiff_type, update size_type - support shift and ?: operations - support long enum types - display 'long' from type_to_str - nwchar_t is unsigned short on windows - unrelated: use memcpy in init_putv for long doubles to avoid random bytes in the image (if tcc was compiled by gcc) for diff purposes. tccpp.c: - make parse_number return correct types - improve multi-character-constants 'XX' 'abcd' Changelog: - update

grischka committed 9 years ago

Commit 14430391 parent 870271e6 files · +164 −176Browse files

Unified · Split

6 files
  1. Changelog +4 −2
  2. libtcc.c +7 −7
  3. tcc.h +11 −12
  4. tccgen.c +83 −90
  5. tccpp.c +58 −64
  6. win32/build-tcc.bat +1 −1
Changelog+4−2
@@ -9,11 +9,10 @@ User interface: · 8 unmodified lines
99 - -mno-sse on x86-64 disables use of SSE instructions
1010 - @listfile support (Vlad Vissoultchev)
1111 - tcc -ar/-impdef - formerly tiny_xxx tools integrated (grischka)
12−- CPATH, C_INCLUDE_PATH and LD_LIBRARY_PATH environment variables support
12+- CPATH, C_INCLUDE_PATH and LIBRARY_PATH environment variables support
1313 (Andrew Aladjev, Urs Janssen)
1414
1515 Platforms:
16−- Bootstrap native Windows 32/64 compiler using Cygwin+gcc (Christian Jullien)
1716 - new AARCH64 (arm64) target (Edmund Grimley Evans)
1817 - vastly improved support for ARM hard float calling convention
1918 (Thomas Preud'homme, Daniel Glöckner)
@@ -22,6 +21,7 @@ Platforms: · 2 unmodified lines
2221 - ABI tests with native compiler using libtcc (James Lyon)
2322 - UNICODE startup code supports wmain and wWinMain (YX Hao)
2423 - shared libraries for x86_64 (Michael Matz)
24+- Bootstrap native Windows 32/64 compiler using Cygwin+gcc (Christian Jullien)
2525
2626 Features:
2727 - VLA (variable length array) improved (James Lyon, Pip Cet)
@@ -35,6 +35,8 @@ Features: · 7 unmodified lines
3535 - standard conforming (and GCC compatible) struct initialization
3636 (Michael Matz)
3737 - bit-field layout made compatible with GCC (Michael Matz)
38+- UTF8 in string literals supported (Zdenek Pavlas)
39+_ _Generic(...) supported (Matthias Gatto)
3840
3941 Licensing:
4042 - TinyCC partly relicensed to MIT license (See RELICENSING file).
libtcc.c+7−7
@@ -836,21 +836,21 @@ LIBTCCAPI TCCState *tcc_new(void) · 835 unmodified lines
836836 # endif
837837
838838 /* TinyCC & gcc defines */
839−#if defined(TCC_TARGET_PE) && PTR_SIZE == 8
839+#if PTR_SIZE == 4
840+ /* 32bit systems. */
841+ tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned int");
842+ tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int");
843+ tcc_define_symbol(s, "__ILP32__", NULL);
844+#elif LONG_SIZE == 4
840845 /* 64bit Windows. */
841846 tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned long long");
842847 tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long long");
843848 tcc_define_symbol(s, "__LLP64__", NULL);
844−#elif PTR_SIZE == 8
849+#else
845850 /* Other 64bit systems. */
846851 tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned long");
847852 tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long");
848853 tcc_define_symbol(s, "__LP64__", NULL);
849−#else
850− /* Other 32bit systems. */
851− tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned int");
852− tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int");
853− tcc_define_symbol(s, "__ILP32__", NULL);
854854 #endif
855855
856856 #if defined(TCC_MUSL)
tcc.h+11−12
@@ -361,6 +361,12 @@ extern long double strtold (const char *__nptr, char **__endptr); · 360 unmodified lines
361361 /* target address type */
362362 #define addr_t ElfW(Addr)
363363
364+#if PTR_SIZE == 8 && !defined TCC_TARGET_PE
365+# define LONG_SIZE 8
366+#else
367+# define LONG_SIZE 4
368+#endif
369+
364370 /* -------------------------------------------- */
365371
366372 #define INCLUDE_STACK_SIZE 32
@@ -880,14 +886,14 @@ struct filespec { · 513 unmodified lines
880886 #define VT_CONSTANT 0x0100 /* const modifier */
881887 #define VT_VOLATILE 0x0200 /* volatile modifier */
882888 #define VT_VLA 0x0400 /* VLA type (also has VT_PTR and VT_ARRAY) */
883−#define VT_LONG 0x0800
889+#define VT_LONG 0x0800 /* long type (also has VT_INT rsp. VT_LLONG) */
884890
885891 /* storage */
886892 #define VT_EXTERN 0x00001000 /* extern definition */
887893 #define VT_STATIC 0x00002000 /* static variable */
888894 #define VT_TYPEDEF 0x00004000 /* typedef definition */
889895 #define VT_INLINE 0x00008000 /* inline definition */
890−/* currently unused: 0x0800, 0x000[1248]0000 */
896+/* currently unused: 0x000[1248]0000 */
891897
892898 #define VT_STRUCT_SHIFT 20 /* shift for bitfield shift values (32 - 2*6) */
893899 #define VT_STRUCT_MASK (((1 << (6+6)) - 1) << VT_STRUCT_SHIFT | VT_BITFIELD)
@@ -906,7 +912,6 @@ struct filespec { · 12 unmodified lines
906912 #define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)
907913 #define VT_TYPE (~(VT_STORAGE|VT_STRUCT_MASK))
908914
909−
910915 /* token values */
911916
912917 /* warning: the following compare tokens depend on i386 asm code */
@@ -947,6 +952,7 @@ struct filespec { · 34 unmodified lines
947952 #define TOK_PPNUM 0xbe /* preprocessor number */
948953 #define TOK_PPSTR 0xbf /* preprocessor string */
949954 #define TOK_LINENUM 0xc0 /* line number info */
955+#define TOK_TWODOTS 0xa8 /* C++ token ? */
950956 /* <-- */
951957
952958 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
@@ -961,15 +967,8 @@ struct filespec { · 8 unmodified lines
961967 #define TOK_PLCHLDR 0xcb /* placeholder token as defined in C99 */
962968 #define TOK_NOSUBST 0xcc /* means following token has already been pp'd */
963969 #define TOK_PPJOIN 0xcd /* A '##' in the right position to mean pasting */
964−
965−#define TOK_CLONG 0xce /* long constant */
966−#define TOK_CULONG 0xcf /* unsigned long constant */
967−
968−
969−#if defined TCC_TARGET_X86_64 && !defined TCC_TARGET_PE
970− #define TCC_LONG_ARE_64_BIT
971−#endif
972−
970+#define TOK_CLONG 0xce /* long constant */
971+#define TOK_CULONG 0xcf /* unsigned long constant */
973972
974973 #define TOK_SHL 0x01 /* shift left */
975974 #define TOK_SAR 0x02 /* signed shift right */
tccgen.c+83−90
@@ -61,7 +61,7 @@ ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc · 60 unmodified lines
6161 ST_DATA const char *funcname;
6262 ST_DATA int g_debug;
6363
64−ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
64+ST_DATA CType char_pointer_type, func_old_type, int_type, size_type, ptrdiff_type;
6565
6666 ST_DATA struct switch_t {
6767 struct case_t {
@@ -240,9 +240,14 @@ ST_FUNC int tccgen_compile(TCCState *s1) · 172 unmodified lines
240240 char_pointer_type.t = VT_BYTE;
241241 mk_pointer(&char_pointer_type);
242242 #if PTR_SIZE == 4
243− size_type.t = VT_INT;
243+ size_type.t = VT_INT | VT_UNSIGNED;
244+ ptrdiff_type.t = VT_INT;
245+#elif LONG_SIZE == 4
246+ size_type.t = VT_LLONG | VT_UNSIGNED;
247+ ptrdiff_type.t = VT_LLONG;
244248 #else
245− size_type.t = VT_LLONG;
249+ size_type.t = VT_LONG | VT_LLONG | VT_UNSIGNED;
250+ ptrdiff_type.t = VT_LONG | VT_LLONG;
246251 #endif
247252 func_old_type.t = VT_FUNC;
248253 func_old_type.ref = sym_push(SYM_FIELD, &int_type, 0, 0);
@@ -2127,12 +2132,7 @@ redo: · 1878 unmodified lines
21272132 }
21282133 vrott(3);
21292134 gen_opic(op);
2130− /* set to integer type */
2131−#if PTR_SIZE == 8
2132− vtop->type.t = VT_LLONG;
2133−#else
2134− vtop->type.t = VT_INT;
2135−#endif
2135+ vtop->type.t = ptrdiff_type.t;
21362136 vswap();
21372137 gen_op(TOK_PDIV);
21382138 } else {
@@ -2218,14 +2218,15 @@ redo: · 79 unmodified lines
22182218 t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
22192219 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (t | VT_UNSIGNED))
22202220 t |= VT_UNSIGNED;
2221+ t |= (VT_LONG & t1);
22212222 goto std_op;
22222223 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
22232224 /* cast to biggest op */
2224− t = VT_LLONG;
2225− /* check if we need to keep type as long or as long long */
2226− if ((t1 & VT_LONG && (t2 & (VT_BTYPE | VT_LONG)) != VT_LLONG) ||
2227− (t2 & VT_LONG && (t1 & (VT_BTYPE | VT_LONG)) != VT_LLONG))
2228− t |= VT_LONG;
2225+ t = VT_LLONG | VT_LONG;
2226+ if (bt1 == VT_LLONG)
2227+ t &= t1;
2228+ if (bt2 == VT_LLONG)
2229+ t &= t2;
22292230 /* convert to unsigned if it does not fit in a long long */
22302231 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) ||
22312232 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED))
@@ -2233,12 +2234,8 @@ redo: · 1 unmodified line
22332234 goto std_op;
22342235 } else {
22352236 /* integer operations */
2236− t = VT_INT;
2237−
2238− if ((t1 & VT_LONG) || (t2 & VT_LONG))
2239− t |= VT_LONG;
2240−
2241− /* convert to unsigned if it does not fit in an integer */
2237+ t = VT_INT | (VT_LONG & (t1 | t2));
2238+ /* convert to unsigned if it does not fit in an integer */
22422239 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) ||
22432240 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED))
22442241 t |= VT_UNSIGNED;
@@ -2741,7 +2738,6 @@ static int compare_types(CType *type1, CType *type2, int unqualified) · 496 unmodified lines
27412738 t1 &= ~VT_DEFSIGN;
27422739 t2 &= ~VT_DEFSIGN;
27432740 }
2744−
27452741 /* XXX: bitfields ? */
27462742 if (t1 != t2)
27472743 return 0;
@@ -2790,14 +2786,7 @@ static void type_to_str(char *buf, int buf_size, · 42 unmodified lines
27902786 t = type->t;
27912787 bt = t & VT_BTYPE;
27922788 buf[0] = '\0';
2793− if (t & VT_CONSTANT)
2794− pstrcat(buf, buf_size, "const ");
2795− if (t & VT_VOLATILE)
2796− pstrcat(buf, buf_size, "volatile ");
2797− if ((t & (VT_DEFSIGN | VT_UNSIGNED)) == (VT_DEFSIGN | VT_UNSIGNED))
2798− pstrcat(buf, buf_size, "unsigned ");
2799− else if (t & VT_DEFSIGN)
2800− pstrcat(buf, buf_size, "signed ");
2789+
28012790 if (t & VT_EXTERN)
28022791 pstrcat(buf, buf_size, "extern ");
28032792 if (t & VT_STATIC)
@@ -2806,17 +2795,20 @@ static void type_to_str(char *buf, int buf_size, · 2 unmodified lines
28062795 pstrcat(buf, buf_size, "typedef ");
28072796 if (t & VT_INLINE)
28082797 pstrcat(buf, buf_size, "inline ");
2798+ if (t & VT_VOLATILE)
2799+ pstrcat(buf, buf_size, "volatile ");
2800+ if (t & VT_CONSTANT)
2801+ pstrcat(buf, buf_size, "const ");
2802+
2803+ if (((t & VT_DEFSIGN) && bt == VT_BYTE)
2804+ || ((t & VT_UNSIGNED)
2805+ && (bt == VT_SHORT || bt == VT_INT || bt == VT_LLONG)
2806+ && !IS_ENUM(t)
2807+ ))
2808+ pstrcat(buf, buf_size, (t & VT_UNSIGNED) ? "unsigned " : "signed ");
2809+
28092810 buf_size -= strlen(buf);
28102811 buf += strlen(buf);
2811− if (IS_ENUM(t)) {
2812− tstr = "enum ";
2813− goto tstruct;
2814− }
2815−
2816− if (!bt && VT_LONG & t) {
2817− tstr = "long";
2818− goto add_tstr;
2819− }
28202812
28212813 switch(bt) {
28222814 case VT_VOID:
@@ -2833,10 +2825,16 @@ static void type_to_str(char *buf, int buf_size, · 10 unmodified lines
28332825 goto add_tstr;
28342826 case VT_INT:
28352827 tstr = "int";
2836− goto add_tstr;
2828+ goto maybe_long;
28372829 case VT_LLONG:
28382830 tstr = "long long";
2839− goto add_tstr;
2831+ maybe_long:
2832+ if (t & VT_LONG)
2833+ tstr = "long";
2834+ if (!IS_ENUM(t))
2835+ goto add_tstr;
2836+ tstr = "enum ";
2837+ goto tstruct;
28402838 case VT_FLOAT:
28412839 tstr = "float";
28422840 goto add_tstr;
@@ -2902,7 +2900,7 @@ static void type_to_str(char *buf, int buf_size, · 59 unmodified lines
29022900 casts if needed. */
29032901 static void gen_assign_cast(CType *dt)
29042902 {
2905− CType *st, *type1, *type2, tmp_type1, tmp_type2;
2903+ CType *st, *type1, *type2;
29062904 char buf1[256], buf2[256];
29072905 int dbt, sbt;
29082906
@@ -2958,7 +2956,7 @@ static void gen_assign_cast(CType *dt) · 49 unmodified lines
29582956 in pointer target signedness. Do warn for different
29592957 base types, though, in particular for unsigned enums
29602958 and signed int targets. */
2961− if ((type1->t & VT_BTYPE) != (type2->t & VT_BTYPE)
2959+ if ((type1->t & (VT_BTYPE|VT_LONG)) != (type2->t & (VT_BTYPE|VT_LONG))
29622960 || IS_ENUM(type1->t) || IS_ENUM(type2->t)
29632961 )
29642962 tcc_warning("assignment from incompatible pointer type");
@@ -2982,11 +2980,7 @@ static void gen_assign_cast(CType *dt) · 17 unmodified lines
29822980 break;
29832981 case VT_STRUCT:
29842982 case_VT_STRUCT:
2985− tmp_type1 = *dt;
2986− tmp_type2 = *st;
2987− tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
2988− tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
2989− if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2983+ if (!is_compatible_unqualified_types(dt, st)) {
29902984 error:
29912985 type_to_str(buf1, sizeof(buf1), st, NULL);
29922986 type_to_str(buf2, sizeof(buf2), dt, NULL);
@@ -3775,10 +3769,10 @@ do_decl: · 782 unmodified lines
37753769 t.t = VT_INT;
37763770 if (nl >= 0) {
37773771 if (pl != (unsigned)pl)
3778− t.t = VT_LLONG;
3772+ t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
37793773 t.t |= VT_UNSIGNED;
37803774 } else if (pl != (int)pl || nl != (int)nl)
3781− t.t = VT_LLONG;
3775+ t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
37823776 s->type.t = type->t = t.t | VT_ENUM;
37833777 s->c = 0;
37843778 /* set type for enum members */
@@ -3791,7 +3785,8 @@ do_decl: · 6 unmodified lines
37913785 if (ll == (unsigned)ll)
37923786 continue;
37933787 }
3794− ss->type.t = (ss->type.t & ~VT_BTYPE) | VT_LLONG;
3788+ ss->type.t = (ss->type.t & ~VT_BTYPE)
3789+ | (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
37953790 }
37963791 } else {
37973792 c = 0;
@@ -3964,7 +3959,7 @@ static int parse_btype(CType *type, AttributeDef *ad) · 166 unmodified lines
39643959 bt = u;
39653960 }
39663961 if (u != VT_INT)
3967− t = (t & ~VT_BTYPE) | u;
3962+ t = (t & ~(VT_BTYPE|VT_LONG)) | u;
39683963 typespec_found = 1;
39693964 break;
39703965 case TOK_VOID:
@@ -3978,11 +3973,9 @@ static int parse_btype(CType *type, AttributeDef *ad) · 7 unmodified lines
39783973 goto basic_type;
39793974 case TOK_LONG:
39803975 if ((t & VT_BTYPE) == VT_DOUBLE) {
3981−#ifndef TCC_TARGET_PE
3982− t = (t & ~(VT_LONG | VT_BTYPE)) | VT_LDOUBLE;
3983−#endif
3984− } else if (t & VT_LONG) {
3985− t = (t & ~(VT_LONG | VT_BTYPE)) | VT_LLONG;
3976+ t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE;
3977+ } else if ((t & (VT_BTYPE|VT_LONG)) == VT_LONG) {
3978+ t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LLONG;
39863979 } else {
39873980 u = VT_LONG;
39883981 goto basic_type;
@@ -4003,12 +3996,8 @@ static int parse_btype(CType *type, AttributeDef *ad) · 14 unmodified lines
40033996 u = VT_FLOAT;
40043997 goto basic_type;
40053998 case TOK_DOUBLE:
4006− if (t & VT_LONG) {
4007−#ifdef TCC_TARGET_PE
4008− t = (t & ~(VT_LONG | VT_BTYPE)) | VT_DOUBLE;
4009−#else
4010− t = (t & ~(VT_LONG | VT_BTYPE)) | VT_LDOUBLE;
4011−#endif
3999+ if ((t & (VT_BTYPE|VT_LONG)) == VT_LONG) {
4000+ t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE;
40124001 } else {
40134002 u = VT_DOUBLE;
40144003 goto basic_type;
@@ -4098,7 +4087,7 @@ static int parse_btype(CType *type, AttributeDef *ad) · 83 unmodified lines
40984087 parse_attribute(ad);
40994088 if (ad->attr_mode) {
41004089 u = ad->attr_mode -1;
4101− t = (t & ~VT_BTYPE) | u;
4090+ t = (t & ~(VT_BTYPE|VT_LONG)) | u;
41024091 }
41034092 break;
41044093 /* GNUC typeof */
@@ -4118,7 +4107,7 @@ static int parse_btype(CType *type, AttributeDef *ad) · 13 unmodified lines
41184107 s = sym_find(tok);
41194108 if (!s || !(s->type.t & VT_TYPEDEF))
41204109 goto the_end;
4121− t &= ~VT_BTYPE;
4110+ t &= ~(VT_BTYPE|VT_LONG);
41224111 u = t & ~(VT_CONSTANT | VT_VOLATILE), t ^= u;
41234112 type->t = (s->type.t & ~VT_TYPEDEF) | u;
41244113 type->ref = s->type.ref;
@@ -4139,13 +4128,13 @@ the_end: · 14 unmodified lines
41394128 if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE)
41404129 t |= VT_UNSIGNED;
41414130 }
4142−
4143− /* long is never used as type */
4144− if (t & VT_LONG)
4145−#if PTR_SIZE == 8 && !defined TCC_TARGET_PE
4146− t = (t & ~VT_BTYPE) | VT_LLONG;
4147−#else
4148− t = (t & ~VT_BTYPE) | VT_INT;
4131+ /* VT_LONG is used just as a modifier for VT_INT / VT_LLONG */
4132+ bt = t & (VT_BTYPE|VT_LONG);
4133+ if (bt == VT_LONG)
4134+ t |= LONG_SIZE == 8 ? VT_LLONG : VT_INT;
4135+#ifdef TCC_TARGET_PE
4136+ if (bt == VT_LDOUBLE)
4137+ t = (t & ~(VT_BTYPE|VT_LONG)) | VT_DOUBLE;
41494138 #endif
41504139 type->t = t;
41514140 return type_found;
@@ -4544,9 +4533,13 @@ ST_FUNC void unary(void) · 392 unmodified lines
45444533 case TOK_EXTENSION:
45454534 next();
45464535 goto tok_next;
4536+ case TOK_LCHAR:
4537+#ifdef TCC_TARGET_PE
4538+ t = VT_SHORT|VT_UNSIGNED;
4539+ goto push_tokc;
4540+#endif
45474541 case TOK_CINT:
45484542 case TOK_CCHAR:
4549− case TOK_LCHAR:
45504543 t = VT_INT;
45514544 push_tokc:
45524545 type.t = t;
@@ -4572,14 +4565,10 @@ ST_FUNC void unary(void) · 19 unmodified lines
45724565 t = VT_LDOUBLE;
45734566 goto push_tokc;
45744567 case TOK_CLONG:
4568+ t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG;
4569+ goto push_tokc;
45754570 case TOK_CULONG:
4576− #ifdef TCC_LONG_ARE_64_BIT
4577− t = VT_LLONG | VT_LONG;
4578− #else
4579− t = VT_INT | VT_LONG;
4580− #endif
4581− if (tok == TOK_CULONG)
4582− t |= VT_UNSIGNED;
4571+ t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG | VT_UNSIGNED;
45834572 goto push_tokc;
45844573 case TOK___FUNCTION__:
45854574 if (!gnu_ext)
@@ -5491,7 +5480,11 @@ static void expr_cond(void) · 905 unmodified lines
54915480 }
54925481 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
54935482 /* cast to biggest op */
5494− type.t = VT_LLONG;
5483+ type.t = VT_LLONG | VT_LONG;
5484+ if (bt1 == VT_LLONG)
5485+ type.t &= t1;
5486+ if (bt2 == VT_LLONG)
5487+ type.t &= t2;
54955488 /* convert to unsigned if it does not fit in a long long */
54965489 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) ||
54975490 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED))
@@ -5518,7 +5511,7 @@ static void expr_cond(void) · 20 unmodified lines
55185511 type.t = VT_VOID;
55195512 } else {
55205513 /* integer operations */
5521− type.t = VT_INT;
5514+ type.t = VT_INT | (VT_LONG & (t1 | t2));
55225515 /* convert to unsigned if it does not fit in an integer */
55235516 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) ||
55245517 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED))
@@ -6490,20 +6483,20 @@ static void init_putv(CType *type, Section *sec, unsigned long c) · 965 unmodified lines
64906483 *(double *)ptr = vtop->c.d;
64916484 break;
64926485 case VT_LDOUBLE:
6493− if (sizeof(long double) == LDOUBLE_SIZE)
6494− *(long double *)ptr = vtop->c.ld;
6495− else if (sizeof(double) == LDOUBLE_SIZE)
6496− *(double *)ptr = (double)vtop->c.ld;
64976486 #if (defined __i386__ || defined __x86_64__) && (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64)
6498− else if (sizeof (long double) >= 10)
6499− memcpy(memset(ptr, 0, LDOUBLE_SIZE), &vtop->c.ld, 10);
6487+ if (sizeof (long double) >= 10) /* zero pad ten-byte LD */
6488+ memcpy(ptr, &vtop->c.ld, 10);
65006489 #ifdef __TINYC__
65016490 else if (sizeof (long double) == sizeof (double))
6502− __asm__("fldl %1\nfstpt %0\n" : "=m"
6503− (memset(ptr, 0, LDOUBLE_SIZE), ptr) : "m" (vtop->c.ld));
6491+ __asm__("fldl %1\nfstpt %0\n" : "=m" (ptr) : "m" (vtop->c.ld));
65046492 #endif
6493+ else
65056494 #endif
6506− else
6495+ if (sizeof(long double) == LDOUBLE_SIZE)
6496+ *(long double*)ptr = vtop->c.ld;
6497+ else if (sizeof(double) == LDOUBLE_SIZE)
6498+ *(double *)ptr = (double)vtop->c.ld;
6499+ else
65076500 tcc_error("can't cross compile long double constants");
65086501 break;
65096502 #if PTR_SIZE != 8
tccpp.c+58−64
@@ -89,7 +89,7 @@ static const unsigned char tok_two_chars[] = · 88 unmodified lines
8989 '^','=', TOK_A_XOR,
9090 '|','=', TOK_A_OR,
9191 '-','>', TOK_ARROW,
92− '.','.', 0xa8, // C++ token ?
92+ '.','.', TOK_TWODOTS,
9393 '#','#', TOK_TWOSHARPS,
9494 0
9595 };
@@ -1017,23 +1017,18 @@ static inline int tok_size(const int *p) · 921 unmodified lines
10171017 case TOK_LCHAR:
10181018 case TOK_CFLOAT:
10191019 case TOK_LINENUM:
1020−#ifndef TCC_LONG_ARE_64_BIT
1021− case TOK_CLONG;
1022− case TOK_CULONG;
1023−#endif
10241020 return 1 + 1;
10251021 case TOK_STR:
10261022 case TOK_LSTR:
10271023 case TOK_PPNUM:
10281024 case TOK_PPSTR:
10291025 return 1 + ((sizeof(CString) + ((CString *)(p+1))->size + 3) >> 2);
1026+ case TOK_CLONG:
1027+ case TOK_CULONG:
1028+ return 1 + LONG_SIZE / 4;
10301029 case TOK_CDOUBLE:
10311030 case TOK_CLLONG:
10321031 case TOK_CULLONG:
1033−#ifdef TCC_LONG_ARE_64_BIT
1034− case TOK_CLONG;
1035− case TOK_CULONG;
1036−#endif
10371032 return 1 + 2;
10381033 case TOK_CLDOUBLE:
10391034 return 1 + LDOUBLE_SIZE / 4;
@@ -1149,7 +1144,7 @@ static void tok_str_add2(TokenString *s, int t, CValue *cv) · 109 unmodified lines
11491144 case TOK_LCHAR:
11501145 case TOK_CFLOAT:
11511146 case TOK_LINENUM:
1152−#ifndef TCC_LONG_ARE_64_BIT
1147+#if LONG_SIZE == 4
11531148 case TOK_CLONG:
11541149 case TOK_CULONG:
11551150 #endif
@@ -1173,7 +1168,7 @@ static void tok_str_add2(TokenString *s, int t, CValue *cv) · 17 unmodified lines
11731168 case TOK_CDOUBLE:
11741169 case TOK_CLLONG:
11751170 case TOK_CULLONG:
1176−#ifdef TCC_LONG_ARE_64_BIT
1171+#if LONG_SIZE == 8
11771172 case TOK_CLONG:
11781173 case TOK_CULONG:
11791174 #endif
@@ -1227,17 +1222,20 @@ static inline void TOK_GET(int *t, const int **pp, CValue *cv) · 47 unmodified lines
12271222
12281223 tab = cv->tab;
12291224 switch(*t = *p++) {
1225+#if LONG_SIZE == 4
1226+ case TOK_CLONG:
1227+#endif
12301228 case TOK_CINT:
1231− case TOK_CUINT:
12321229 case TOK_CCHAR:
12331230 case TOK_LCHAR:
12341231 case TOK_LINENUM:
1235−#ifndef TCC_LONG_ARE_64_BIT
1236− case TOK_CLONG:
1232+ cv->i = *p++;
1233+ break;
1234+#if LONG_SIZE == 4
12371235 case TOK_CULONG:
12381236 #endif
1239− tab[0] = *p++;
1240− cv->i = (*t == TOK_CUINT) ? (unsigned)cv->i : (int)cv->i;
1237+ case TOK_CUINT:
1238+ cv->i = (unsigned)*p++;
12411239 break;
12421240 case TOK_CFLOAT:
12431241 tab[0] = *p++;
@@ -1253,7 +1251,7 @@ static inline void TOK_GET(int *t, const int **pp, CValue *cv) · 9 unmodified lines
12531251 case TOK_CDOUBLE:
12541252 case TOK_CLLONG:
12551253 case TOK_CULLONG:
1256−#ifdef TCC_LONG_ARE_64_BIT
1254+#if LONG_SIZE == 8
12571255 case TOK_CLONG:
12581256 case TOK_CULONG:
12591257 #endif
@@ -2206,23 +2204,24 @@ static void parse_string(const char *s, int len) · 946 unmodified lines
22062204 tcc_free(p);
22072205
22082206 if (sep == '\'') {
2209− int char_size;
2207+ int char_size, i, n, c;
22102208 /* XXX: make it portable */
22112209 if (!is_long)
2212− char_size = 1;
2210+ tok = TOK_CCHAR, char_size = 1;
22132211 else
2214− char_size = sizeof(nwchar_t);
2215− if (tokcstr.size <= char_size)
2212+ tok = TOK_LCHAR, char_size = sizeof(nwchar_t);
2213+ n = tokcstr.size / char_size - 1;
2214+ if (n < 1)
22162215 tcc_error("empty character constant");
2217− if (tokcstr.size > 2 * char_size)
2216+ if (n > 1)
22182217 tcc_warning("multi-character character constant");
2219− if (!is_long) {
2220− tokc.i = *(int8_t *)tokcstr.data;
2221− tok = TOK_CCHAR;
2222− } else {
2223− tokc.i = *(nwchar_t *)tokcstr.data;
2224− tok = TOK_LCHAR;
2218+ for (c = i = 0; i < n; ++i) {
2219+ if (is_long)
2220+ c = ((nwchar_t *)tokcstr.data)[i];
2221+ else
2222+ c = (c << 8) | ((char *)tokcstr.data)[i];
22252223 }
2224+ tokc.i = c;
22262225 } else {
22272226 tokc.str.size = tokcstr.size;
22282227 tokc.str.data = tokcstr.data;
@@ -2456,7 +2455,7 @@ static void parse_number(const char *p) · 227 unmodified lines
24562455 }
24572456 } else {
24582457 unsigned long long n, n1;
2459− int lcount, ucount, must_64bit;
2458+ int lcount, ucount, ov = 0;
24602459 const char *p1;
24612460
24622461 /* integer number */
@@ -2483,14 +2482,13 @@ static void parse_number(const char *p) · 20 unmodified lines
24832482 n1 = n;
24842483 n = n * b + t;
24852484 /* detect overflow */
2486− /* XXX: this test is not reliable */
2487− if (n < n1)
2488− tcc_error("integer constant overflow");
2485+ if (n1 >= 0x1000000000000000ULL && n / b != n1)
2486+ ov = 1;
24892487 }
24902488
24912489 /* Determine the characteristics (unsigned and/or 64bit) the type of
24922490 the constant must have according to the constant suffix(es) */
2493− lcount = ucount = must_64bit = 0;
2491+ lcount = ucount = 0;
24942492 p1 = p;
24952493 for(;;) {
24962494 t = toup(ch);
@@ -2500,8 +2498,6 @@ static void parse_number(const char *p) · 3 unmodified lines
25002498 if (lcount && *(p - 1) != ch)
25012499 tcc_error("incorrect integer suffix: %s", p1);
25022500 lcount++;
2503− if (lcount == 2)
2504− must_64bit = 1;
25052501 ch = *p++;
25062502 } else if (t == 'U') {
25072503 if (ucount >= 1)
@@ -2513,38 +2509,36 @@ static void parse_number(const char *p) · 5 unmodified lines
25132509 }
25142510 }
25152511
2516− /* Whether 64 bits are needed to hold the constant's value */
2517− if (n & 0xffffffff00000000LL || must_64bit) {
2518− tok = TOK_CLLONG;
2519− n1 = n >> 32;
2520− } else if (lcount) {
2521−#ifdef TCC_LONG_ARE_64_BIT
2522− n1 = n >> 32;
2523−#else
2524− n1 = n;
2525−#endif
2526− tok = TOK_CLONG;
2527− } else {
2528− tok = TOK_CINT;
2529− n1 = n;
2512+ /* Determine if it needs 64 bits and/or unsigned in order to fit */
2513+ if (ucount == 0 && b == 10) {
2514+ if (lcount <= (LONG_SIZE == 4)) {
2515+ if (n >= 0x80000000U)
2516+ lcount = (LONG_SIZE == 4) + 1;
2517+ }
2518+ if (n >= 0x8000000000000000ULL)
2519+ ov = 1, ucount = 1;
2520+ } else {
2521+ if (lcount <= (LONG_SIZE == 4)) {
2522+ if (n >= 0x100000000ULL)
2523+ lcount = (LONG_SIZE == 4) + 1;
2524+ else if (n >= 0x80000000U)
2525+ ucount = 1;
2526+ }
2527+ if (n >= 0x8000000000000000ULL)
2528+ ucount = 1;
25302529 }
25312530
2532− /* Whether type must be unsigned to hold the constant's value */
2533− if (ucount || ((n1 >> 31) && (b != 10))) {
2534− if (tok == TOK_CLLONG)
2535− tok = TOK_CULLONG;
2536− else if (tok == TOK_CLONG)
2537− tok = TOK_CULONG;
2538− else
2539− tok = TOK_CUINT;
2540− /* If decimal and no unsigned suffix, bump to 64 bits or throw error */
2541− } else if (n1 >> 31) {
2542− if (tok == TOK_CINT)
2543− tok = TOK_CLLONG;
2544− else
2545− tcc_error("integer constant overflow");
2546− }
2531+ if (ov)
2532+ tcc_warning("integer constant overflow");
25472533
2534+ tok = TOK_CINT;
2535+ if (lcount) {
2536+ tok = TOK_CLONG;
2537+ if (lcount == 2)
2538+ tok = TOK_CLLONG;
2539+ }
2540+ if (ucount)
2541+ ++tok; /* TOK_CU... */
25482542 tokc.i = n;
25492543 }
25502544 if (ch)
win32/build-tcc.bat+1−1
@@ -113,7 +113,7 @@ for %%f in (*tcc.exe *tcc.dll) do @del %%f · 112 unmodified lines
113113 :compiler
114114 %CC% -o libtcc.dll -shared ..\libtcc.c %D% -DLIBTCC_AS_DLL
115115 @if errorlevel 1 goto :the_end
116−%CC% -o tcc.exe ..\tcc.c libtcc.dll %D% -DONE_SOURCE=0
116+%CC% -o tcc.exe ..\tcc.c libtcc.dll %D% -DONE_SOURCE"=0"
117117 %CC% -o %PX%-tcc.exe ..\tcc.c %DX%
118118
119119 @if (%TCC_FILES%)==(no) goto :files-done

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t