From 6dbc6f233ba0974468e9afa330768e01b7fdae69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20D=C3=A4schle?= Date: Thu, 12 Aug 2021 09:47:24 +0200 Subject: [PATCH] v.parser: add checks for interoperability (C. or JS.) function declarations (#11140) --- vlib/v/parser/fn.v | 15 +++++++++++++-- vlib/v/parser/tests/export_interop_func_err.out | 4 ++++ vlib/v/parser/tests/export_interop_func_err.vv | 2 ++ vlib/v/parser/tests/interop_func_body_err.out | 3 +++ vlib/v/parser/tests/interop_func_body_err.vv | 1 + 5 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 vlib/v/parser/tests/export_interop_func_err.out create mode 100644 vlib/v/parser/tests/export_interop_func_err.vv create mode 100644 vlib/v/parser/tests/interop_func_body_err.out create mode 100644 vlib/v/parser/tests/interop_func_body_err.vv diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index cd3fc35a0c..29700fec9c 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -212,9 +212,17 @@ fn (mut p Parser) fn_decl() ast.FnDecl { mut language := ast.Language.v if p.tok.kind == .name && p.tok.lit == 'C' { is_unsafe = !is_trusted - language = ast.Language.c + language = .c } else if p.tok.kind == .name && p.tok.lit == 'JS' { - language = ast.Language.js + language = .js + } + if language != .v { + for fna in p.attrs { + if fna.name == 'export' { + p.error_with_pos('interop function cannot be exported', fna.pos) + break + } + } } if is_keep_alive && language != .c { p.error_with_pos('attribute [keep_args_alive] is only supported for C functions', @@ -435,6 +443,9 @@ fn (mut p Parser) fn_decl() ast.FnDecl { mut stmts := []ast.Stmt{} body_start_pos := p.peek_tok.position() if p.tok.kind == .lcbr { + if language != .v { + p.error_with_pos('interop functions cannot have a body', p.tok.position()) + } p.inside_fn = true p.inside_unsafe_fn = is_unsafe stmts = p.parse_block_no_scope(true) diff --git a/vlib/v/parser/tests/export_interop_func_err.out b/vlib/v/parser/tests/export_interop_func_err.out new file mode 100644 index 0000000000..129e6b24c0 --- /dev/null +++ b/vlib/v/parser/tests/export_interop_func_err.out @@ -0,0 +1,4 @@ +vlib/v/parser/tests/export_interop_func_err.vv:1:1: error: interop function cannot be exported + 1 | [export: 'test'] + | ~~~~~~~~~~~~~~~~ + 2 | fn C.printf(s string) diff --git a/vlib/v/parser/tests/export_interop_func_err.vv b/vlib/v/parser/tests/export_interop_func_err.vv new file mode 100644 index 0000000000..b18925b713 --- /dev/null +++ b/vlib/v/parser/tests/export_interop_func_err.vv @@ -0,0 +1,2 @@ +[export: 'test'] +fn C.printf(s string) diff --git a/vlib/v/parser/tests/interop_func_body_err.out b/vlib/v/parser/tests/interop_func_body_err.out new file mode 100644 index 0000000000..ebdbc19742 --- /dev/null +++ b/vlib/v/parser/tests/interop_func_body_err.out @@ -0,0 +1,3 @@ +vlib/v/parser/tests/interop_func_body_err.vv:1:23: error: interop functions cannot have a body + 1 | fn C.printf(s string) {} + | ^ diff --git a/vlib/v/parser/tests/interop_func_body_err.vv b/vlib/v/parser/tests/interop_func_body_err.vv new file mode 100644 index 0000000000..157f6f7480 --- /dev/null +++ b/vlib/v/parser/tests/interop_func_body_err.vv @@ -0,0 +1 @@ +fn C.printf(s string) {}