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.
master
Michael Matz 2017-03-06 21:45:41 +01:00
parent 21b12ea10d
commit 8ca98e23c4
3 changed files with 43 additions and 30 deletions

View File

@ -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;

View File

@ -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:

View File

@ -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);
}