From 05fc7d3a725e7a5c3e58e49f5fc316f7f46389e0 Mon Sep 17 00:00:00 2001 From: Swastik Baranwal Date: Tue, 11 Oct 2022 18:16:35 +0530 Subject: [PATCH] checker: disallow function cast outside unsafe (#16030) --- vlib/v/checker/checker.v | 6 ++++++ vlib/v/checker/tests/function_cast_outside_unsafe_err.out | 6 ++++++ vlib/v/checker/tests/function_cast_outside_unsafe_err.vv | 7 +++++++ 3 files changed, 19 insertions(+) create mode 100644 vlib/v/checker/tests/function_cast_outside_unsafe_err.out create mode 100644 vlib/v/checker/tests/function_cast_outside_unsafe_err.vv diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index d8eafc318f..869986c84b 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -2546,6 +2546,12 @@ pub fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type { c.error('casting numbers to enums, should be done inside `unsafe{}` blocks', node.pos) } + if final_to_sym.kind == .function && final_from_sym.kind == .function && !(c.inside_unsafe + || c.file.is_translated) && !c.check_matching_function_symbols(final_from_sym, final_to_sym) { + c.error('casting a function value from one function signature, to another function signature, should be done inside `unsafe{}` blocks', + node.pos) + } + if to_type == ast.string_type { if from_type in [ast.u8_type, ast.bool_type] { snexpr := node.expr.str() diff --git a/vlib/v/checker/tests/function_cast_outside_unsafe_err.out b/vlib/v/checker/tests/function_cast_outside_unsafe_err.out new file mode 100644 index 0000000000..5ab731a587 --- /dev/null +++ b/vlib/v/checker/tests/function_cast_outside_unsafe_err.out @@ -0,0 +1,6 @@ +vlib/v/checker/tests/function_cast_outside_unsafe_err.vv:6:10: error: casting a function value from one function signature, to another function signature, should be done inside `unsafe{}` blocks + 4 | fn main(){ + 5 | f := fn(){} + 6 | println(FnB(f)) // not FnA() + | ~~~~~~ + 7 | } diff --git a/vlib/v/checker/tests/function_cast_outside_unsafe_err.vv b/vlib/v/checker/tests/function_cast_outside_unsafe_err.vv new file mode 100644 index 0000000000..21d45605bb --- /dev/null +++ b/vlib/v/checker/tests/function_cast_outside_unsafe_err.vv @@ -0,0 +1,7 @@ +type FnA = fn() +type FnB = fn(int) + +fn main(){ + f := fn(){} + println(FnB(f)) // not FnA() +}