[PATCH v1 21/28] scope: give a scope for labels & gotos

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxx>
---
 parse.c  | 8 +++++++-
 parse.h  | 1 +
 symbol.h | 4 ++++
 3 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/parse.c b/parse.c
index ecc33765e1ef..bf45e3b0ea44 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);
 		}
diff --git a/parse.h b/parse.h
index 0742a2a87e9d..daef243938b2 100644
--- a/parse.h
+++ b/parse.h
@@ -72,6 +72,7 @@ struct statement {
 		};
 		struct /* labeled_struct */ {
 			struct symbol *label_identifier;
+			struct scope *label_scope;
 			struct statement *label_statement;
 		};
 		struct /* case_struct */ {
diff --git a/symbol.h b/symbol.h
index c297c778dfdf..2293d06dd4fb 100644
--- a/symbol.h
+++ b/symbol.h
@@ -167,6 +167,10 @@ struct symbol {
 			int (*handler)(struct stream *, struct token **, struct token *);
 			int normal;
 		};
+		struct /* NS_LABEL */ {
+			struct scope *label_scope;
+			struct position label_pos;
+		};
 		struct /* NS_SYMBOL */ {
 			unsigned long	offset;
 			int		bit_size;
-- 
2.26.2




[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux