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); 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) static void parse_builtin_params(int nc, const char *args)
{ {
char c, sep = '('; char c, sep = '(';
@ -4345,33 +4337,32 @@ ST_FUNC void unary(void)
case TOK_CINT: case TOK_CINT:
case TOK_CCHAR: case TOK_CCHAR:
case TOK_LCHAR: case TOK_LCHAR:
vpushi(tokc.i); t = VT_INT;
push_tokc:
type.t = t;
type.ref = 0;
vsetc(&type, VT_CONST, &tokc);
next(); next();
break; break;
case TOK_CUINT: case TOK_CUINT:
vpush_tokc(VT_INT | VT_UNSIGNED); t = VT_INT | VT_UNSIGNED;
next(); goto push_tokc;
break;
case TOK_CLLONG: case TOK_CLLONG:
vpush_tokc(VT_LLONG); t = VT_LLONG;
next(); goto push_tokc;
break;
case TOK_CULLONG: case TOK_CULLONG:
vpush_tokc(VT_LLONG | VT_UNSIGNED); t =VT_LLONG | VT_UNSIGNED;
next(); goto push_tokc;
break;
case TOK_CFLOAT: case TOK_CFLOAT:
vpush_tokc(VT_FLOAT); t = VT_FLOAT;
next(); goto push_tokc;
break;
case TOK_CDOUBLE: case TOK_CDOUBLE:
vpush_tokc(VT_DOUBLE); t = VT_DOUBLE;
next(); goto push_tokc;
break;
case TOK_CLDOUBLE: case TOK_CLDOUBLE:
vpush_tokc(VT_LDOUBLE); t = VT_LDOUBLE;
next(); goto push_tokc;
break;
case TOK___FUNCTION__: case TOK___FUNCTION__:
if (!gnu_ext) if (!gnu_ext)
goto tok_identifier; 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_CUINT:
case TOK_CCHAR: case TOK_CCHAR:
case TOK_LCHAR: case TOK_LCHAR:
case TOK_CFLOAT:
case TOK_LINENUM: case TOK_LINENUM:
tab[0] = *p++; tab[0] = *p++;
cv->i = (*t == TOK_CUINT) ? (unsigned)cv->i : (int)cv->i;
break; break;
case TOK_CFLOAT:
tab[0] = *p++;
break;
case TOK_STR: case TOK_STR:
case TOK_LSTR: case TOK_LSTR:
case TOK_PPNUM: case TOK_PPNUM:

View File

@ -3720,8 +3720,6 @@ typedef struct __attribute__((__packed__)) {
int c; int c;
} Spacked2; } Spacked2;
Spacked2 spacked2; Spacked2 spacked2;
/* This doesn't work for now. Requires adjusting field offsets/sizes
after parsing the struct members. */
typedef struct Spacked3_s { typedef struct Spacked3_s {
char a; char a;
short b; short b;
@ -3754,3 +3752,24 @@ void * __attribute__((__unused__)) get_void_ptr (void *a)
{ {
return 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);
}