diff options
| -rw-r--r-- | pp.c | 3 | ||||
| -rw-r--r-- | stmt.c | 31 | ||||
| -rw-r--r-- | tests/label-typedef.c | 4 | ||||
| -rw-r--r-- | tests/label-typedef.qbe | 7 | 
4 files changed, 33 insertions, 12 deletions
| @@ -112,7 +112,8 @@ next(void)  bool  peek(int kind)  { -	nextinto(&pending); +	if (!pending.kind) +		nextinto(&pending);  	if (pending.kind != kind)  		return false;  	pending.kind = TNONE; @@ -14,6 +14,23 @@  #include "token.h"  #include "type.h" +static bool +gotolabel(struct function *f) +{ +	char *name; +	struct gotolabel *g; + +	if (tok.kind != TIDENT) +		return false; +	name = tok.lit; +	if (!peek(TCOLON)) +		return false; +	g = funcgoto(f, name); +	g->defined = true; +	funclabel(f, g->label); +	return true; +} +  /* 6.8 Statements and blocks */  void  stmt(struct function *f, struct scope *s) @@ -25,6 +42,8 @@ stmt(struct function *f, struct scope *s)  	struct switchcases swtch = {0};  	uint64_t i; +	while (gotolabel(f)) +		;  	switch (tok.kind) {  	/* 6.8.1 Labeled statements */  	case TCASE: @@ -55,7 +74,7 @@ stmt(struct function *f, struct scope *s)  		next();  		s = mkscope(s);  		while (tok.kind != TRBRACE) { -			if (!decl(s, f)) +			if (gotolabel(f) || !decl(s, f))  				stmt(f, s);  		}  		s = delscope(s); @@ -66,16 +85,6 @@ stmt(struct function *f, struct scope *s)  	case TSEMICOLON:  		next();  		break; -	case TIDENT: -		name = tok.lit; -		if (peek(TCOLON)) { -			struct gotolabel *g = funcgoto(f, name); -			g->defined = true; -			funclabel(f, g->label); -			stmt(f, s); -			break; -		} -		/* fallthrough */  	default:  		e = expr(s);  		v = funcexpr(f, e); diff --git a/tests/label-typedef.c b/tests/label-typedef.c new file mode 100644 index 0000000..f3744e3 --- /dev/null +++ b/tests/label-typedef.c @@ -0,0 +1,4 @@ +typedef int x; +void f(void) { +x:; +} diff --git a/tests/label-typedef.qbe b/tests/label-typedef.qbe new file mode 100644 index 0000000..b11f621 --- /dev/null +++ b/tests/label-typedef.qbe @@ -0,0 +1,7 @@ +export +function $f() { +@start.1 +@body.2 +@x.3 +	ret +} | 
