mirror of
https://github.com/mirror/tinycc.git
synced 2024-12-26 03:50:07 +08:00
tccgen: multi-dimensional vla: bug fixes
fixes these cases: ptr - ptr (-> ptrdiff_t) ptr +/- num (-> ptr) sizeof (ptr+/-num) (-> size_t) Also some cleanups
This commit is contained in:
parent
ec5d94291c
commit
0c6adcbe53
68
tccgen.c
68
tccgen.c
@ -234,7 +234,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has
|
|||||||
static void decl(int l);
|
static void decl(int l);
|
||||||
static int decl0(int l, int is_for_loop_init, Sym *);
|
static int decl0(int l, int is_for_loop_init, Sym *);
|
||||||
static void expr_eq(void);
|
static void expr_eq(void);
|
||||||
static void vla_runtime_type_size(CType *type, int *a);
|
static void vpush_type_size(CType *type, int *a);
|
||||||
static int is_compatible_unqualified_types(CType *type1, CType *type2);
|
static int is_compatible_unqualified_types(CType *type1, CType *type2);
|
||||||
static inline int64_t expr_const64(void);
|
static inline int64_t expr_const64(void);
|
||||||
static void vpush64(int ty, unsigned long long v);
|
static void vpush64(int ty, unsigned long long v);
|
||||||
@ -3173,7 +3173,7 @@ static void type_to_str(char *buf, int buf_size,
|
|||||||
goto no_var;
|
goto no_var;
|
||||||
case VT_PTR:
|
case VT_PTR:
|
||||||
s = type->ref;
|
s = type->ref;
|
||||||
if (t & VT_ARRAY) {
|
if (t & (VT_ARRAY|VT_VLA)) {
|
||||||
if (varstr && '*' == *varstr)
|
if (varstr && '*' == *varstr)
|
||||||
snprintf(buf1, sizeof(buf1), "(%s)[%d]", varstr, s->c);
|
snprintf(buf1, sizeof(buf1), "(%s)[%d]", varstr, s->c);
|
||||||
else
|
else
|
||||||
@ -3220,12 +3220,6 @@ static int pointed_size(CType *type)
|
|||||||
return type_size(pointed_type(type), &align);
|
return type_size(pointed_type(type), &align);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vla_runtime_pointed_size(CType *type)
|
|
||||||
{
|
|
||||||
int align;
|
|
||||||
vla_runtime_type_size(pointed_type(type), &align);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int is_null_pointer(SValue *p)
|
static inline int is_null_pointer(SValue *p)
|
||||||
{
|
{
|
||||||
if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
|
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)
|
|||||||
/* generic gen_op: handles types problems */
|
/* generic gen_op: handles types problems */
|
||||||
ST_FUNC void gen_op(int op)
|
ST_FUNC void gen_op(int op)
|
||||||
{
|
{
|
||||||
int u, t1, t2, bt1, bt2, t;
|
int t1, t2, bt1, bt2, t;
|
||||||
CType type1, combtype;
|
CType type1, combtype;
|
||||||
|
|
||||||
redo:
|
redo:
|
||||||
@ -3463,17 +3457,14 @@ redo:
|
|||||||
} else if (bt1 == VT_PTR || bt2 == VT_PTR) {
|
} else if (bt1 == VT_PTR || bt2 == VT_PTR) {
|
||||||
/* at least one operand is a pointer */
|
/* at least one operand is a pointer */
|
||||||
/* relational op: must be both pointers */
|
/* relational op: must be both pointers */
|
||||||
|
int align;
|
||||||
if (TOK_ISCOND(op))
|
if (TOK_ISCOND(op))
|
||||||
goto std_op;
|
goto std_op;
|
||||||
/* if both pointers, then it must be the '-' op */
|
/* if both pointers, then it must be the '-' op */
|
||||||
if (bt1 == VT_PTR && bt2 == VT_PTR) {
|
if (bt1 == VT_PTR && bt2 == VT_PTR) {
|
||||||
if (op != '-')
|
if (op != '-')
|
||||||
tcc_error("cannot use pointers here");
|
tcc_error("cannot use pointers here");
|
||||||
if (vtop[-1].type.t & VT_VLA) {
|
vpush_type_size(pointed_type(&vtop[-1].type), &align);
|
||||||
vla_runtime_pointed_size(&vtop[-1].type);
|
|
||||||
} else {
|
|
||||||
vpushi(pointed_size(&vtop[-1].type));
|
|
||||||
}
|
|
||||||
vrott(3);
|
vrott(3);
|
||||||
gen_opic(op);
|
gen_opic(op);
|
||||||
vtop->type.t = VT_PTRDIFF_T;
|
vtop->type.t = VT_PTRDIFF_T;
|
||||||
@ -3494,19 +3485,7 @@ redo:
|
|||||||
gen_cast_s(VT_INT);
|
gen_cast_s(VT_INT);
|
||||||
#endif
|
#endif
|
||||||
type1 = vtop[-1].type;
|
type1 = vtop[-1].type;
|
||||||
if (vtop[-1].type.ref->type.t & VT_VLA)
|
vpush_type_size(pointed_type(&vtop[-1].type), &align);
|
||||||
vla_runtime_pointed_size(&vtop[-1].type);
|
|
||||||
else {
|
|
||||||
u = pointed_size(&vtop[-1].type);
|
|
||||||
if (u < 0)
|
|
||||||
tcc_error("unknown array element size");
|
|
||||||
#if PTR_SIZE == 8
|
|
||||||
vpushll(u);
|
|
||||||
#else
|
|
||||||
/* XXX: cast to int ? (long long case) */
|
|
||||||
vpushi(u);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
gen_op('*');
|
gen_op('*');
|
||||||
#ifdef CONFIG_TCC_BCHECK
|
#ifdef CONFIG_TCC_BCHECK
|
||||||
if (tcc_state->do_bounds_check && !const_wanted) {
|
if (tcc_state->do_bounds_check && !const_wanted) {
|
||||||
@ -3523,7 +3502,7 @@ redo:
|
|||||||
{
|
{
|
||||||
gen_opic(op);
|
gen_opic(op);
|
||||||
}
|
}
|
||||||
type1.t &= ~VT_ARRAY;
|
type1.t &= ~(VT_ARRAY|VT_VLA);
|
||||||
/* put again type if gen_opic() swaped operands */
|
/* put again type if gen_opic() swaped operands */
|
||||||
vtop->type = type1;
|
vtop->type = type1;
|
||||||
}
|
}
|
||||||
@ -3957,13 +3936,16 @@ ST_FUNC int type_size(CType *type, int *a)
|
|||||||
|
|
||||||
/* push type size as known at runtime time on top of value stack. Put
|
/* push type size as known at runtime time on top of value stack. Put
|
||||||
alignment at 'a' */
|
alignment at 'a' */
|
||||||
ST_FUNC void vla_runtime_type_size(CType *type, int *a)
|
static void vpush_type_size(CType *type, int *a)
|
||||||
{
|
{
|
||||||
if (type->t & VT_VLA) {
|
if (type->t & VT_VLA) {
|
||||||
type_size(&type->ref->type, a);
|
type_size(&type->ref->type, a);
|
||||||
vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
|
vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
|
||||||
} else {
|
} else {
|
||||||
vpushi(type_size(type, a));
|
int size = type_size(type, a);
|
||||||
|
if (size < 0)
|
||||||
|
tcc_error("unknown type size");
|
||||||
|
vpushi(size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5501,7 +5483,7 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td)
|
|||||||
loc &= -align;
|
loc &= -align;
|
||||||
n = loc;
|
n = loc;
|
||||||
|
|
||||||
vla_runtime_type_size(type, &align);
|
vpush_type_size(type, &align);
|
||||||
gen_op('*');
|
gen_op('*');
|
||||||
vset(&int_type, VT_LOCAL|VT_LVAL, n);
|
vset(&int_type, VT_LOCAL|VT_LVAL, n);
|
||||||
vswap();
|
vswap();
|
||||||
@ -6050,24 +6032,18 @@ ST_FUNC void unary(void)
|
|||||||
next();
|
next();
|
||||||
in_sizeof++;
|
in_sizeof++;
|
||||||
expr_type(&type, unary); /* Perform a in_sizeof = 0; */
|
expr_type(&type, unary); /* Perform a in_sizeof = 0; */
|
||||||
s = NULL;
|
|
||||||
if (vtop[1].r & VT_SYM)
|
|
||||||
s = vtop[1].sym; /* hack: accessing previous vtop */
|
|
||||||
size = type_size(&type, &align);
|
|
||||||
if (s && s->a.aligned)
|
|
||||||
align = 1 << (s->a.aligned - 1);
|
|
||||||
if (t == TOK_SIZEOF) {
|
if (t == TOK_SIZEOF) {
|
||||||
if (!(type.t & VT_VLA)) {
|
vpush_type_size(&type, &align);
|
||||||
if (size < 0)
|
gen_cast_s(VT_SIZE_T);
|
||||||
tcc_error("sizeof applied to an incomplete type");
|
|
||||||
vpushs(size);
|
|
||||||
} else {
|
|
||||||
vla_runtime_type_size(&type, &align);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
|
type_size(&type, &align);
|
||||||
|
s = NULL;
|
||||||
|
if (vtop[1].r & VT_SYM)
|
||||||
|
s = vtop[1].sym; /* hack: accessing previous vtop */
|
||||||
|
if (s && s->a.aligned)
|
||||||
|
align = 1 << (s->a.aligned - 1);
|
||||||
vpushs(align);
|
vpushs(align);
|
||||||
}
|
}
|
||||||
vtop->type.t |= VT_UNSIGNED;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_builtin_expect:
|
case TOK_builtin_expect:
|
||||||
@ -8566,7 +8542,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vla_runtime_type_size(type, &a);
|
vpush_type_size(type, &a);
|
||||||
gen_vla_alloc(type, a);
|
gen_vla_alloc(type, a);
|
||||||
#if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
|
#if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
|
||||||
/* on _WIN64, because of the function args scratch area, the
|
/* 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)
|
|||||||
for (z=0; z<d; z++) {
|
for (z=0; z<d; z++) {
|
||||||
for (y=0; y<h; y++) {
|
for (y=0; y<h; y++) {
|
||||||
for (x=0; x<w; x++) {
|
for (x=0; x<w; x++) {
|
||||||
printf("% 4i", arr[z][y][x]);
|
printf(" %2d", arr[z][y][x]);
|
||||||
}
|
}
|
||||||
puts("");
|
puts("");
|
||||||
}
|
}
|
||||||
puts("");
|
puts("");
|
||||||
}
|
}
|
||||||
|
printf(" sizes : %d %d %d\n"
|
||||||
|
" pdiff : %d %d\n"
|
||||||
|
" tests : %d %d\n",
|
||||||
|
sizeof (*arr), sizeof (*arr)[0], sizeof (*arr)[0][0],
|
||||||
|
arr + 2 - arr, *arr + 3 - *arr,
|
||||||
|
0 == sizeof (*arr + 1) - sizeof arr,
|
||||||
|
0 == sizeof sizeof *arr - sizeof arr
|
||||||
|
);
|
||||||
free (arr);
|
free (arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user