Correctly support all unary expression with sizeof
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
This commit is contained in:
parent
6655e06ec8
commit
8de9b7a631
1 changed files with 19 additions and 6 deletions
25
tccgen.c
25
tccgen.c
|
|
@ -284,6 +284,13 @@ static void vsetc(CType *type, int r, CValue *vc)
|
||||||
vtop->c = *vc;
|
vtop->c = *vc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* push constant of type "type" with useless value */
|
||||||
|
void vpush(CType *type)
|
||||||
|
{
|
||||||
|
CValue cval;
|
||||||
|
vsetc(type, VT_CONST, &cval);
|
||||||
|
}
|
||||||
|
|
||||||
/* push integer constant */
|
/* push integer constant */
|
||||||
ST_FUNC void vpushi(int v)
|
ST_FUNC void vpushi(int v)
|
||||||
{
|
{
|
||||||
|
|
@ -3244,11 +3251,14 @@ static void vpush_tokc(int t)
|
||||||
|
|
||||||
ST_FUNC void unary(void)
|
ST_FUNC void unary(void)
|
||||||
{
|
{
|
||||||
int n, t, align, size, r;
|
int n, t, align, size, r, sizeof_caller;
|
||||||
CType type;
|
CType type;
|
||||||
Sym *s;
|
Sym *s;
|
||||||
AttributeDef ad;
|
AttributeDef ad;
|
||||||
|
static int in_sizeof = 0;
|
||||||
|
|
||||||
|
sizeof_caller = in_sizeof;
|
||||||
|
in_sizeof = 0;
|
||||||
/* XXX: GCC 2.95.3 does not generate a table although it should be
|
/* XXX: GCC 2.95.3 does not generate a table although it should be
|
||||||
better here */
|
better here */
|
||||||
tok_next:
|
tok_next:
|
||||||
|
|
@ -3345,6 +3355,10 @@ ST_FUNC void unary(void)
|
||||||
memset(&ad, 0, sizeof(AttributeDef));
|
memset(&ad, 0, sizeof(AttributeDef));
|
||||||
decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
|
decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
|
||||||
} else {
|
} else {
|
||||||
|
if (sizeof_caller) {
|
||||||
|
vpush(&type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
unary();
|
unary();
|
||||||
gen_cast(&type);
|
gen_cast(&type);
|
||||||
}
|
}
|
||||||
|
|
@ -3414,11 +3428,8 @@ ST_FUNC void unary(void)
|
||||||
case TOK_ALIGNOF2:
|
case TOK_ALIGNOF2:
|
||||||
t = tok;
|
t = tok;
|
||||||
next();
|
next();
|
||||||
if (tok == '(') {
|
in_sizeof++;
|
||||||
parse_expr_type(&type);
|
unary_type(&type); // Perform a in_sizeof = 0;
|
||||||
} else {
|
|
||||||
unary_type(&type);
|
|
||||||
}
|
|
||||||
size = type_size(&type, &align);
|
size = type_size(&type, &align);
|
||||||
if (t == TOK_SIZEOF) {
|
if (t == TOK_SIZEOF) {
|
||||||
if (size < 0)
|
if (size < 0)
|
||||||
|
|
@ -4040,9 +4051,11 @@ static void expr_type(CType *type)
|
||||||
static void unary_type(CType *type)
|
static void unary_type(CType *type)
|
||||||
{
|
{
|
||||||
int a;
|
int a;
|
||||||
|
void *vtop_saved;
|
||||||
|
|
||||||
a = nocode_wanted;
|
a = nocode_wanted;
|
||||||
nocode_wanted = 1;
|
nocode_wanted = 1;
|
||||||
|
vtop_saved = vtop;
|
||||||
unary();
|
unary();
|
||||||
*type = vtop->type;
|
*type = vtop->type;
|
||||||
vpop();
|
vpop();
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue