From 4cf6abd99d64f7599a5aa96f4efc1de4006082cd Mon Sep 17 00:00:00 2001 From: yuyi Date: Sun, 5 Jun 2022 13:44:35 +0800 Subject: [PATCH] checker: check using literal argument as reference parameter (#14674) --- vlib/v/checker/fn.v | 9 +++++++++ .../checker/tests/fn_ref_arg_mismatch_err.out | 13 +++++++++++++ .../v/checker/tests/fn_ref_arg_mismatch_err.vv | 18 ++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 vlib/v/checker/tests/fn_ref_arg_mismatch_err.out create mode 100644 vlib/v/checker/tests/fn_ref_arg_mismatch_err.vv diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index f4bf50b914..523990a607 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -897,6 +897,11 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) } continue } + if param.typ.is_ptr() && !param.is_mut && !call_arg.typ.is_real_pointer() + && call_arg.expr.is_literal() && func.language == .v { + c.error('literal argument cannot be passed as reference parameter `${c.table.type_to_str(param.typ)}`', + call_arg.pos) + } c.check_expected_call_arg(arg_typ, c.unwrap_generic(param.typ), node.language, call_arg) or { if param.typ.has_flag(.generic) { @@ -1433,6 +1438,10 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type { } continue } + if param.typ.is_ptr() && !arg.typ.is_real_pointer() && arg.expr.is_literal() { + c.error('literal argument cannot be passed as reference parameter `${c.table.type_to_str(param.typ)}`', + arg.pos) + } c.check_expected_call_arg(got_arg_typ, exp_arg_typ, node.language, arg) or { // str method, allow type with str method if fn arg is string // Passing an int or a string array produces a c error here diff --git a/vlib/v/checker/tests/fn_ref_arg_mismatch_err.out b/vlib/v/checker/tests/fn_ref_arg_mismatch_err.out new file mode 100644 index 0000000000..3ed583c48f --- /dev/null +++ b/vlib/v/checker/tests/fn_ref_arg_mismatch_err.out @@ -0,0 +1,13 @@ +vlib/v/checker/tests/fn_ref_arg_mismatch_err.vv:15:10: error: literal argument cannot be passed as reference parameter `&T` + 13 | fn main() { + 14 | foo := Foo{} + 15 | foo.foo(12) + | ~~ + 16 | + 17 | bar(12) +vlib/v/checker/tests/fn_ref_arg_mismatch_err.vv:17:11: error: literal argument cannot be passed as reference parameter `&T` + 15 | foo.foo(12) + 16 | + 17 | bar(12) + | ~~ + 18 | } diff --git a/vlib/v/checker/tests/fn_ref_arg_mismatch_err.vv b/vlib/v/checker/tests/fn_ref_arg_mismatch_err.vv new file mode 100644 index 0000000000..e9ffeeda6b --- /dev/null +++ b/vlib/v/checker/tests/fn_ref_arg_mismatch_err.vv @@ -0,0 +1,18 @@ +module main + +struct Foo { } + +fn (f &Foo) foo(a &T) { + println(a) +} + +fn bar(a &T) { + println(a) +} + +fn main() { + foo := Foo{} + foo.foo(12) + + bar(12) +}