From 8a497080b3d3c7ea291e50a13856300f510006f9 Mon Sep 17 00:00:00 2001 From: crthpl <56052645+crthpl@users.noreply.github.com> Date: Mon, 7 Jun 2021 00:53:33 -0700 Subject: [PATCH] cgen: fix assembly in generic fns (#10370) --- vlib/v/checker/checker.v | 2 +- vlib/v/gen/c/cgen.v | 3 ++- vlib/v/tests/assembly/asm_test.amd64.v | 22 ++++++++++++++++++++++ vlib/v/tests/assembly/asm_test.i386.v | 23 ++++++++++++++++++++++- 4 files changed, 47 insertions(+), 3 deletions(-) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 551c2c6bf8..347641b55b 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -4957,7 +4957,7 @@ pub fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type { } } else if to_type_sym.kind == .interface_ { c.type_implements(node.expr_type, node.typ, node.pos) - } else if node.typ == ast.bool_type { + } else if node.typ == ast.bool_type && !c.inside_unsafe { c.error('cannot cast to bool - use e.g. `some_int != 0` instead', node.pos) } else if node.expr_type == ast.none_type && !node.typ.has_flag(.optional) { type_name := c.table.type_to_str(node.typ) diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index ca08a14d98..760b38a9c9 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -1937,7 +1937,8 @@ fn (mut g Gen) gen_asm_stmt(stmt ast.AsmStmt) { } g.writeln(' (') g.indent++ - for mut template in stmt.templates { + for template_tmp in stmt.templates { + mut template := template_tmp g.write('"') if template.is_directive { g.write('.') diff --git a/vlib/v/tests/assembly/asm_test.amd64.v b/vlib/v/tests/assembly/asm_test.amd64.v index 8e515ac5c0..1f8c04b542 100644 --- a/vlib/v/tests/assembly/asm_test.amd64.v +++ b/vlib/v/tests/assembly/asm_test.amd64.v @@ -183,3 +183,25 @@ fn test_flag_output() { assert out assert maybe_four == 9 } + +fn test_asm_generic() { + u := u64(49) + b := unsafe { bool(123) } + assert generic_asm(u) == 14 + assert u == 63 + assert u64(generic_asm(b)) == 14 + assert u64(b) == 137 +} + +fn generic_asm(var &T) T { + mut ret := T(14) + unsafe { + asm volatile amd64 { + add var, ret + ; +m (var[0]) as var + +r (ret) + ; ; memory + } + } + return ret +} diff --git a/vlib/v/tests/assembly/asm_test.i386.v b/vlib/v/tests/assembly/asm_test.i386.v index 1e0078066c..d285407253 100644 --- a/vlib/v/tests/assembly/asm_test.i386.v +++ b/vlib/v/tests/assembly/asm_test.i386.v @@ -1,5 +1,4 @@ import v.tests.assembly.util -// rename this file to asm_test.amd64.v (and make more for other architectures) once pure v code is enforced fn test_inline_asm() { a, mut b := 10, 0 @@ -165,3 +164,25 @@ fn test_flag_output() { assert out assert maybe_four == 9 } + +fn test_asm_generic() { + u := u64(49) + b := unsafe { bool(123) } + assert generic_asm(u) == 14 + assert u == 63 + assert u64(generic_asm(b)) == 14 + assert u64(b) == 137 +} + +fn generic_asm(var &T) T { + mut ret := T(14) + unsafe { + asm volatile amd64 { + add var, ret + ; +m (var[0]) as var + +r (ret) + ; ; memory + } + } + return ret +}