From 7b9756be72760a925c54c571fd1ee5e37a965b2a Mon Sep 17 00:00:00 2001 From: yuyi Date: Thu, 24 Dec 2020 00:17:09 +0800 Subject: [PATCH] parser: check for builtin function redefinitions (fix #7499) (#7507) --- vlib/v/parser/fn.v | 13 +++++++++++-- vlib/v/parser/parser.v | 4 ++++ vlib/v/parser/tests/fn_use_builtin_err.out | 5 +++++ vlib/v/parser/tests/fn_use_builtin_err.vv | 9 +++++++++ 4 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 vlib/v/parser/tests/fn_use_builtin_err.out create mode 100644 vlib/v/parser/tests/fn_use_builtin_err.vv diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index 0b4ec7590c..3fd2ec11ba 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -229,10 +229,12 @@ fn (mut p Parser) fn_decl() ast.FnDecl { } mut name := '' if p.tok.kind == .name { + pos := p.tok.position() // TODO high order fn name = if language == .js { p.check_js_name() } else { p.check_name() } if language == .v && !p.pref.translated && util.contains_capital(name) && p.mod != 'builtin' { - p.error('function names cannot contain uppercase letters, use snake_case instead') + p.error_with_pos('function names cannot contain uppercase letters, use snake_case instead', + pos) return ast.FnDecl{ scope: 0 } @@ -240,7 +242,14 @@ fn (mut p Parser) fn_decl() ast.FnDecl { type_sym := p.table.get_type_symbol(rec_type) // interfaces are handled in the checker, methods can not be defined on them this way if is_method && (type_sym.has_method(name) && type_sym.kind != .interface_) { - p.error('duplicate method `$name`') + p.error_with_pos('duplicate method `$name`', pos) + return ast.FnDecl{ + scope: 0 + } + } + // cannot redefine buildin function + if !is_method && p.mod != 'builtin' && name in builtin_functions { + p.error_with_pos('cannot redefine builtin function `$name`', pos) return ast.FnDecl{ scope: 0 } diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 0990e43dca..b422a8c01c 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -14,6 +14,10 @@ import os import runtime import time +const ( + builtin_functions = ['print', 'println', 'eprint', 'eprintln', 'isnil', 'panic', 'exit'] +) + pub struct Parser { pref &pref.Preferences mut: diff --git a/vlib/v/parser/tests/fn_use_builtin_err.out b/vlib/v/parser/tests/fn_use_builtin_err.out new file mode 100644 index 0000000000..5e57fe2ff1 --- /dev/null +++ b/vlib/v/parser/tests/fn_use_builtin_err.out @@ -0,0 +1,5 @@ +vlib/v/parser/tests/fn_use_builtin_err.vv:1:4: error: cannot redefine builtin function `print` + 1 | fn print(strings ...string) { + | ~~~~~ + 2 | for s in strings { + 3 | println(s) diff --git a/vlib/v/parser/tests/fn_use_builtin_err.vv b/vlib/v/parser/tests/fn_use_builtin_err.vv new file mode 100644 index 0000000000..1466e4cd26 --- /dev/null +++ b/vlib/v/parser/tests/fn_use_builtin_err.vv @@ -0,0 +1,9 @@ +fn print(strings ...string) { + for s in strings { + println(s) + } +} + +fn main() { + print('text') +}