mirror of
https://github.com/frida/tinycc
synced 2025-01-03 02:24:24 +03:00
Tidy unary() a bit
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.
This commit is contained in:
parent
21b12ea10d
commit
8ca98e23c4
45
tccgen.c
45
tccgen.c
@ -4297,14 +4297,6 @@ static void parse_type(CType *type)
|
||||
type_decl(type, &ad, &n, TYPE_ABSTRACT);
|
||||
}
|
||||
|
||||
static void vpush_tokc(int t)
|
||||
{
|
||||
CType type;
|
||||
type.t = t;
|
||||
type.ref = 0;
|
||||
vsetc(&type, VT_CONST, &tokc);
|
||||
}
|
||||
|
||||
static void parse_builtin_params(int nc, const char *args)
|
||||
{
|
||||
char c, sep = '(';
|
||||
@ -4345,33 +4337,32 @@ ST_FUNC void unary(void)
|
||||
case TOK_CINT:
|
||||
case TOK_CCHAR:
|
||||
case TOK_LCHAR:
|
||||
vpushi(tokc.i);
|
||||
t = VT_INT;
|
||||
push_tokc:
|
||||
type.t = t;
|
||||
type.ref = 0;
|
||||
vsetc(&type, VT_CONST, &tokc);
|
||||
next();
|
||||
break;
|
||||
case TOK_CUINT:
|
||||
vpush_tokc(VT_INT | VT_UNSIGNED);
|
||||
next();
|
||||
break;
|
||||
t = VT_INT | VT_UNSIGNED;
|
||||
goto push_tokc;
|
||||
case TOK_CLLONG:
|
||||
vpush_tokc(VT_LLONG);
|
||||
next();
|
||||
break;
|
||||
t = VT_LLONG;
|
||||
goto push_tokc;
|
||||
case TOK_CULLONG:
|
||||
vpush_tokc(VT_LLONG | VT_UNSIGNED);
|
||||
next();
|
||||
break;
|
||||
t =VT_LLONG | VT_UNSIGNED;
|
||||
goto push_tokc;
|
||||
case TOK_CFLOAT:
|
||||
vpush_tokc(VT_FLOAT);
|
||||
next();
|
||||
break;
|
||||
t = VT_FLOAT;
|
||||
goto push_tokc;
|
||||
case TOK_CDOUBLE:
|
||||
vpush_tokc(VT_DOUBLE);
|
||||
next();
|
||||
break;
|
||||
t = VT_DOUBLE;
|
||||
goto push_tokc;
|
||||
case TOK_CLDOUBLE:
|
||||
vpush_tokc(VT_LDOUBLE);
|
||||
next();
|
||||
break;
|
||||
t = VT_LDOUBLE;
|
||||
goto push_tokc;
|
||||
|
||||
case TOK___FUNCTION__:
|
||||
if (!gnu_ext)
|
||||
goto tok_identifier;
|
||||
|
5
tccpp.c
5
tccpp.c
@ -1230,10 +1230,13 @@ static inline void TOK_GET(int *t, const int **pp, CValue *cv)
|
||||
case TOK_CUINT:
|
||||
case TOK_CCHAR:
|
||||
case TOK_LCHAR:
|
||||
case TOK_CFLOAT:
|
||||
case TOK_LINENUM:
|
||||
tab[0] = *p++;
|
||||
cv->i = (*t == TOK_CUINT) ? (unsigned)cv->i : (int)cv->i;
|
||||
break;
|
||||
case TOK_CFLOAT:
|
||||
tab[0] = *p++;
|
||||
break;
|
||||
case TOK_STR:
|
||||
case TOK_LSTR:
|
||||
case TOK_PPNUM:
|
||||
|
@ -3720,8 +3720,6 @@ typedef struct __attribute__((__packed__)) {
|
||||
int c;
|
||||
} Spacked2;
|
||||
Spacked2 spacked2;
|
||||
/* This doesn't work for now. Requires adjusting field offsets/sizes
|
||||
after parsing the struct members. */
|
||||
typedef struct Spacked3_s {
|
||||
char a;
|
||||
short b;
|
||||
@ -3754,3 +3752,24 @@ void * __attribute__((__unused__)) get_void_ptr (void *a)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
/* This part checks for a bug in TOK_GET (used for inline expansion),
|
||||
where the large long long constant left the the high bits set for
|
||||
the integer constant token. */
|
||||
static inline
|
||||
int __get_order(unsigned long long size)
|
||||
{
|
||||
int order;
|
||||
size -= 0xffff880000000000ULL; // this const left high bits set in the token
|
||||
{
|
||||
struct S { int i : 1; } s; // constructed for this '1'
|
||||
}
|
||||
order = size;
|
||||
return order;
|
||||
}
|
||||
|
||||
/* This just forces the above inline function to be actually emitted. */
|
||||
int force_get_order(unsigned long s)
|
||||
{
|
||||
return __get_order(s);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user