mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
parent
2221dd7058
commit
a9b54e9b98
@ -571,6 +571,18 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool)
|
||||
ret_type := typ.typ.set_flag(.optional)
|
||||
node.return_type = ret_type
|
||||
return ret_type
|
||||
} else if fn_name == '__addr' {
|
||||
if !c.inside_unsafe {
|
||||
c.error('`__addr` must be called from an unsafe block', node.pos)
|
||||
}
|
||||
if node.args.len != 1 {
|
||||
c.error('`__addr` requires 1 argument', node.pos)
|
||||
return ast.void_type
|
||||
}
|
||||
typ := c.expr(node.args[0].expr)
|
||||
node.args[0].typ = typ
|
||||
node.return_type = typ.ref()
|
||||
return node.return_type
|
||||
}
|
||||
// look for function in format `mod.fn` or `fn` (builtin)
|
||||
mut func := ast.Fn{}
|
||||
|
7
vlib/v/checker/tests/addr.out
Normal file
7
vlib/v/checker/tests/addr.out
Normal file
@ -0,0 +1,7 @@
|
||||
vlib/v/checker/tests/addr.vv:3:7: error: `__addr` must be called from an unsafe block
|
||||
1 | fn main() {
|
||||
2 | a := 4
|
||||
3 | b := __addr(a)
|
||||
| ~~~~~~~~~
|
||||
4 | assert *b == 4
|
||||
5 | }
|
5
vlib/v/checker/tests/addr.vv
Normal file
5
vlib/v/checker/tests/addr.vv
Normal file
@ -0,0 +1,5 @@
|
||||
fn main() {
|
||||
a := 4
|
||||
b := __addr(a)
|
||||
assert *b == 4
|
||||
}
|
@ -1221,6 +1221,9 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
|
||||
name = ''
|
||||
json_obj = tmp2
|
||||
}
|
||||
if name == '__addr' {
|
||||
name = '&'
|
||||
}
|
||||
if node.language == .c {
|
||||
// Skip "C."
|
||||
name = util.no_dots(name[2..])
|
||||
@ -1376,7 +1379,9 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
|
||||
g.write(')')
|
||||
}
|
||||
mut tmp_cnt_save := -1
|
||||
g.write('(')
|
||||
if name != '&' {
|
||||
g.write('(')
|
||||
}
|
||||
if is_json_fn {
|
||||
g.write(json_obj)
|
||||
} else {
|
||||
@ -1395,7 +1400,9 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
|
||||
g.call_args(node)
|
||||
}
|
||||
}
|
||||
g.write(')')
|
||||
if name != '&' {
|
||||
g.write(')')
|
||||
}
|
||||
if tmp_cnt_save >= 0 {
|
||||
g.writeln(';')
|
||||
g.keep_alive_call_postgen(node, tmp_cnt_save)
|
||||
|
1
vlib/v/gen/c/testdata/addr.c.must_have
vendored
Normal file
1
vlib/v/gen/c/testdata/addr.c.must_have
vendored
Normal file
@ -0,0 +1 @@
|
||||
int* b = &a;
|
23
vlib/v/gen/c/testdata/addr.vv
vendored
Normal file
23
vlib/v/gen/c/testdata/addr.vv
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
struct AA {
|
||||
mut:
|
||||
a int
|
||||
}
|
||||
|
||||
fn test_addr() {
|
||||
mut a := 4
|
||||
b := unsafe { __addr(a) }
|
||||
a = 3
|
||||
assert *b == 3
|
||||
|
||||
mut c := [3, 4, 5]
|
||||
d := unsafe { __addr(c[1]) }
|
||||
c[1] = 3
|
||||
assert *d == 3
|
||||
|
||||
mut e := AA{
|
||||
a: 4
|
||||
}
|
||||
f := unsafe { __addr(e.a) }
|
||||
e.a = 3
|
||||
assert *f == 3
|
||||
}
|
23
vlib/v/tests/addr_test.v
Normal file
23
vlib/v/tests/addr_test.v
Normal file
@ -0,0 +1,23 @@
|
||||
struct AA {
|
||||
mut:
|
||||
a int
|
||||
}
|
||||
|
||||
fn test_addr() {
|
||||
mut a := 4
|
||||
b := unsafe { __addr(a) }
|
||||
a = 3
|
||||
assert *b == 3
|
||||
|
||||
mut c := [3, 4, 5]
|
||||
d := unsafe { __addr(c[1]) }
|
||||
c[1] = 3
|
||||
assert *d == 3
|
||||
|
||||
mut e := AA{
|
||||
a: 4
|
||||
}
|
||||
f := unsafe { __addr(e.a) }
|
||||
e.a = 3
|
||||
assert *f == 3
|
||||
}
|
Loading…
Reference in New Issue
Block a user