From: Rico Tzschichholz Date: Sat, 22 Sep 2018 12:44:40 +0000 (+0200) Subject: vala: Enforce "return yield ..." syntax to be expected X-Git-Tag: 0.43.1~209 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=898e45a6ff6129fc5c674af48118042dd64123ff;p=thirdparty%2Fvala.git vala: Enforce "return yield ..." syntax to be expected "yield return ..." wasn't handled correctly and resulted in broken c-code. Fixes https://gitlab.gnome.org/GNOME/vala/issues/675 --- diff --git a/codegen/valagasyncmodule.vala b/codegen/valagasyncmodule.vala index 9d63ab7ad..f234afdb4 100644 --- a/codegen/valagasyncmodule.vala +++ b/codegen/valagasyncmodule.vala @@ -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) diff --git a/tests/Makefile.am b/tests/Makefile.am index da1b33169..fc161d099 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -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 index 000000000..08256e0cf --- /dev/null +++ b/tests/parser/yield-return.test @@ -0,0 +1,13 @@ +Invalid Code + +class Foo { + public async Foo () { + } +} + +async Foo bar () { + yield return new Foo (); +} + +void main () { +} diff --git a/vala/valacodewriter.vala b/vala/valacodewriter.vala index 620e45896..a71a6a382 100644 --- a/vala/valacodewriter.vala +++ b/vala/valacodewriter.vala @@ -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 (); } diff --git a/vala/valagenieparser.vala b/vala/valagenieparser.vala index 24c638492..0220deafa 100644 --- a/vala/valagenieparser.vala +++ b/vala/valagenieparser.vala @@ -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 { diff --git a/vala/valaparser.vala b/vala/valaparser.vala index c4d8a5313..05b7139bf 100644 --- a/vala/valaparser.vala +++ b/vala/valaparser.vala @@ -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 { diff --git a/vala/valayieldstatement.vala b/vala/valayieldstatement.vala index 5b5a6f307..795de2761 100644 --- a/vala/valayieldstatement.vala +++ b/vala/valayieldstatement.vala @@ -24,21 +24,6 @@ * 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); } }