]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
vala: Enforce "return yield ..." syntax to be expected 898e45a6ff6129fc5c674af48118042dd64123ff
authorRico Tzschichholz <ricotz@ubuntu.com>
Sat, 22 Sep 2018 12:44:40 +0000 (14:44 +0200)
committerRico Tzschichholz <ricotz@ubuntu.com>
Sat, 22 Sep 2018 14:28:33 +0000 (16:28 +0200)
"yield return ..." wasn't handled correctly and resulted in broken c-code.

Fixes https://gitlab.gnome.org/GNOME/vala/issues/675

codegen/valagasyncmodule.vala
tests/Makefile.am
tests/parser/yield-return.test [new file with mode: 0644]
vala/valacodewriter.vala
vala/valagenieparser.vala
vala/valaparser.vala
vala/valayieldstatement.vala

index 9d63ab7adfc19e7cbb407826f60b22f237e78532..f234afdb440929437a92bfe5a2e36d159ded6de6 100644 (file)
@@ -773,37 +773,12 @@ public class Vala.GAsyncModule : GtkModule {
                        return;
                }
 
-               if (stmt.yield_expression == null) {
-                       int state = emit_context.next_coroutine_state++;
+               int state = emit_context.next_coroutine_state++;
 
-                       ccode.add_assignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), "_state_"), new CCodeConstant (state.to_string ()));
-                       ccode.add_return (new CCodeConstant ("FALSE"));
-                       ccode.add_label ("_state_%d".printf (state));
-                       ccode.add_statement (new CCodeEmptyStatement ());
-
-                       return;
-               }
-
-               if (stmt.yield_expression.error) {
-                       stmt.error = true;
-                       return;
-               }
-
-               ccode.add_expression (get_cvalue (stmt.yield_expression));
-
-               if (stmt.tree_can_fail && stmt.yield_expression.tree_can_fail) {
-                       // simple case, no node breakdown necessary
-
-                       add_simple_check (stmt.yield_expression);
-               }
-
-               /* free temporary objects */
-
-               foreach (var value in temp_ref_values) {
-                       ccode.add_expression (destroy_value (value));
-               }
-
-               temp_ref_values.clear ();
+               ccode.add_assignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), "_state_"), new CCodeConstant (state.to_string ()));
+               ccode.add_return (new CCodeConstant ("FALSE"));
+               ccode.add_label ("_state_%d".printf (state));
+               ccode.add_statement (new CCodeEmptyStatement ());
        }
 
        public override void return_with_exception (CCodeExpression error_expr)
index da1b3316946578e9aa14dafe7ae30b0050925daf..fc161d0993fbeed2665c85ff8566aad4facfa387 100644 (file)
@@ -482,6 +482,7 @@ TESTS = \
        parser/unsupported-property-async.test \
        parser/unsupported-property-throws.test \
        parser/yield-method.test \
+       parser/yield-return.test \
        parser/yield-return.vala \
        parser/bug728574.vala \
        parser/bug749576.vala \
