Unary expression can start with a parenthesis. Thus, the current test to detect which sizeof form is being parsed is inaccurate. This patch makes tcc able to handle things like sizeof (x)[1] where x is declared as char x[5]; wich is a valid unary expression
Unified · Split
| @@ -284,6 +284,13 @@ static void vsetc(CType *type, int r, CValue *vc) · 283 unmodified lines | |||
| 284 | vtop->c = *vc; | 284 | vtop->c = *vc; |
| 285 | } | 285 | } |
| 286 | 286 | ||
| 287 | /* push constant of type "type" with useless value */ | ||
| 288 | void vpush(CType *type) | ||
| 289 | { | ||
| 290 | CValue cval; | ||
| 291 | vsetc(type, VT_CONST, &cval); | ||
| 292 | } | ||
| 293 | |||
| 287 | /* push integer constant */ | 294 | /* push integer constant */ |
| 288 | ST_FUNC void vpushi(int v) | 295 | ST_FUNC void vpushi(int v) |
| 289 | { | 296 | { |
| @@ -3244,11 +3251,14 @@ static void vpush_tokc(int t) · 2954 unmodified lines | |||
| 3244 | 3251 | ||
| 3245 | ST_FUNC void unary(void) | 3252 | ST_FUNC void unary(void) |
| 3246 | { | 3253 | { |
| 3247 | int n, t, align, size, r; | 3254 | int n, t, align, size, r, sizeof_caller; |
| 3248 | CType type; | 3255 | CType type; |
| 3249 | Sym *s; | 3256 | Sym *s; |
| 3250 | AttributeDef ad; | 3257 | AttributeDef ad; |
| 3258 | static int in_sizeof = 0; | ||
| 3251 | 3259 | ||
| 3260 | sizeof_caller = in_sizeof; | ||
| 3261 | in_sizeof = 0; | ||
| 3252 | /* XXX: GCC 2.95.3 does not generate a table although it should be | 3262 | /* XXX: GCC 2.95.3 does not generate a table although it should be |
| 3253 | better here */ | 3263 | better here */ |
| 3254 | tok_next: | 3264 | tok_next: |
| @@ -3345,6 +3355,10 @@ ST_FUNC void unary(void) · 90 unmodified lines | |||
| 3345 | memset(&ad, 0, sizeof(AttributeDef)); | 3355 | memset(&ad, 0, sizeof(AttributeDef)); |
| 3346 | decl_initializer_alloc(&type, &ad, r, 1, 0, 0); | 3356 | decl_initializer_alloc(&type, &ad, r, 1, 0, 0); |
| 3347 | } else { | 3357 | } else { |
| 3358 | if (sizeof_caller) { | ||
| 3359 | vpush(&type); | ||
| 3360 | return; | ||
| 3361 | } | ||
| 3348 | unary(); | 3362 | unary(); |
| 3349 | gen_cast(&type); | 3363 | gen_cast(&type); |
| 3350 | } | 3364 | } |
| @@ -3414,11 +3428,8 @@ ST_FUNC void unary(void) · 63 unmodified lines | |||
| 3414 | case TOK_ALIGNOF2: | 3428 | case TOK_ALIGNOF2: |
| 3415 | t = tok; | 3429 | t = tok; |
| 3416 | next(); | 3430 | next(); |
| 3417 | if (tok == '(') { | 3431 | in_sizeof++; |
| 3418 | parse_expr_type(&type); | 3432 | unary_type(&type); // Perform a in_sizeof = 0; |
| 3419 | } else { | ||
| 3420 | unary_type(&type); | ||
| 3421 | } | ||
| 3422 | size = type_size(&type, &align); | 3433 | size = type_size(&type, &align); |
| 3423 | if (t == TOK_SIZEOF) { | 3434 | if (t == TOK_SIZEOF) { |
| 3424 | if (size < 0) | 3435 | if (size < 0) |
| @@ -4040,9 +4051,11 @@ static void expr_type(CType *type) · 615 unmodified lines | |||
| 4040 | static void unary_type(CType *type) | 4051 | static void unary_type(CType *type) |
| 4041 | { | 4052 | { |
| 4042 | int a; | 4053 | int a; |
| 4054 | void *vtop_saved; | ||
| 4043 | 4055 | ||
| 4044 | a = nocode_wanted; | 4056 | a = nocode_wanted; |
| 4045 | nocode_wanted = 1; | 4057 | nocode_wanted = 1; |
| 4058 | vtop_saved = vtop; | ||
| 4046 | unary(); | 4059 | unary(); |
| 4047 | *type = vtop->type; | 4060 | *type = vtop->type; |
| 4048 | vpop(); | 4061 | vpop(); |