1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

compiler: allow function expecting a void* to receive a byteptr

This commit is contained in:
bogen85 2019-11-28 00:44:43 -06:00 committed by Alexander Medvednikov
parent e63300e286
commit 9374168b26
2 changed files with 38 additions and 18 deletions

19
vlib/builtin/isnil_test.v Normal file
View File

@ -0,0 +1,19 @@
fn test_isnil_byteptr(){
pb := byteptr(0)
assert isnil( pb )
}
fn test_isnil_voidptr(){
pv := voidptr(0)
assert isnil( pv )
}
fn test_isnil_charptr(){
pc := &char(0)
assert isnil( pc )
}
fn test_isnil_intptr(){
pi := &int(0)
assert isnil( pi )
}

View File

@ -187,7 +187,7 @@ fn (p mut Parser) clear_vars() {
} }
p.local_vars = [] p.local_vars = []
} }
} }
// Function signatures are added to the top of the .c file in the first run. // Function signatures are added to the top of the .c file in the first run.
@ -225,7 +225,7 @@ fn (p mut Parser) fn_decl() {
//p.gen('/* returns $p.returns */') //p.gen('/* returns $p.returns */')
p.next() p.next()
p.fspace() p.fspace()
// Method receiver // Method receiver
mut receiver_typ := '' mut receiver_typ := ''
if p.tok == .lpar { if p.tok == .lpar {
@ -245,7 +245,7 @@ fn (p mut Parser) fn_decl() {
t := p.table.find_type(receiver_typ) t := p.table.find_type(receiver_typ)
if (t.name == '' || t.is_placeholder) && !p.first_pass() { if (t.name == '' || t.is_placeholder) && !p.first_pass() {
p.error('unknown receiver type `$receiver_typ`') p.error('unknown receiver type `$receiver_typ`')
} }
if t.cat == .interface_ { if t.cat == .interface_ {
p.error('invalid receiver type `$receiver_typ` (`$receiver_typ` is an interface)') p.error('invalid receiver type `$receiver_typ` (`$receiver_typ` is an interface)')
} }
@ -687,10 +687,10 @@ fn (p mut Parser) async_fn_call(f Fn, method_ph int, receiver_var, receiver_type
fn (p mut Parser) fn_call(f mut Fn, method_ph int, receiver_var, receiver_type string) { fn (p mut Parser) fn_call(f mut Fn, method_ph int, receiver_var, receiver_type string) {
if f.is_unsafe && !p.builtin_mod && !p.inside_unsafe { if f.is_unsafe && !p.builtin_mod && !p.inside_unsafe {
p.warn('you are calling an unsafe function outside of an unsafe block') p.warn('you are calling an unsafe function outside of an unsafe block')
} }
if f.is_deprecated { if f.is_deprecated {
p.warn('$f.name is deprecated') p.warn('$f.name is deprecated')
} }
if !f.is_public && !f.is_c && !p.pref.is_test && !f.is_interface && f.mod != p.mod { if !f.is_public && !f.is_c && !p.pref.is_test && !f.is_interface && f.mod != p.mod {
if f.name == 'contains' { if f.name == 'contains' {
println('use `value in numbers` instead of `numbers.contains(value)`') println('use `value in numbers` instead of `numbers.contains(value)`')
@ -700,7 +700,7 @@ fn (p mut Parser) fn_call(f mut Fn, method_ph int, receiver_var, receiver_type s
is_comptime_define := f.comptime_define != '' && f.comptime_define != p.pref.comptime_define is_comptime_define := f.comptime_define != '' && f.comptime_define != p.pref.comptime_define
if is_comptime_define { if is_comptime_define {
p.cgen.nogen = true p.cgen.nogen = true
} }
p.calling_c = f.is_c p.calling_c = f.is_c
if f.is_c && !p.builtin_mod { if f.is_c && !p.builtin_mod {
if f.name == 'free' { if f.name == 'free' {
@ -747,8 +747,8 @@ fn (p mut Parser) fn_call(f mut Fn, method_ph int, receiver_var, receiver_type s
for i, method in t.methods { for i, method in t.methods {
if method.name == f.name { if method.name == f.name {
idx = i idx = i
} }
} }
p.cgen.resetln('') p.cgen.resetln('')
var := p.expr_var.name var := p.expr_var.name
iname := f.args[0].typ // Speaker iname := f.args[0].typ // Speaker
@ -777,7 +777,7 @@ fn (p mut Parser) fn_call(f mut Fn, method_ph int, receiver_var, receiver_type s
// Normal function call // Normal function call
p.gen('$cgen_name (') p.gen('$cgen_name (')
} }
// `foo<Bar>()` // `foo<Bar>()`
// if f is generic, the name is changed to a suitable instance in dispatch_generic_fn_instance() // if f is generic, the name is changed to a suitable instance in dispatch_generic_fn_instance()
// we then replace `cgen_name` with the instance's name // we then replace `cgen_name` with the instance's name
@ -1003,12 +1003,12 @@ fn (p mut Parser) fn_call_args(f mut Fn) {
if clone { if clone {
p.gen('/*YY f=$f.name arg=$arg.name is_moved=$arg.is_moved*/string_clone(') p.gen('/*YY f=$f.name arg=$arg.name is_moved=$arg.is_moved*/string_clone(')
} }
// x64 println gen // x64 println gen
if p.pref.x64 && i == 0 && f.name == 'println' && p.tok == .str && p.peek() == .rpar { if p.pref.x64 && i == 0 && f.name == 'println' && p.tok == .str && p.peek() == .rpar {
p.x64.gen_print(p.lit) p.x64.gen_print(p.lit)
} }
mut typ := p.bool_expression() mut typ := p.bool_expression()
// Register an interface type usage: // Register an interface type usage:
// fn run(r Animal) { ... } // fn run(r Animal) { ... }
@ -1028,8 +1028,8 @@ fn (p mut Parser) fn_call_args(f mut Fn) {
if clone { if clone {
p.gen(')') p.gen(')')
} }
// Optimize `println`: replace it with `printf` to avoid extra allocations and // Optimize `println`: replace it with `printf` to avoid extra allocations and
// function calls. // function calls.
// `println(777)` => `printf("%d\n", 777)` // `println(777)` => `printf("%d\n", 777)`
@ -1156,11 +1156,12 @@ fn (p mut Parser) fn_call_args(f mut Fn) {
} }
} $else { } $else {
p.cgen.set_placeholder(ph, '& /*114*/') p.cgen.set_placeholder(ph, '& /*114*/')
} }
} }
// println('\ne:"$expected" got:"$got"') // println('\ne:"$expected" got:"$got"')
else if ! (expected == 'void*' && got == 'int') && else if ! (expected == 'void*' && got == 'int') &&
! (expected == 'void*' && got == 'byteptr') &&
! (expected == 'byte*' && got.contains(']byte')) && ! (expected == 'byte*' && got.contains(']byte')) &&
! (expected == 'byte*' && got == 'string') && ! (expected == 'byte*' && got == 'string') &&
//! (expected == 'void*' && got == 'array_int') { //! (expected == 'void*' && got == 'array_int') {
@ -1318,7 +1319,7 @@ fn (p mut Parser) register_vargs_stuct(typ string, len int) string {
} }
p.table.add_field(vargs_struct, 'len', 'int', false, '', .public) p.table.add_field(vargs_struct, 'len', 'int', false, '', .public)
p.table.add_field(vargs_struct, 'args[$varg_len]', typ, false, '', .public) p.table.add_field(vargs_struct, 'args[$varg_len]', typ, false, '', .public)
return vargs_struct return vargs_struct
} }