diff --git a/tests/parser/yield-return.test b/tests/parser/yield-return.test
new file mode 100644 (file)
index 0000000..08256e0
--- /dev/null
@@ -0,0 +1,13 @@
+Invalid Code
+
+class Foo {
+       public async Foo () {
+       }
+}
+
+async Foo bar () {
+       yield return new Foo ();
+}
+
+void main () {
+}
index 620e45896aa998fd2fb84a990df94f5433c9b922..a71a6a38299443b83618cd3fab5975fe27b09deb 100644 (file)
@@ -1103,10 +1103,6 @@ public class Vala.CodeWriter : CodeVisitor {
        public override void visit_yield_statement (YieldStatement y) {
                write_indent ();
                write_string ("yield");
-               if (y.yield_expression != null) {
-                       write_string (" ");
-                       y.yield_expression.accept (this);
-               }
                write_string (";");
                write_newline ();
        }
index 24c63849251cbd3b47de77a06ce5c77b48aed026..0220deafa32e56d02c0767cf5e7a4b0dc2b28b82 100644 (file)
@@ -2260,16 +2260,12 @@ public class Vala.Genie.Parser : CodeVisitor {
        Statement parse_yield_statement () throws ParseError {
                var begin = get_location ();
                expect (TokenType.YIELD);
-               if (current () != TokenType.SEMICOLON && current () != TokenType.EOL && current () != TokenType.RETURN) {
+               if (current () != TokenType.SEMICOLON && current () != TokenType.EOL) {
                        prev ();
                        return parse_expression_statement ();
                }
-               Expression expr = null;
-               if (accept (TokenType.RETURN)) {
-                       expr = parse_expression ();
-               }
                expect_terminator ();
-               return new YieldStatement (expr, get_src (begin));
+               return new YieldStatement (get_src (begin));
        }
 
        Statement parse_throw_statement () throws ParseError {
index c4d8a5313b4af87063d81c814bc950c0f1b33f78..05b7139bf51526e97d39417b642969f32c153339 100644 (file)
@@ -2070,17 +2070,17 @@ public class Vala.Parser : CodeVisitor {
        Statement parse_yield_statement () throws ParseError {
                var begin = get_location ();
                expect (TokenType.YIELD);
-               if (current () != TokenType.SEMICOLON && current () != TokenType.RETURN) {
+               var token = current ();
+               if (token != TokenType.SEMICOLON) {
                        // yield expression
                        prev ();
+                       if (token == TokenType.RETURN) {
+                               throw new ParseError.SYNTAX ("expected `return yield'");
+                       }
                        return parse_expression_statement ();
                }
-               Expression expr = null;
-               if (accept (TokenType.RETURN)) {
-                       expr = parse_expression ();
-               }
                expect (TokenType.SEMICOLON);
-               return new YieldStatement (expr, get_src (begin));
+               return new YieldStatement (get_src (begin));
        }
 
        Statement parse_throw_statement () throws ParseError {
index 5b5a6f30717645f211a01b9447f146fa6df74637..795de27610417c7cc3815de08e6e1c8c4673c76d 100644 (file)
  * Represents a yield statement in the source code.
  */
 public class Vala.YieldStatement : CodeNode, Statement {
-       /**
-        * The expression to yield or the method call to yield to.
-        */
-       public Expression? yield_expression {
-               get { return _yield_expression; }
-               set {
-                       _yield_expression = value;
-                       if (_yield_expression != null) {
-                               _yield_expression.parent_node = this;
-                       }
-               }
-       }
-
-       private Expression _yield_expression;
-
        /**
         * Creates a new yield statement.
         *
@@ -46,45 +31,11 @@ public class Vala.YieldStatement : CodeNode, Statement {
         * @param source_reference reference to source code
         * @return                 newly created yield statement
         */
-       public YieldStatement (Expression? yield_expression, SourceReference? source_reference = null) {
-               this.yield_expression = yield_expression;
+       public YieldStatement (SourceReference? source_reference = null) {
                this.source_reference = source_reference;
        }
 
-       public override void accept (CodeVisitor visitor) {
-               visitor.visit_yield_statement (this);
-       }
-
-       public override void accept_children (CodeVisitor visitor) {
-               if (yield_expression != null) {
-                       yield_expression.accept (visitor);
-
-                       visitor.visit_end_full_expression (yield_expression);
-               }
-       }
-
-       public override void replace_expression (Expression old_node, Expression new_node) {
-               if (yield_expression == old_node) {
-                       yield_expression = new_node;
-               }
-       }
-
-       public override bool check (CodeContext context) {
-               if (yield_expression != null) {
-                       yield_expression.check (context);
-                       error = yield_expression.error;
-               }
-
-               return !error;
-       }
-
        public override void emit (CodeGenerator codegen) {
-               if (yield_expression != null) {
-                       yield_expression.emit (codegen);
-
-                       codegen.visit_end_full_expression (yield_expression);
-               }
-
                codegen.visit_yield_statement (this);
        }
 }