scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit 886bd49d93db4ea06014b50df0827f3788584259
parent 1cd7549a09f4c1d125bb04a641aab05a83e5f2b9
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Wed,  9 Jul 2014 18:28:03 +0200

Force switch value to be integer

switch only accepts integer values, so this patch forces it.

Diffstat:
Mcc1/stmt.c | 20+++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/cc1/stmt.c b/cc1/stmt.c @@ -203,27 +203,33 @@ static void Switch(Symbol *lbreak, Symbol *lcont, Caselist *lswitch) { Caselist lcase = {.nr = 0, .head = NULL, .deflabel = NULL}; - struct scase *p; + struct scase *p, *next; Node *cond; Symbol *lcond; + void free(void *ptr); - lbreak = install("", NS_LABEL); - lcond = install("", NS_LABEL); expect(SWITCH); expect ('('); - cond = eval(expr()); + if ((cond = expr()) == NULL) + error("expected expression before '%s'", yytext); + if ((cond = convert(cond, inttype, 0)) == NULL) + error("incorrect type in switch statement"); expect (')'); - /* TODO: check integer type */ + + lbreak = install("", NS_LABEL); + lcond = install("", NS_LABEL); emitjump(lcond, NULL); stmt(lbreak, lcont, &lcase); emitlabel(lcond); emitswitch(lcase.nr, cond); - for (p = lcase.head; p; p = p->next) + for (p = lcase.head; p; p = next) { emitcase(p->label, p->expr); + next = p->next; + free(p); + } if (lcase.deflabel) emitdefault(lcase.deflabel); emitlabel(lbreak); - /* TODO: free memory */ } static void