cproc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/cproc
Log | Files | Refs | Submodules | README | LICENSE

commit 82590e5121136414c78d17454d666084d7b19302
parent 8c343ad7edd73c169d865c64e7868e3ec447ecda
Author: Michael Forney <mforney@mforney.org>
Date:   Sat, 20 Apr 2019 20:24:52 -0700

eval: Handle casts in constant expressions

Fixes #23.

Diffstat:
Meval.c | 29++++++++++++++++++++++++++---
Atest/const-expr-cast.c | 7+++++++
Atest/const-expr-cast.qbe | 3+++
3 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/eval.c b/eval.c @@ -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 @@ -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 @@ -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, }