aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/parse.c
diff options
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-04-09 09:14:01 +0200
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-05-21 17:27:45 +0200
commit177f5fe2255e2fd16040c802a7298ec21a29bd80 (patch)
treee4689872972c4217c2caad41c557bdc2a2474f29 /parse.c
parenteff5e6c1a4e6c36614dcfaa0213e2ccf57e844a3 (diff)
downloadsparse-dev-177f5fe2255e2fd16040c802a7298ec21a29bd80.tar.gz
scope: give a scope for labels & gotos
One way of detecting gotos inside an statement expression is to use a new kind of scope for the gotos & labels. Since gotos don't need to have their label predeclared, nothing can be checked at parsing time but later it can be checked that a goto doesn't jump inside one of the label scope created by statement expressions. So, add additional scope information to gotos and labels to allow such check to be done. Note: the label's symbols are still created in the function scope since they belong to a single namespace. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Diffstat (limited to 'parse.c')
-rw-r--r--parse.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/parse.c b/parse.c
index ecc33765..bf45e3b0 100644
--- a/parse.c
+++ b/parse.c
@@ -2488,7 +2488,12 @@ static struct token *parse_goto_statement(struct token *token, struct statement
token = parse_expression(token->next, &stmt->goto_expression);
add_statement(&function_computed_goto_list, stmt);
} else if (token_type(token) == TOKEN_IDENT) {
- stmt->goto_label = label_symbol(token);
+ struct symbol *label = label_symbol(token);
+ stmt->goto_label = label;
+ if (!label->stmt && !label->label_scope) {
+ label->label_scope = label_scope;
+ label->label_pos = stmt->pos;
+ }
token = token->next;
} else {
sparse_error(token->pos, "Expected identifier or goto expression");
@@ -2549,6 +2554,7 @@ static struct token *statement(struct token *token, struct statement **tree)
}
stmt->type = STMT_LABEL;
stmt->label_identifier = s;
+ stmt->label_scope = label_scope;
s->stmt = stmt;
return statement(token, &stmt->label_statement);
}