cgen: check for null when calling function pointers in structs
parent
e2822356c2
commit
7f26e6d457
|
@ -802,6 +802,25 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
|
|||
}
|
||||
|
||||
fn (mut g Gen) fn_call(node ast.CallExpr) {
|
||||
mut nullcheck := false
|
||||
if node.is_field && !node.return_type.has_flag(.optional) {
|
||||
nullcheck = true
|
||||
g.write('/* null check */ (')
|
||||
// fn_name := c_name(node.name)
|
||||
if node.left_type != 0 {
|
||||
left_sym := g.table.get_type_symbol(node.left_type)
|
||||
if left_sym.kind == .interface_ {
|
||||
g.write('(*')
|
||||
}
|
||||
g.expr(node.left)
|
||||
if node.left_type.is_ptr() {
|
||||
g.write('->')
|
||||
} else {
|
||||
g.write('.')
|
||||
}
|
||||
}
|
||||
g.write('$node.name)? ')
|
||||
}
|
||||
// call struct field with fn type
|
||||
// TODO: test node.left instead
|
||||
// left & left_type will be `x` and `x type` in `x.fieldfn()`
|
||||
|
@ -969,6 +988,13 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
|
|||
}
|
||||
}
|
||||
g.write(')')
|
||||
if nullcheck && node.left_type != 0 {
|
||||
g.write(': 0')
|
||||
left_sym := g.table.get_type_symbol(node.left_type)
|
||||
if left_sym.kind == .interface_ {
|
||||
g.write(')')
|
||||
}
|
||||
}
|
||||
if tmp_cnt_save >= 0 {
|
||||
g.writeln(';')
|
||||
g.keep_alive_call_postgen(node, tmp_cnt_save)
|
||||
|
|
|
@ -27,3 +27,28 @@ fn test_struct_fn_field_can_be_used_directly() {
|
|||
eprintln(res)
|
||||
assert res == [byte(0x88), 0x01, 0x02, 0x02, 0x99]
|
||||
}
|
||||
|
||||
// null check test
|
||||
|
||||
struct NullCall {
|
||||
mut:
|
||||
nullcall fn ()
|
||||
}
|
||||
|
||||
fn hello() {
|
||||
println('hello world')
|
||||
}
|
||||
|
||||
fn null_function() fn () {
|
||||
return NullCall{}.nullcall
|
||||
}
|
||||
|
||||
fn test_struct_fn_field_can_be_null() {
|
||||
mut a := NullCall{hello}
|
||||
a.nullcall()
|
||||
a.nullcall = null_function()
|
||||
a.nullcall() // not segfault
|
||||
unsafe {
|
||||
a.nullcall() // do segfault
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue