patch 9.0.2169: Vim9: builtin funcs may accept a non-value
Problem: Vim9: builtin funcs may accept a non-value
Solution: Restrict builtin functions that accept `type`
This PR finishes off detection and prevention of using a type as a
value. It takes care of builtin functions. However there are some
builtin functions, that need to be able to handle types as well as
non-args: instanceof(), type(), typename(), string().
A "bit", FE_X, is added to funcentry_T; when set, the builtin function
can handle a type (class or type-alias) in addition to a value.
Noteworthy change: Discovered that in compile_call() the builtin add()
is compiled inline instead of calling the builtin. Had to add a check
there.
closes: #13688
Signed-off-by: Ernie Rael <errael@raelity.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim
index 1267936..9af0d07 100644
--- a/src/testdir/test_vim9_builtin.vim
+++ b/src/testdir/test_vim9_builtin.vim
@@ -5048,4 +5048,153 @@
v9.CheckDefExecAndScriptFailure(['writefile(["a"], "")'], 'E482: Can''t create file <empty>')
enddef
+def Test_passing_type_to_builtin()
+ # type, typename, string, instanceof are allowed type argument
+ var lines =<< trim END
+ vim9script
+ class C
+ endclass
+ type T = number
+ type U = C
+ var x: any
+ x = type(C)
+ x = type(T)
+ x = typename(C)
+ x = typename(T)
+ x = string(C)
+ x = string(T)
+ x = instanceof(C.new(), U, C)
+ END
+ v9.CheckScriptSuccess(lines)
+
+ # check argument to add at script level
+ # Note: add() is special cased in compile_call in vim9expr
+ lines =<< trim END
+ vim9script
+ class C
+ endclass
+ add([], C)
+ END
+ v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
+
+ # check argument to add in :def
+ lines =<< trim END
+ vim9script
+ class C
+ endclass
+ def F()
+ add([], C)
+ enddef
+ F()
+ END
+ v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
+
+ # check member call argument to add at script level
+ lines =<< trim END
+ vim9script
+ class C
+ endclass
+ []->add(C)
+ END
+ v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
+
+ # check member call argument to add in :def
+ lines =<< trim END
+ vim9script
+ class C
+ endclass
+ def F()
+ []->add(C)
+ enddef
+ F()
+ END
+ v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
+
+ # Try "empty()" builtin
+ # check argument to empty at script level
+ lines =<< trim END
+ vim9script
+ class C
+ endclass
+ empty(C)
+ END
+ v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
+
+ # check argument to empty in :def
+ lines =<< trim END
+ vim9script
+ class C
+ endclass
+ def F()
+ empty(C)
+ enddef
+ F()
+ END
+ v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
+
+ # check member call argument to empty at script level
+ lines =<< trim END
+ vim9script
+ class C
+ endclass
+ C->empty()
+ END
+ v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
+
+ # check member call argument to empty in :def
+ lines =<< trim END
+ vim9script
+ class C
+ endclass
+ def F()
+ C->empty()
+ enddef
+ F()
+ END
+ v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
+
+ # Try "abs()" builtin
+ # check argument to abs at script level
+ lines =<< trim END
+ vim9script
+ class C
+ endclass
+ abs(C)
+ END
+ v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
+
+ # check argument to abs in :def
+ lines =<< trim END
+ vim9script
+ class C
+ endclass
+ def F()
+ abs(C)
+ enddef
+ F()
+ END
+ v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
+
+ # check member call argument to abs at script level
+ lines =<< trim END
+ vim9script
+ class C
+ endclass
+ C->abs()
+ END
+ v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
+
+ # check member call argument to abs in :def
+ lines =<< trim END
+ vim9script
+ class C
+ endclass
+ def F()
+ C->abs()
+ enddef
+ F()
+ END
+ v9.CheckScriptFailure(lines, 'E1405: Class "C" cannot be used as a value')
+enddef
+
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker