From 9553c5a4e6faf2f2ac19dc7e0200586bde825f7f Mon Sep 17 00:00:00 2001 From: crthpl <56052645+crthpl@users.noreply.github.com> Date: Fri, 4 Jun 2021 13:18:11 -0700 Subject: [PATCH] parser: fix multiple output modifiers in asm (#10347) --- vlib/v/ast/ast.v | 2 +- vlib/v/checker/checker.v | 4 +++- vlib/v/parser/parser.v | 2 +- vlib/v/parser/pratt.v | 3 +++ vlib/v/tests/assembly/asm_test.amd64.v | 13 +++++++++++++ vlib/v/tests/assembly/asm_test.i386.v | 13 +++++++++++++ 6 files changed, 34 insertions(+), 3 deletions(-) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index e58c69e144..a9cb23136c 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -1577,7 +1577,7 @@ pub fn (expr Expr) is_expr() bool { pub fn (expr Expr) is_lit() bool { return match expr { - BoolLiteral, StringLiteral, IntegerLiteral { true } + BoolLiteral, CharLiteral, StringLiteral, IntegerLiteral { true } else { false } } } diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 8c5e1686e0..07d594c307 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1558,7 +1558,9 @@ fn (mut c Checker) fail_if_immutable(expr ast.Expr) (string, token.Position) { return '', pos } else { - c.error('unexpected expression `$expr.type_name()`', expr.position()) + if !expr.is_lit() { + c.error('unexpected expression `$expr.type_name()`', expr.position()) + } } } if explicit_lock_needed { diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 4f9320729c..b2aa87689c 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -1411,7 +1411,7 @@ fn (mut p Parser) asm_ios(output bool) []ast.AsmIO { if mut expr is ast.ParExpr { expr = expr.expr } else { - p.error('asm in/output must be incolsed in brackets $expr.type_name()') + p.error('asm in/output must be incolsed in brackets') } mut alias := '' if p.tok.kind == .key_as { diff --git a/vlib/v/parser/pratt.v b/vlib/v/parser/pratt.v index 1221b287bc..46105dbc11 100644 --- a/vlib/v/parser/pratt.v +++ b/vlib/v/parser/pratt.v @@ -352,6 +352,9 @@ pub fn (mut p Parser) check_expr(precedence int) ?ast.Expr { pub fn (mut p Parser) expr_with_left(left ast.Expr, precedence int, is_stmt_ident bool) ast.Expr { mut node := left + if p.inside_asm && p.prev_tok.position().line_nr < p.tok.position().line_nr { + return node + } // Infix for precedence < p.tok.precedence() { if p.tok.kind == .dot { diff --git a/vlib/v/tests/assembly/asm_test.amd64.v b/vlib/v/tests/assembly/asm_test.amd64.v index ade60e0161..8e515ac5c0 100644 --- a/vlib/v/tests/assembly/asm_test.amd64.v +++ b/vlib/v/tests/assembly/asm_test.amd64.v @@ -169,4 +169,17 @@ fn test_flag_output() { ; r (zero) } assert out + + mut maybe_four := 4 + mut four := 4 + asm amd64 { + subl four, maybe_four + testl four, maybe_four + movl maybe_four, 9 + ; +m (maybe_four) + +r (four) + =@ccz (out) + } + assert out + assert maybe_four == 9 } diff --git a/vlib/v/tests/assembly/asm_test.i386.v b/vlib/v/tests/assembly/asm_test.i386.v index 364b53e937..1e0078066c 100644 --- a/vlib/v/tests/assembly/asm_test.i386.v +++ b/vlib/v/tests/assembly/asm_test.i386.v @@ -151,4 +151,17 @@ fn test_flag_output() { ; r (zero) } assert out + + mut maybe_four := 4 + mut four := 4 + asm amd64 { + subl four, maybe_four + testl four, maybe_four + movl maybe_four, 9 + ; +m (maybe_four) + +r (four) + =@ccz (out) + } + assert out + assert maybe_four == 9 }