]> git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
pass parent scope to parse_statement_or_block
authorDale Weiler <weilercdale@gmail.com>
Tue, 2 Mar 2021 15:46:05 +0000 (10:46 -0500)
committerDale Weiler <weilercdale@gmail.com>
Tue, 2 Mar 2021 15:46:05 +0000 (10:46 -0500)
previous behavior when parsing a statement where a block is typically expected would fail to associate the statement with the parent block it's in, resulting in variable declarations ending up in global scope.

this fixes #197

parser.cpp
tests/parent_block_scope_for_locals.qc [new file with mode: 0644]
tests/parent_block_scope_for_locals.tmpl [new file with mode: 0644]

index b0afc79c1d990460af4ee2951d522595d42c70fe..ac28fd7a3cac0803742d24662be8ad208a08ce6a 100644 (file)
@@ -20,7 +20,7 @@ static bool parse_typedef(parser_t *parser);
 static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofields, int qualifier, ast_value *cached_typedef, bool noref, bool is_static, uint32_t qflags, char *vstring);
 static ast_block* parse_block(parser_t *parser);
 static bool parse_block_into(parser_t *parser, ast_block *block);
-static bool parse_statement_or_block(parser_t *parser, ast_expression **out);
+static bool parse_statement_or_block(parser_t *parser, ast_block* parent_block, ast_expression **out);
 static bool parse_statement(parser_t *parser, ast_block *block, ast_expression **out, bool allow_cases);
 static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma, bool truthvalue, bool with_labels);
 static ast_expression* parse_expression(parser_t *parser, bool stopatcomma, bool with_labels);
@@ -2162,7 +2162,7 @@ static bool parse_if(parser_t *parser, ast_block *block, ast_expression **out)
         ast_unref(cond);
         return false;
     }
-    if (!parse_statement_or_block(parser, &ontrue)) {
+    if (!parse_statement_or_block(parser, block, &ontrue)) {
         ast_unref(cond);
         return false;
     }
@@ -2177,7 +2177,7 @@ static bool parse_if(parser_t *parser, ast_block *block, ast_expression **out)
             ast_unref(cond);
             return false;
         }
-        if (!parse_statement_or_block(parser, &onfalse)) {
+        if (!parse_statement_or_block(parser, block, &onfalse)) {
             delete ontrue;
             ast_unref(cond);
             return false;
@@ -2285,7 +2285,7 @@ static bool parse_while_go(parser_t *parser, ast_block *block, ast_expression **
         ast_unref(cond);
         return false;
     }
-    if (!parse_statement_or_block(parser, &ontrue)) {
+    if (!parse_statement_or_block(parser, block, &ontrue)) {
         ast_unref(cond);
         return false;
     }
@@ -2360,7 +2360,7 @@ static bool parse_dowhile_go(parser_t *parser, ast_block *block, ast_expression
 
     (void)block; /* not touching */
 
-    if (!parse_statement_or_block(parser, &ontrue))
+    if (!parse_statement_or_block(parser, block, &ontrue))
         return false;
 
     /* expect the "while" */
@@ -2561,7 +2561,7 @@ static bool parse_for_go(parser_t *parser, ast_block *block, ast_expression **ou
         parseerror(parser, "expected for-loop body");
         goto onerr;
     }
-    if (!parse_statement_or_block(parser, &ontrue))
+    if (!parse_statement_or_block(parser, block, &ontrue))
         goto onerr;
 
     if (cond) {
@@ -3805,13 +3805,13 @@ static ast_block* parse_block(parser_t *parser)
     return block;
 }
 
-static bool parse_statement_or_block(parser_t *parser, ast_expression **out)
+static bool parse_statement_or_block(parser_t *parser, ast_block* parent_block, ast_expression **out)
 {
     if (parser->tok == '{') {
         *out = parse_block(parser);
         return !!*out;
     }
-    return parse_statement(parser, nullptr, out, false);
+    return parse_statement(parser, parent_block, out, false);
 }
 
 static bool create_vector_members(ast_value *var, ast_member **me)
diff --git a/tests/parent_block_scope_for_locals.qc b/tests/parent_block_scope_for_locals.qc
new file mode 100644 (file)
index 0000000..fc3eef5
--- /dev/null
@@ -0,0 +1,16 @@
+void a() {
+       if (1)
+               for (float i = 0; i < 3; ++i)
+                       print(ftos(i));
+}
+
+void b() {
+       if (1)
+               for (float i = 0; i < 3; ++i)
+                       print(ftos(i));
+}
+
+void main() {
+       a();
+       b();
+}
\ No newline at end of file
diff --git a/tests/parent_block_scope_for_locals.tmpl b/tests/parent_block_scope_for_locals.tmpl
new file mode 100644 (file)
index 0000000..2eb9ae2
--- /dev/null
@@ -0,0 +1,5 @@
+I: parent_block_scope_for_locals.qc
+D: when omitting braces ensure locals end up in parent block
+T: -execute
+C: -std=fteqcc
+M: 012012