factor code a bit for transforming tokens into SValues. This revealed a bug in TOK_GET (see testcase), which happened to be harmless before. So fix that as well.
Unified · Split
| @@ -4297,14 +4297,6 @@ static void parse_type(CType *type) · 4296 unmodified lines | ||
| 4297 | 4297 | type_decl(type, &ad, &n, TYPE_ABSTRACT); |
| 4298 | 4298 | } |
| 4299 | 4299 | |
| 4300 | −static void vpush_tokc(int t) | |
| 4301 | −{ | |
| 4302 | − CType type; | |
| 4303 | − type.t = t; | |
| 4304 | − type.ref = 0; | |
| 4305 | − vsetc(&type, VT_CONST, &tokc); | |
| 4306 | −} | |
| 4307 | − | |
| 4308 | 4300 | static void parse_builtin_params(int nc, const char *args) |
| 4309 | 4301 | { |
| 4310 | 4302 | char c, sep = '('; |
| @@ -4345,33 +4337,32 @@ ST_FUNC void unary(void) · 34 unmodified lines | ||
| 4345 | 4337 | case TOK_CINT: |
| 4346 | 4338 | case TOK_CCHAR: |
| 4347 | 4339 | case TOK_LCHAR: |
| 4348 | − vpushi(tokc.i); | |
| 4340 | + t = VT_INT; | |
| 4341 | + push_tokc: | |
| 4342 | + type.t = t; | |
| 4343 | + type.ref = 0; | |
| 4344 | + vsetc(&type, VT_CONST, &tokc); | |
| 4349 | 4345 | next(); |
| 4350 | 4346 | break; |
| 4351 | 4347 | case TOK_CUINT: |
| 4352 | − vpush_tokc(VT_INT | VT_UNSIGNED); | |
| 4353 | − next(); | |
| 4354 | − break; | |
| 4348 | + t = VT_INT | VT_UNSIGNED; | |
| 4349 | + goto push_tokc; | |
| 4355 | 4350 | case TOK_CLLONG: |
| 4356 | − vpush_tokc(VT_LLONG); | |
| 4357 | − next(); | |
| 4358 | − break; | |
| 4351 | + t = VT_LLONG; | |
| 4352 | + goto push_tokc; | |
| 4359 | 4353 | case TOK_CULLONG: |
| 4360 | − vpush_tokc(VT_LLONG | VT_UNSIGNED); | |
| 4361 | − next(); | |
| 4362 | − break; | |
| 4354 | + t =VT_LLONG | VT_UNSIGNED; | |
| 4355 | + goto push_tokc; | |
| 4363 | 4356 | case TOK_CFLOAT: |
| 4364 | − vpush_tokc(VT_FLOAT); | |
| 4365 | − next(); | |
| 4366 | − break; | |
| 4357 | + t = VT_FLOAT; | |
| 4358 | + goto push_tokc; | |
| 4367 | 4359 | case TOK_CDOUBLE: |
| 4368 | − vpush_tokc(VT_DOUBLE); | |
| 4369 | − next(); | |
| 4370 | − break; | |
| 4360 | + t = VT_DOUBLE; | |
| 4361 | + goto push_tokc; | |
| 4371 | 4362 | case TOK_CLDOUBLE: |
| 4372 | − vpush_tokc(VT_LDOUBLE); | |
| 4373 | − next(); | |
| 4374 | − break; | |
| 4363 | + t = VT_LDOUBLE; | |
| 4364 | + goto push_tokc; | |
| 4365 | + | |
| 4375 | 4366 | case TOK___FUNCTION__: |
| 4376 | 4367 | if (!gnu_ext) |
| 4377 | 4368 | goto tok_identifier; |
| @@ -1230,10 +1230,13 @@ static inline void TOK_GET(int *t, const int **pp, CValue *cv) · 1229 unmodified lines | ||
| 1230 | 1230 | case TOK_CUINT: |
| 1231 | 1231 | case TOK_CCHAR: |
| 1232 | 1232 | case TOK_LCHAR: |
| 1233 | − case TOK_CFLOAT: | |
| 1234 | 1233 | case TOK_LINENUM: |
| 1235 | 1234 | tab[0] = *p++; |
| 1235 | + cv->i = (*t == TOK_CUINT) ? (unsigned)cv->i : (int)cv->i; | |
| 1236 | 1236 | break; |
| 1237 | + case TOK_CFLOAT: | |
| 1238 | + tab[0] = *p++; | |
| 1239 | + break; | |
| 1237 | 1240 | case TOK_STR: |
| 1238 | 1241 | case TOK_LSTR: |
| 1239 | 1242 | case TOK_PPNUM: |
| @@ -3720,8 +3720,6 @@ typedef struct __attribute__((__packed__)) { · 3719 unmodified lines | ||
| 3720 | 3720 | int c; |
| 3721 | 3721 | } Spacked2; |
| 3722 | 3722 | Spacked2 spacked2; |
| 3723 | −/* This doesn't work for now. Requires adjusting field offsets/sizes | |
| 3724 | − after parsing the struct members. */ | |
| 3725 | 3723 | typedef struct Spacked3_s { |
| 3726 | 3724 | char a; |
| 3727 | 3725 | short b; |
| @@ -3754,3 +3752,24 @@ void * __attribute__((__unused__)) get_void_ptr (void *a) · 26 unmodified lines | ||
| 3754 | 3752 | { |
| 3755 | 3753 | return a; |
| 3756 | 3754 | } |
| 3755 | + | |
| 3756 | +/* This part checks for a bug in TOK_GET (used for inline expansion), | |
| 3757 | + where the large long long constant left the the high bits set for | |
| 3758 | + the integer constant token. */ | |
| 3759 | +static inline | |
| 3760 | +int __get_order(unsigned long long size) | |
| 3761 | +{ | |
| 3762 | + int order; | |
| 3763 | + size -= 0xffff880000000000ULL; // this const left high bits set in the token | |
| 3764 | + { | |
| 3765 | + struct S { int i : 1; } s; // constructed for this '1' | |
| 3766 | + } | |
| 3767 | + order = size; | |
| 3768 | + return order; | |
| 3769 | +} | |
| 3770 | + | |
| 3771 | +/* This just forces the above inline function to be actually emitted. */ | |
| 3772 | +int force_get_order(unsigned long s) | |
| 3773 | +{ | |
| 3774 | + return __get_order(s); | |
| 3775 | +} | |