summaryrefslogtreecommitdiff
path: root/parser.c
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2011-03-23 14:50:18 -0400
committerSøren Sandmann Pedersen <ssp@redhat.com>2011-03-23 14:50:18 -0400
commit5beefbe664a5b3458a746a8ce4366bdb66daefe2 (patch)
tree0d123caa0f9a26dbceb8b02ee864e20612da1100 /parser.c
parent09962a3ac95969dc68ac67fe66ffaf172d3b4671 (diff)
Fix bugs in variable definitions inside expressions
If such expressions don't have an initializer, they can be confused with "case clauses". So require them to have an initializer. Example. Here: case 100 + i: break; the "i:" would be considered the beginning of variable definition, and then the break would cause a parse error.
Diffstat (limited to 'parser.c')
-rw-r--r--parser.c51
1 files changed, 26 insertions, 25 deletions
diff --git a/parser.c b/parser.c
index 40b4f7d..e253dd3 100644
--- a/parser.c
+++ b/parser.c
@@ -1281,37 +1281,38 @@ parse_expression_helper (const token_t *in,
ast_definition_t *def;
ast_type_spec_t *type;
+ type = NULL;
+
/* Variable declaration */
- if (!left &&
- (tmp = parse_token (t, TOKEN_IDENTIFIER)) &&
- (tmp = parse_token (tmp, TOKEN_COLON)))
+ if (!left &&
+ (((tmp = parse_token (t, TOKEN_IDENTIFIER)) &&
+ (tmp = parse_token (tmp, TOKEN_COLON)) &&
+ (tmp = parse_type_spec (tmp, &type)) &&
+ (tmp = parse_token (tmp, TOKEN_ASSIGN)) &&
+ (tmp = parse_expression (tmp, &right))) ||
+ ((tmp = parse_token (t, TOKEN_IDENTIFIER)) &&
+ (tmp = parse_token (tmp, TOKEN_COLON)) &&
+ (tmp = parse_token (tmp, TOKEN_ASSIGN)) &&
+ (tmp = parse_expression (tmp, &right)))))
{
char *name = g_strdup (t->identifier.name);
- if ((tmp2 = parse_type_spec (tmp, &type)))
- tmp = tmp2;
- else
+ if (!type)
type = ast_type_spec_new (AST_INFERRED_TYPE);
- if ((tmp = parse_token (tmp, TOKEN_ASSIGN)) &&
- (tmp = rest_of_expression (tmp, NULL, ASSIGNMENT_LEVEL, &right)))
- {
- g_assert (right);
-
- def = ast_definition_new_variable (name, type);
-
- *result = ast_expression_new_statement (
- ast_statement_new_definition (def),
- ast_expression_new_binary (
- AST_ASSIGN,
- ast_expression_new_identifier (def->variable.name),
- right));
-
- if (type->common.type == AST_INFERRED_TYPE)
- right->common.type_inferrer = &def->variable;
-
- return tmp;
- }
+ def = ast_definition_new_variable (name, type);
+
+ *result = ast_expression_new_statement (
+ ast_statement_new_definition (def),
+ ast_expression_new_binary (
+ AST_ASSIGN,
+ ast_expression_new_identifier (def->variable.name),
+ right));
+
+ if (type->common.type == AST_INFERRED_TYPE)
+ right->common.type_inferrer = &def->variable;
+
+ return tmp;
}
/* Lambda expression */
else if (!left &&