diff options
-rw-r--r-- | eval.c | 29 | ||||
-rw-r--r-- | test/const-expr-cast.c | 7 | ||||
-rw-r--r-- | test/const-expr-cast.qbe | 3 |
3 files changed, 36 insertions, 3 deletions
@@ -4,12 +4,33 @@ #include "util.h" #include "cc.h" +#define F (1<<8) +#define S (2<<8) +static void +cast(struct expr *expr) +{ + unsigned size; + + size = expr->type->size; + if (typeprop(expr->type) & PROPFLOAT) + size |= F; + else if (expr->type->basic.issigned) + size |= S; + switch (size) { + case 1: expr->constant.i = (uint8_t)expr->constant.i; break; + case 1|S: expr->constant.i = (int8_t)expr->constant.i; break; + case 2: expr->constant.i = (uint16_t)expr->constant.i; break; + case 2|S: expr->constant.i = (int16_t)expr->constant.i; break; + case 4: expr->constant.i = (uint32_t)expr->constant.i; break; + case 4|S: expr->constant.i = (int32_t)expr->constant.i; break; + case 4|F: expr->constant.f = (float)expr->constant.f; break; + } +} + static void binary(struct expr *expr, enum tokenkind op, struct expr *l, struct expr *r) { expr->kind = EXPRCONST; -#define F (1<<8) -#define S (2<<8) if (typeprop(l->type) & PROPFLOAT) op |= F; else if (l->type->basic.issigned) @@ -60,9 +81,10 @@ binary(struct expr *expr, enum tokenkind op, struct expr *l, struct expr *r) default: fatal("internal error; unknown binary expression"); } + cast(expr); +} #undef F #undef S -} struct expr * eval(struct expr *expr) @@ -110,6 +132,7 @@ eval(struct expr *expr) expr->constant.i = l->constant.f; else expr->constant = l->constant; + cast(expr); } else if (l->type->kind == TYPEPOINTER && expr->type->kind == TYPEPOINTER) { expr = l; } diff --git a/test/const-expr-cast.c b/test/const-expr-cast.c new file mode 100644 index 0000000..10a3eac --- /dev/null +++ b/test/const-expr-cast.c @@ -0,0 +1,7 @@ +enum { + A = (unsigned char)0x321, + B = (short)-2147438112, + C = 0x80000003 * 2, +}; + +int a = A, b = B, c = C; diff --git a/test/const-expr-cast.qbe b/test/const-expr-cast.qbe new file mode 100644 index 0000000..b36aefc --- /dev/null +++ b/test/const-expr-cast.qbe @@ -0,0 +1,3 @@ +export data $a = align 4 { w 33, } +export data $b = align 4 { w 18446744073709531616, } +export data $c = align 4 { w 6, } |