* check that _Generic don't match unsigned char * with char * this case is usefull as with -funsigned-char, 'char *' are unsigned * change VT_LONG so it's now a qualifier VT_LONG are never use for code generation, but only durring parsing state, in _Generic we need to be able to make diference between 'long' and 'long long' So VT_LONG is now use as a type qualifier, it's old behaviour is still here, but we can keep trace of what was a long and what wasn't * add TOK_CLONG and TOK_CULONG tcc was directly converting value like '7171L' into TOK_CLLONG or TOK_CINT depending of the machine architecture. because of that, we was unable to make diference between a long and a long long, which doesn't work with _Generic. So now 7171L is a TOK_CLONG, and we can handle _Generic properly * check that _Generic can make diference between long and long long * uncomment "type match twice" as it should now pass tests on any platforms * add inside_generic global the point of this variable is to use VT_LONG in comparaison only when we are evaluating a _Generic. problem is with my lastest patchs tcc can now make the diference between a 'long long' and a 'long', but in 64 bit stddef.h typedef uint64_t as typedef signed long long int int64_t and stdint.h as unsigned long int, so tcc break when stdint.h and stddef.h are include together. Another solution woud be to modifie include/stddef.h so it define uint64_t as unsigned long int when processor is 64 bit, but this could break some legacy code, so for now, VT_LONG are use only inside generc. * check that _Generic parse first argument correctly * check that _Generic evaluate correctly exresion like "f() / 2"
Unified · Split
| @@ -849,7 +849,6 @@ struct filespec { · 848 unmodified lines | |||
| 849 | #define VT_DOUBLE 9 /* IEEE double */ | 849 | #define VT_DOUBLE 9 /* IEEE double */ |
| 850 | #define VT_LDOUBLE 10 /* IEEE long double */ | 850 | #define VT_LDOUBLE 10 /* IEEE long double */ |
| 851 | #define VT_BOOL 11 /* ISOC99 boolean type */ | 851 | #define VT_BOOL 11 /* ISOC99 boolean type */ |
| 852 | #define VT_LONG 12 /* long integer (NEVER USED as type, only during parsing) */ | ||
| 853 | #define VT_QLONG 13 /* 128-bit integer. Only used for x86-64 ABI */ | 852 | #define VT_QLONG 13 /* 128-bit integer. Only used for x86-64 ABI */ |
| 854 | #define VT_QFLOAT 14 /* 128-bit float. Only used for x86-64 ABI */ | 853 | #define VT_QFLOAT 14 /* 128-bit float. Only used for x86-64 ABI */ |
| 855 | 854 | ||
| @@ -860,6 +859,7 @@ struct filespec { · 4 unmodified lines | |||
| 860 | #define VT_CONSTANT 0x0100 /* const modifier */ | 859 | #define VT_CONSTANT 0x0100 /* const modifier */ |
| 861 | #define VT_VOLATILE 0x0200 /* volatile modifier */ | 860 | #define VT_VOLATILE 0x0200 /* volatile modifier */ |
| 862 | #define VT_VLA 0x0400 /* VLA type (also has VT_PTR and VT_ARRAY) */ | 861 | #define VT_VLA 0x0400 /* VLA type (also has VT_PTR and VT_ARRAY) */ |
| 862 | #define VT_LONG 0x0800 | ||
| 863 | 863 | ||
| 864 | /* storage */ | 864 | /* storage */ |
| 865 | #define VT_EXTERN 0x00001000 /* extern definition */ | 865 | #define VT_EXTERN 0x00001000 /* extern definition */ |
| @@ -939,7 +939,16 @@ struct filespec { · 73 unmodified lines | |||
| 939 | #define TOK_TWOSHARPS 0xca /* ## preprocessing token */ | 939 | #define TOK_TWOSHARPS 0xca /* ## preprocessing token */ |
| 940 | #define TOK_PLCHLDR 0xcb /* placeholder token as defined in C99 */ | 940 | #define TOK_PLCHLDR 0xcb /* placeholder token as defined in C99 */ |
| 941 | #define TOK_NOSUBST 0xcc /* means following token has already been pp'd */ | 941 | #define TOK_NOSUBST 0xcc /* means following token has already been pp'd */ |
| 942 | #define TOK_PPJOIN 0xce /* A '##' in the right position to mean pasting */ | 942 | #define TOK_PPJOIN 0xcd /* A '##' in the right position to mean pasting */ |
| 943 | |||
| 944 | #define TOK_CLONG 0xce /* long constant */ | ||
| 945 | #define TOK_CULONG 0xcf /* unsigned long constant */ | ||
| 946 | |||
| 947 | |||
| 948 | #if defined TCC_TARGET_X86_64 && !defined TCC_TARGET_PE | ||
| 949 | #define TCC_LONG_ARE_64_BIT | ||
| 950 | #endif | ||
| 951 | |||
| 943 | 952 | ||
| 944 | #define TOK_SHL 0x01 /* shift left */ | 953 | #define TOK_SHL 0x01 /* shift left */ |
| 945 | #define TOK_SAR 0x02 /* signed shift right */ | 954 | #define TOK_SAR 0x02 /* signed shift right */ |
| @@ -42,6 +42,7 @@ ST_DATA Sym *local_label_stack; · 41 unmodified lines | |||
| 42 | static int local_scope; | 42 | static int local_scope; |
| 43 | static int in_sizeof; | 43 | static int in_sizeof; |
| 44 | static int section_sym; | 44 | static int section_sym; |
| 45 | static int inside_generic; | ||
| 45 | 46 | ||
| 46 | ST_DATA int vlas_in_scope; /* number of VLAs that are currently in scope */ | 47 | ST_DATA int vlas_in_scope; /* number of VLAs that are currently in scope */ |
| 47 | ST_DATA int vla_sp_root_loc; /* vla_sp_loc for SP before any VLAs were pushed */ | 48 | ST_DATA int vla_sp_root_loc; /* vla_sp_loc for SP before any VLAs were pushed */ |
| @@ -2218,6 +2219,10 @@ redo: · 2170 unmodified lines | |||
| 2218 | } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) { | 2219 | } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) { |
| 2219 | /* cast to biggest op */ | 2220 | /* cast to biggest op */ |
| 2220 | t = VT_LLONG; | 2221 | t = VT_LLONG; |
| 2222 | /* check if we need to keep type as long or as long long */ | ||
| 2223 | if ((t1 & VT_LONG && (t2 & (VT_BTYPE | VT_LONG)) != VT_LLONG) || | ||
| 2224 | (t2 & VT_LONG && (t1 & (VT_BTYPE | VT_LONG)) != VT_LLONG)) | ||
| 2225 | t |= VT_LONG; | ||
| 2221 | /* convert to unsigned if it does not fit in a long long */ | 2226 | /* convert to unsigned if it does not fit in a long long */ |
| 2222 | if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) || | 2227 | if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) || |
| 2223 | (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED)) | 2228 | (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED)) |
| @@ -2226,7 +2231,11 @@ redo: · 2 unmodified lines | |||
| 2226 | } else { | 2231 | } else { |
| 2227 | /* integer operations */ | 2232 | /* integer operations */ |
| 2228 | t = VT_INT; | 2233 | t = VT_INT; |
| 2229 | /* convert to unsigned if it does not fit in an integer */ | 2234 | |
| 2235 | if ((t1 & VT_LONG) || (t2 & VT_LONG)) | ||
| 2236 | t |= VT_LONG; | ||
| 2237 | |||
| 2238 | /* convert to unsigned if it does not fit in an integer */ | ||
| 2230 | if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) || | 2239 | if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) || |
| 2231 | (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED)) | 2240 | (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED)) |
| 2232 | t |= VT_UNSIGNED; | 2241 | t |= VT_UNSIGNED; |
| @@ -2723,6 +2732,11 @@ static int compare_types(CType *type1, CType *type2, int unqualified) · 490 unmodified lines | |||
| 2723 | t1 &= ~(VT_CONSTANT | VT_VOLATILE); | 2732 | t1 &= ~(VT_CONSTANT | VT_VOLATILE); |
| 2724 | t2 &= ~(VT_CONSTANT | VT_VOLATILE); | 2733 | t2 &= ~(VT_CONSTANT | VT_VOLATILE); |
| 2725 | } | 2734 | } |
| 2735 | |||
| 2736 | if (!inside_generic) { | ||
| 2737 | t1 &= ~VT_LONG; | ||
| 2738 | t2 &= ~VT_LONG; | ||
| 2739 | } | ||
| 2726 | /* Default Vs explicit signedness only matters for char */ | 2740 | /* Default Vs explicit signedness only matters for char */ |
| 2727 | if ((t1 & VT_BTYPE) != VT_BYTE) { | 2741 | if ((t1 & VT_BTYPE) != VT_BYTE) { |
| 2728 | t1 &= ~VT_DEFSIGN; | 2742 | t1 &= ~VT_DEFSIGN; |
| @@ -2799,6 +2813,12 @@ static void type_to_str(char *buf, int buf_size, · 70 unmodified lines | |||
| 2799 | tstr = "enum "; | 2813 | tstr = "enum "; |
| 2800 | goto tstruct; | 2814 | goto tstruct; |
| 2801 | } | 2815 | } |
| 2816 | |||
| 2817 | if (!bt && VT_LONG & t) { | ||
| 2818 | tstr = "long"; | ||
| 2819 | goto add_tstr; | ||
| 2820 | } | ||
| 2821 | |||
| 2802 | switch(bt) { | 2822 | switch(bt) { |
| 2803 | case VT_VOID: | 2823 | case VT_VOID: |
| 2804 | tstr = "void"; | 2824 | tstr = "void"; |
| @@ -2815,9 +2835,6 @@ static void type_to_str(char *buf, int buf_size, · 10 unmodified lines | |||
| 2815 | case VT_INT: | 2835 | case VT_INT: |
| 2816 | tstr = "int"; | 2836 | tstr = "int"; |
| 2817 | goto add_tstr; | 2837 | goto add_tstr; |
| 2818 | case VT_LONG: | ||
| 2819 | tstr = "long"; | ||
| 2820 | goto add_tstr; | ||
| 2821 | case VT_LLONG: | 2838 | case VT_LLONG: |
| 2822 | tstr = "long long"; | 2839 | tstr = "long long"; |
| 2823 | goto add_tstr; | 2840 | goto add_tstr; |
| @@ -3960,10 +3977,10 @@ static int parse_btype(CType *type, AttributeDef *ad) · 1136 unmodified lines | |||
| 3960 | case TOK_LONG: | 3977 | case TOK_LONG: |
| 3961 | if ((t & VT_BTYPE) == VT_DOUBLE) { | 3978 | if ((t & VT_BTYPE) == VT_DOUBLE) { |
| 3962 | #ifndef TCC_TARGET_PE | 3979 | #ifndef TCC_TARGET_PE |
| 3963 | t = (t & ~VT_BTYPE) | VT_LDOUBLE; | 3980 | t = (t & ~(VT_LONG | VT_BTYPE)) | VT_LDOUBLE; |
| 3964 | #endif | 3981 | #endif |
| 3965 | } else if ((t & VT_BTYPE) == VT_LONG) { | 3982 | } else if (t & VT_LONG) { |
| 3966 | t = (t & ~VT_BTYPE) | VT_LLONG; | 3983 | t = (t & ~(VT_LONG | VT_BTYPE)) | VT_LLONG; |
| 3967 | } else { | 3984 | } else { |
| 3968 | u = VT_LONG; | 3985 | u = VT_LONG; |
| 3969 | goto basic_type; | 3986 | goto basic_type; |
| @@ -3984,11 +4001,11 @@ static int parse_btype(CType *type, AttributeDef *ad) · 14 unmodified lines | |||
| 3984 | u = VT_FLOAT; | 4001 | u = VT_FLOAT; |
| 3985 | goto basic_type; | 4002 | goto basic_type; |
| 3986 | case TOK_DOUBLE: | 4003 | case TOK_DOUBLE: |
| 3987 | if ((t & VT_BTYPE) == VT_LONG) { | 4004 | if (t & VT_LONG) { |
| 3988 | #ifdef TCC_TARGET_PE | 4005 | #ifdef TCC_TARGET_PE |
| 3989 | t = (t & ~VT_BTYPE) | VT_DOUBLE; | 4006 | t = (t & ~(VT_LONG | VT_BTYPE)) | VT_DOUBLE; |
| 3990 | #else | 4007 | #else |
| 3991 | t = (t & ~VT_BTYPE) | VT_LDOUBLE; | 4008 | t = (t & ~(VT_LONG | VT_BTYPE)) | VT_LDOUBLE; |
| 3992 | #endif | 4009 | #endif |
| 3993 | } else { | 4010 | } else { |
| 3994 | u = VT_DOUBLE; | 4011 | u = VT_DOUBLE; |
| @@ -4122,7 +4139,7 @@ the_end: · 127 unmodified lines | |||
| 4122 | } | 4139 | } |
| 4123 | 4140 | ||
| 4124 | /* long is never used as type */ | 4141 | /* long is never used as type */ |
| 4125 | if ((t & VT_BTYPE) == VT_LONG) | 4142 | if (t & VT_LONG) |
| 4126 | #if PTR_SIZE == 8 && !defined TCC_TARGET_PE | 4143 | #if PTR_SIZE == 8 && !defined TCC_TARGET_PE |
| 4127 | t = (t & ~VT_BTYPE) | VT_LLONG; | 4144 | t = (t & ~VT_BTYPE) | VT_LLONG; |
| 4128 | #else | 4145 | #else |
| @@ -4552,7 +4569,16 @@ ST_FUNC void unary(void) · 423 unmodified lines | |||
| 4552 | case TOK_CLDOUBLE: | 4569 | case TOK_CLDOUBLE: |
| 4553 | t = VT_LDOUBLE; | 4570 | t = VT_LDOUBLE; |
| 4554 | goto push_tokc; | 4571 | goto push_tokc; |
| 4555 | 4572 | case TOK_CLONG: | |
| 4573 | case TOK_CULONG: | ||
| 4574 | #ifdef TCC_LONG_ARE_64_BIT | ||
| 4575 | t = VT_LLONG | VT_LONG; | ||
| 4576 | #else | ||
| 4577 | t = VT_INT | VT_LONG; | ||
| 4578 | #endif | ||
| 4579 | if (tok == TOK_CULONG) | ||
| 4580 | t |= VT_UNSIGNED; | ||
| 4581 | goto push_tokc; | ||
| 4556 | case TOK___FUNCTION__: | 4582 | case TOK___FUNCTION__: |
| 4557 | if (!gnu_ext) | 4583 | if (!gnu_ext) |
| 4558 | goto tok_identifier; | 4584 | goto tok_identifier; |
| @@ -4906,8 +4932,9 @@ ST_FUNC void unary(void) · 347 unmodified lines | |||
| 4906 | 4932 | ||
| 4907 | next(); | 4933 | next(); |
| 4908 | skip('('); | 4934 | skip('('); |
| 4935 | inside_generic = 1; | ||
| 4909 | expr_type(&controlling_type, expr_eq); | 4936 | expr_type(&controlling_type, expr_eq); |
| 4910 | controlling_type.t &= ~(VT_CONSTANT|VT_VOLATILE|VT_ARRAY); | 4937 | controlling_type.t &= ~(VT_CONSTANT | VT_VOLATILE | VT_ARRAY); |
| 4911 | for (;;) { | 4938 | for (;;) { |
| 4912 | learn = 0; | 4939 | learn = 0; |
| 4913 | skip(','); | 4940 | skip(','); |
| @@ -4926,7 +4953,7 @@ ST_FUNC void unary(void) · 12 unmodified lines | |||
| 4926 | type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT); | 4953 | type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT); |
| 4927 | if (compare_types(&controlling_type, &cur_type, 0)) { | 4954 | if (compare_types(&controlling_type, &cur_type, 0)) { |
| 4928 | if (has_match) { | 4955 | if (has_match) { |
| 4929 | // tcc_error("type match twice"); | 4956 | tcc_error("type match twice"); |
| 4930 | } | 4957 | } |
| 4931 | has_match = 1; | 4958 | has_match = 1; |
| 4932 | learn = 1; | 4959 | learn = 1; |
| @@ -4950,6 +4977,7 @@ ST_FUNC void unary(void) · 17 unmodified lines | |||
| 4950 | } | 4977 | } |
| 4951 | begin_macro(str, 1); | 4978 | begin_macro(str, 1); |
| 4952 | next(); | 4979 | next(); |
| 4980 | inside_generic = 0; | ||
| 4953 | expr_eq(); | 4981 | expr_eq(); |
| 4954 | if (tok != TOK_EOF) | 4982 | if (tok != TOK_EOF) |
| 4955 | expect(","); | 4983 | expect(","); |
| @@ -480,6 +480,8 @@ ST_FUNC const char *get_tok_str(int v, CValue *cv) · 479 unmodified lines | |||
| 480 | switch(v) { | 480 | switch(v) { |
| 481 | case TOK_CINT: | 481 | case TOK_CINT: |
| 482 | case TOK_CUINT: | 482 | case TOK_CUINT: |
| 483 | case TOK_CLONG: | ||
| 484 | case TOK_CULONG: | ||
| 483 | case TOK_CLLONG: | 485 | case TOK_CLLONG: |
| 484 | case TOK_CULLONG: | 486 | case TOK_CULLONG: |
| 485 | /* XXX: not quite exact, but only useful for testing */ | 487 | /* XXX: not quite exact, but only useful for testing */ |
| @@ -1014,6 +1016,10 @@ static inline int tok_size(const int *p) · 528 unmodified lines | |||
| 1014 | case TOK_LCHAR: | 1016 | case TOK_LCHAR: |
| 1015 | case TOK_CFLOAT: | 1017 | case TOK_CFLOAT: |
| 1016 | case TOK_LINENUM: | 1018 | case TOK_LINENUM: |
| 1019 | #ifndef TCC_LONG_ARE_64_BIT | ||
| 1020 | case TOK_CLONG; | ||
| 1021 | case TOK_CULONG; | ||
| 1022 | #endif | ||
| 1017 | return 1 + 1; | 1023 | return 1 + 1; |
| 1018 | case TOK_STR: | 1024 | case TOK_STR: |
| 1019 | case TOK_LSTR: | 1025 | case TOK_LSTR: |
| @@ -1023,6 +1029,10 @@ static inline int tok_size(const int *p) · 3 unmodified lines | |||
| 1023 | case TOK_CDOUBLE: | 1029 | case TOK_CDOUBLE: |
| 1024 | case TOK_CLLONG: | 1030 | case TOK_CLLONG: |
| 1025 | case TOK_CULLONG: | 1031 | case TOK_CULLONG: |
| 1032 | #ifdef TCC_LONG_ARE_64_BIT | ||
| 1033 | case TOK_CLONG; | ||
| 1034 | case TOK_CULONG; | ||
| 1035 | #endif | ||
| 1026 | return 1 + 2; | 1036 | return 1 + 2; |
| 1027 | case TOK_CLDOUBLE: | 1037 | case TOK_CLDOUBLE: |
| 1028 | return 1 + LDOUBLE_SIZE / 4; | 1038 | return 1 + LDOUBLE_SIZE / 4; |
| @@ -1138,6 +1148,10 @@ static void tok_str_add2(TokenString *s, int t, CValue *cv) · 109 unmodified lines | |||
| 1138 | case TOK_LCHAR: | 1148 | case TOK_LCHAR: |
| 1139 | case TOK_CFLOAT: | 1149 | case TOK_CFLOAT: |
| 1140 | case TOK_LINENUM: | 1150 | case TOK_LINENUM: |
| 1151 | #ifndef TCC_LONG_ARE_64_BIT | ||
| 1152 | case TOK_CLONG: | ||
| 1153 | case TOK_CULONG: | ||
| 1154 | #endif | ||
| 1141 | str[len++] = cv->tab[0]; | 1155 | str[len++] = cv->tab[0]; |
| 1142 | break; | 1156 | break; |
| 1143 | case TOK_PPNUM: | 1157 | case TOK_PPNUM: |
| @@ -1158,6 +1172,10 @@ static void tok_str_add2(TokenString *s, int t, CValue *cv) · 14 unmodified lines | |||
| 1158 | case TOK_CDOUBLE: | 1172 | case TOK_CDOUBLE: |
| 1159 | case TOK_CLLONG: | 1173 | case TOK_CLLONG: |
| 1160 | case TOK_CULLONG: | 1174 | case TOK_CULLONG: |
| 1175 | #ifdef TCC_LONG_ARE_64_BIT | ||
| 1176 | case TOK_CLONG: | ||
| 1177 | case TOK_CULONG: | ||
| 1178 | #endif | ||
| 1161 | #if LDOUBLE_SIZE == 8 | 1179 | #if LDOUBLE_SIZE == 8 |
| 1162 | case TOK_CLDOUBLE: | 1180 | case TOK_CLDOUBLE: |
| 1163 | #endif | 1181 | #endif |
| @@ -1213,6 +1231,10 @@ static inline void TOK_GET(int *t, const int **pp, CValue *cv) · 49 unmodified lines | |||
| 1213 | case TOK_CCHAR: | 1231 | case TOK_CCHAR: |
| 1214 | case TOK_LCHAR: | 1232 | case TOK_LCHAR: |
| 1215 | case TOK_LINENUM: | 1233 | case TOK_LINENUM: |
| 1234 | #ifndef TCC_LONG_ARE_64_BIT | ||
| 1235 | case TOK_CLONG: | ||
| 1236 | case TOK_CULONG: | ||
| 1237 | #endif | ||
| 1216 | tab[0] = *p++; | 1238 | tab[0] = *p++; |
| 1217 | cv->i = (*t == TOK_CUINT) ? (unsigned)cv->i : (int)cv->i; | 1239 | cv->i = (*t == TOK_CUINT) ? (unsigned)cv->i : (int)cv->i; |
| 1218 | break; | 1240 | break; |
| @@ -1230,6 +1252,10 @@ static inline void TOK_GET(int *t, const int **pp, CValue *cv) · 11 unmodified lines | |||
| 1230 | case TOK_CDOUBLE: | 1252 | case TOK_CDOUBLE: |
| 1231 | case TOK_CLLONG: | 1253 | case TOK_CLLONG: |
| 1232 | case TOK_CULLONG: | 1254 | case TOK_CULLONG: |
| 1255 | #ifdef TCC_LONG_ARE_64_BIT | ||
| 1256 | case TOK_CLONG: | ||
| 1257 | case TOK_CULONG: | ||
| 1258 | #endif | ||
| 1233 | n = 2; | 1259 | n = 2; |
| 1234 | goto copy; | 1260 | goto copy; |
| 1235 | case TOK_CLDOUBLE: | 1261 | case TOK_CLDOUBLE: |
| @@ -2407,9 +2433,7 @@ static void parse_number(const char *p) · 1171 unmodified lines | |||
| 2407 | if (lcount && *(p - 1) != ch) | 2433 | if (lcount && *(p - 1) != ch) |
| 2408 | tcc_error("incorrect integer suffix: %s", p1); | 2434 | tcc_error("incorrect integer suffix: %s", p1); |
| 2409 | lcount++; | 2435 | lcount++; |
| 2410 | #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE | ||
| 2411 | if (lcount == 2) | 2436 | if (lcount == 2) |
| 2412 | #endif | ||
| 2413 | must_64bit = 1; | 2437 | must_64bit = 1; |
| 2414 | ch = *p++; | 2438 | ch = *p++; |
| 2415 | } else if (t == 'U') { | 2439 | } else if (t == 'U') { |
| @@ -2426,6 +2450,13 @@ static void parse_number(const char *p) · 10 unmodified lines | |||
| 2426 | if (n & 0xffffffff00000000LL || must_64bit) { | 2450 | if (n & 0xffffffff00000000LL || must_64bit) { |
| 2427 | tok = TOK_CLLONG; | 2451 | tok = TOK_CLLONG; |
| 2428 | n1 = n >> 32; | 2452 | n1 = n >> 32; |
| 2453 | } else if (lcount) { | ||
| 2454 | #ifdef TCC_LONG_ARE_64_BIT | ||
| 2455 | n1 = n >> 32; | ||
| 2456 | #else | ||
| 2457 | n1 = n; | ||
| 2458 | #endif | ||
| 2459 | tok = TOK_CLONG; | ||
| 2429 | } else { | 2460 | } else { |
| 2430 | tok = TOK_CINT; | 2461 | tok = TOK_CINT; |
| 2431 | n1 = n; | 2462 | n1 = n; |
| @@ -2435,7 +2466,9 @@ static void parse_number(const char *p) · 3 unmodified lines | |||
| 2435 | if (ucount || ((n1 >> 31) && (b != 10))) { | 2466 | if (ucount || ((n1 >> 31) && (b != 10))) { |
| 2436 | if (tok == TOK_CLLONG) | 2467 | if (tok == TOK_CLLONG) |
| 2437 | tok = TOK_CULLONG; | 2468 | tok = TOK_CULLONG; |
| 2438 | else | 2469 | else if (tok == TOK_CLONG) |
| 2470 | tok = TOK_CULONG; | ||
| 2471 | else | ||
| 2439 | tok = TOK_CUINT; | 2472 | tok = TOK_CUINT; |
| 2440 | /* If decimal and no unsigned suffix, bump to 64 bits or throw error */ | 2473 | /* If decimal and no unsigned suffix, bump to 64 bits or throw error */ |
| 2441 | } else if (n1 >> 31) { | 2474 | } else if (n1 >> 31) { |
| @@ -20,6 +20,8 @@ int b_f() · 19 unmodified lines | |||
| 20 | return 10; | 20 | return 10; |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | typedef int int_type1; | ||
| 24 | |||
| 23 | #define gen_sw(a) _Generic(a, const char *: 1, default: 8, int: 123); | 25 | #define gen_sw(a) _Generic(a, const char *: 1, default: 8, int: 123); |
| 24 | 26 | ||
| 25 | int main() | 27 | int main() |
| @@ -28,24 +30,32 @@ int main() · 2 unmodified lines | |||
| 28 | struct b titi; | 30 | struct b titi; |
| 29 | const int * const ptr; | 31 | const int * const ptr; |
| 30 | const char *ti; | 32 | const char *ti; |
| 33 | int_type1 i2; | ||
| 31 | 34 | ||
| 32 | i = _Generic(a, int: a_f, const int: b_f)(); | 35 | i = _Generic(a, int: a_f, const int: b_f)(); |
| 33 | printf("%d\n", i); | 36 | printf("%d\n", i); |
| 37 | i = _Generic(a, int: a_f() / 2, const int: b_f() / 2); | ||
| 38 | printf("%d\n", i); | ||
| 34 | i = _Generic(ptr, int *:1, int * const:2, default:20); | 39 | i = _Generic(ptr, int *:1, int * const:2, default:20); |
| 35 | printf("%d\n", i); | 40 | printf("%d\n", i); |
| 36 | i = gen_sw(a); | 41 | i = gen_sw(a); |
| 37 | printf("%d\n", i); | 42 | printf("%d\n", i); |
| 38 | i = _Generic(titi, struct a:1, struct b:2, default:20); | 43 | i = _Generic(titi, struct a:1, struct b:2, default:20); |
| 39 | printf("%d\n", i); | 44 | printf("%d\n", i); |
| 45 | i = _Generic(i2, char: 1, int : 0); | ||
| 46 | printf("%d\n", i); | ||
| 40 | i = _Generic(a, char:1, int[4]:2, default:5); | 47 | i = _Generic(a, char:1, int[4]:2, default:5); |
| 41 | printf("%d\n", i); | 48 | printf("%d\n", i); |
| 42 | i = _Generic(17, int :1, int **:2); | 49 | i = _Generic(17, int :1, int **:2); |
| 43 | printf("%d\n", i); | 50 | printf("%d\n", i); |
| 44 | i = _Generic(17L, int :1, long :2); | 51 | i = _Generic(17L, int :1, long :2, long long : 3); |
| 45 | printf("%d\n", i); | 52 | printf("%d\n", i); |
| 46 | i = _Generic("17, io", const char *:1, char *:3, const int :2); | 53 | i = _Generic("17, io", char *: 3, const char *: 1); |
| 47 | printf("%d\n", i); | 54 | printf("%d\n", i); |
| 48 | i = _Generic(ti, const char *:1, char *:3, const int :2); | 55 | i = _Generic(ti, const unsigned char *:1, const char *:4, char *:3, |
| 56 | const signed char *:2); | ||
| 49 | printf("%d\n", i); | 57 | printf("%d\n", i); |
| 58 | printf("%s\n", _Generic(i + 2L, long: "long", int: "int", | ||
| 59 | long long: "long long")); | ||
| 50 | return 0; | 60 | return 0; |
| 51 | } | 61 | } |
| @@ -1,9 +1,12 @@ | |||
| 1 | 20 | 1 | 20 |
| 2 | 10 | ||
| 2 | 20 | 3 | 20 |
| 3 | 123 | 4 | 123 |
| 4 | 2 | 5 | 2 |
| 6 | 0 | ||
| 5 | 5 | 7 | 5 |
| 6 | 1 | 8 | 1 |
| 7 | 2 | 9 | 2 |
| 8 | 3 | 10 | 3 |
| 9 | 1 | 11 | 4 |
| 12 | long | ||