fixes these cases: ptr - ptr (-> ptrdiff_t) ptr +/- num (-> ptr) sizeof (ptr+/-num) (-> size_t) Also some cleanups
Unified · Split
| @@ -234,7 +234,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has · 233 unmodified lines | ||
| 234 | 234 | static void decl(int l); |
| 235 | 235 | static int decl0(int l, int is_for_loop_init, Sym *); |
| 236 | 236 | static void expr_eq(void); |
| 237 | −static void vla_runtime_type_size(CType *type, int *a); | |
| 237 | +static void vpush_type_size(CType *type, int *a); | |
| 238 | 238 | static int is_compatible_unqualified_types(CType *type1, CType *type2); |
| 239 | 239 | static inline int64_t expr_const64(void); |
| 240 | 240 | static void vpush64(int ty, unsigned long long v); |
| @@ -3173,7 +3173,7 @@ static void type_to_str(char *buf, int buf_size, · 2932 unmodified lines | ||
| 3173 | 3173 | goto no_var; |
| 3174 | 3174 | case VT_PTR: |
| 3175 | 3175 | s = type->ref; |
| 3176 | − if (t & VT_ARRAY) { | |
| 3176 | + if (t & (VT_ARRAY|VT_VLA)) { | |
| 3177 | 3177 | if (varstr && '*' == *varstr) |
| 3178 | 3178 | snprintf(buf1, sizeof(buf1), "(%s)[%d]", varstr, s->c); |
| 3179 | 3179 | else |
| @@ -3220,12 +3220,6 @@ static int pointed_size(CType *type) · 40 unmodified lines | ||
| 3220 | 3220 | return type_size(pointed_type(type), &align); |
| 3221 | 3221 | } |
| 3222 | 3222 | |
| 3223 | −static void vla_runtime_pointed_size(CType *type) | |
| 3224 | −{ | |
| 3225 | − int align; | |
| 3226 | − vla_runtime_type_size(pointed_type(type), &align); | |
| 3227 | −} | |
| 3228 | − | |
| 3229 | 3223 | static inline int is_null_pointer(SValue *p) |
| 3230 | 3224 | { |
| 3231 | 3225 | if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST) |
| @@ -3436,7 +3430,7 @@ static int combine_types(CType *dest, SValue *op1, SValue *op2, int op) · 204 unmodified lines | ||
| 3436 | 3430 | /* generic gen_op: handles types problems */ |
| 3437 | 3431 | ST_FUNC void gen_op(int op) |
| 3438 | 3432 | { |
| 3439 | − int u, t1, t2, bt1, bt2, t; | |
| 3433 | + int t1, t2, bt1, bt2, t; | |
| 3440 | 3434 | CType type1, combtype; |
| 3441 | 3435 | |
| 3442 | 3436 | redo: |
| @@ -3463,17 +3457,14 @@ redo: · 20 unmodified lines | ||
| 3463 | 3457 | } else if (bt1 == VT_PTR || bt2 == VT_PTR) { |
| 3464 | 3458 | /* at least one operand is a pointer */ |
| 3465 | 3459 | /* relational op: must be both pointers */ |
| 3460 | + int align; | |
| 3466 | 3461 | if (TOK_ISCOND(op)) |
| 3467 | 3462 | goto std_op; |
| 3468 | 3463 | /* if both pointers, then it must be the '-' op */ |
| 3469 | 3464 | if (bt1 == VT_PTR && bt2 == VT_PTR) { |
| 3470 | 3465 | if (op != '-') |
| 3471 | 3466 | tcc_error("cannot use pointers here"); |
| 3472 | − if (vtop[-1].type.t & VT_VLA) { | |
| 3473 | − vla_runtime_pointed_size(&vtop[-1].type); | |
| 3474 | − } else { | |
| 3475 | − vpushi(pointed_size(&vtop[-1].type)); | |
| 3476 | − } | |
| 3467 | + vpush_type_size(pointed_type(&vtop[-1].type), &align); | |
| 3477 | 3468 | vrott(3); |
| 3478 | 3469 | gen_opic(op); |
| 3479 | 3470 | vtop->type.t = VT_PTRDIFF_T; |
| @@ -3494,19 +3485,7 @@ redo: · 14 unmodified lines | ||
| 3494 | 3485 | gen_cast_s(VT_INT); |
| 3495 | 3486 | #endif |
| 3496 | 3487 | type1 = vtop[-1].type; |
| 3497 | − if (vtop[-1].type.ref->type.t & VT_VLA) | |
| 3498 | − vla_runtime_pointed_size(&vtop[-1].type); | |
| 3499 | − else { | |
| 3500 | − u = pointed_size(&vtop[-1].type); | |
| 3501 | − if (u < 0) | |
| 3502 | − tcc_error("unknown array element size"); | |
| 3503 | −#if PTR_SIZE == 8 | |
| 3504 | − vpushll(u); | |
| 3505 | −#else | |
| 3506 | − /* XXX: cast to int ? (long long case) */ | |
| 3507 | − vpushi(u); | |
| 3508 | −#endif | |
| 3509 | − } | |
| 3488 | + vpush_type_size(pointed_type(&vtop[-1].type), &align); | |
| 3510 | 3489 | gen_op('*'); |
| 3511 | 3490 | #ifdef CONFIG_TCC_BCHECK |
| 3512 | 3491 | if (tcc_state->do_bounds_check && !const_wanted) { |
| @@ -3523,7 +3502,7 @@ redo: · 10 unmodified lines | ||
| 3523 | 3502 | { |
| 3524 | 3503 | gen_opic(op); |
| 3525 | 3504 | } |
| 3526 | − type1.t &= ~VT_ARRAY; | |
| 3505 | + type1.t &= ~(VT_ARRAY|VT_VLA); | |
| 3527 | 3506 | /* put again type if gen_opic() swaped operands */ |
| 3528 | 3507 | vtop->type = type1; |
| 3529 | 3508 | } |
| @@ -3957,13 +3936,16 @@ ST_FUNC int type_size(CType *type, int *a) · 427 unmodified lines | ||
| 3957 | 3936 | |
| 3958 | 3937 | /* push type size as known at runtime time on top of value stack. Put |
| 3959 | 3938 | alignment at 'a' */ |
| 3960 | −ST_FUNC void vla_runtime_type_size(CType *type, int *a) | |
| 3939 | +static void vpush_type_size(CType *type, int *a) | |
| 3961 | 3940 | { |
| 3962 | 3941 | if (type->t & VT_VLA) { |
| 3963 | 3942 | type_size(&type->ref->type, a); |
| 3964 | 3943 | vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c); |
| 3965 | 3944 | } else { |
| 3966 | − vpushi(type_size(type, a)); | |
| 3945 | + int size = type_size(type, a); | |
| 3946 | + if (size < 0) | |
| 3947 | + tcc_error("unknown type size"); | |
| 3948 | + vpushi(size); | |
| 3967 | 3949 | } |
| 3968 | 3950 | } |
| 3969 | 3951 | |
| @@ -5501,7 +5483,7 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td) · 1531 unmodified lines | ||
| 5501 | 5483 | loc &= -align; |
| 5502 | 5484 | n = loc; |
| 5503 | 5485 | |
| 5504 | − vla_runtime_type_size(type, &align); | |
| 5486 | + vpush_type_size(type, &align); | |
| 5505 | 5487 | gen_op('*'); |
| 5506 | 5488 | vset(&int_type, VT_LOCAL|VT_LVAL, n); |
| 5507 | 5489 | vswap(); |
| @@ -6050,24 +6032,18 @@ ST_FUNC void unary(void) · 542 unmodified lines | ||
| 6050 | 6032 | next(); |
| 6051 | 6033 | in_sizeof++; |
| 6052 | 6034 | expr_type(&type, unary); /* Perform a in_sizeof = 0; */ |
| 6053 | − s = NULL; | |
| 6054 | − if (vtop[1].r & VT_SYM) | |
| 6055 | − s = vtop[1].sym; /* hack: accessing previous vtop */ | |
| 6056 | − size = type_size(&type, &align); | |
| 6057 | − if (s && s->a.aligned) | |
| 6058 | − align = 1 << (s->a.aligned - 1); | |
| 6059 | 6035 | if (t == TOK_SIZEOF) { |
| 6060 | − if (!(type.t & VT_VLA)) { | |
| 6061 | − if (size < 0) | |
| 6062 | − tcc_error("sizeof applied to an incomplete type"); | |
| 6063 | − vpushs(size); | |
| 6064 | − } else { | |
| 6065 | − vla_runtime_type_size(&type, &align); | |
| 6066 | − } | |
| 6036 | + vpush_type_size(&type, &align); | |
| 6037 | + gen_cast_s(VT_SIZE_T); | |
| 6067 | 6038 | } else { |
| 6039 | + type_size(&type, &align); | |
| 6040 | + s = NULL; | |
| 6041 | + if (vtop[1].r & VT_SYM) | |
| 6042 | + s = vtop[1].sym; /* hack: accessing previous vtop */ | |
| 6043 | + if (s && s->a.aligned) | |
| 6044 | + align = 1 << (s->a.aligned - 1); | |
| 6068 | 6045 | vpushs(align); |
| 6069 | 6046 | } |
| 6070 | − vtop->type.t |= VT_UNSIGNED; | |
| 6071 | 6047 | break; |
| 6072 | 6048 | |
| 6073 | 6049 | case TOK_builtin_expect: |
| @@ -8566,7 +8542,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 2492 unmodified lines | ||
| 8566 | 8542 | } |
| 8567 | 8543 | } |
| 8568 | 8544 | |
| 8569 | − vla_runtime_type_size(type, &a); | |
| 8545 | + vpush_type_size(type, &a); | |
| 8570 | 8546 | gen_vla_alloc(type, a); |
| 8571 | 8547 | #if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64 |
| 8572 | 8548 | /* on _WIN64, because of the function args scratch area, the |
| @@ -2980,12 +2980,20 @@ void c99_vla_test_2(int d, int h, int w) · 2979 unmodified lines | ||
| 2980 | 2980 | for (z=0; z<d; z++) { |
| 2981 | 2981 | for (y=0; y<h; y++) { |
| 2982 | 2982 | for (x=0; x<w; x++) { |
| 2983 | − printf("% 4i", arr[z][y][x]); | |
| 2983 | + printf(" %2d", arr[z][y][x]); | |
| 2984 | 2984 | } |
| 2985 | 2985 | puts(""); |
| 2986 | 2986 | } |
| 2987 | 2987 | puts(""); |
| 2988 | 2988 | } |
| 2989 | + printf(" sizes : %d %d %d\n" | |
| 2990 | + " pdiff : %d %d\n" | |
| 2991 | + " tests : %d %d\n", | |
| 2992 | + sizeof (*arr), sizeof (*arr)[0], sizeof (*arr)[0][0], | |
| 2993 | + arr + 2 - arr, *arr + 3 - *arr, | |
| 2994 | + 0 == sizeof (*arr + 1) - sizeof arr, | |
| 2995 | + 0 == sizeof sizeof *arr - sizeof arr | |
| 2996 | + ); | |
| 2989 | 2997 | free (arr); |
| 2990 | 2998 | } |
| 2991 | 2999 | |