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

pull/2916/head
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

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 = []
}
}
// 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.next()
p.fspace()
// Method receiver
mut receiver_typ := ''
if p.tok == .lpar {
@ -245,7 +245,7 @@ fn (p mut Parser) fn_decl() {
t := p.table.find_type(receiver_typ)
if (t.name == '' || t.is_placeholder) && !p.first_pass() {
p.error('unknown receiver type `$receiver_typ`')
}
}
if t.cat == .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) {
if f.is_unsafe && !p.builtin_mod && !p.inside_unsafe {
p.warn('you are calling an unsafe function outside of an unsafe block')
}
}
if f.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.name == 'contains' {
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
if is_comptime_define {
p.cgen.nogen = true
}
}
p.calling_c = f.is_c
if f.is_c && !p.builtin_mod {
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 {
if method.name == f.name {
idx = i
}
}
}
}
p.cgen.resetln('')
var := p.expr_var.name
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
p.gen('$cgen_name (')
}
// `foo<Bar>()`
// 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
@ -1003,12 +1003,12 @@ fn (p mut Parser) fn_call_args(f mut Fn) {
if clone {
p.gen('/*YY f=$f.name arg=$arg.name is_moved=$arg.is_moved*/string_clone(')
}
// x64 println gen
if p.pref.x64 && i == 0 && f.name == 'println' && p.tok == .str && p.peek() == .rpar {
p.x64.gen_print(p.lit)
}
}
mut typ := p.bool_expression()
// Register an interface type usage:
// fn run(r Animal) { ... }
@ -1028,8 +1028,8 @@ fn (p mut Parser) fn_call_args(f mut Fn) {
if clone {
p.gen(')')
}
// Optimize `println`: replace it with `printf` to avoid extra allocations and
// function calls.
// `println(777)` => `printf("%d\n", 777)`
@ -1156,11 +1156,12 @@ fn (p mut Parser) fn_call_args(f mut Fn) {
}
} $else {
p.cgen.set_placeholder(ph, '& /*114*/')
}
}
}
}
// println('\ne:"$expected" got:"$got"')
else if ! (expected == 'void*' && got == 'int') &&
! (expected == 'void*' && got == 'byteptr') &&
! (expected == 'byte*' && got.contains(']byte')) &&
! (expected == 'byte*' && got == 'string') &&
//! (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, 'args[$varg_len]', typ, false, '', .public)
return vargs_struct
}