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

cgen: add __addr (bootstraps #14818) (#15585)

This commit is contained in:
crthpl 2022-08-30 00:28:47 -07:00 committed by GitHub
parent 2221dd7058
commit a9b54e9b98
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 80 additions and 2 deletions

View File

@ -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{}

View 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 | }

View File

@ -0,0 +1,5 @@
fn main() {
a := 4
b := __addr(a)
assert *b == 4
}

View File

@ -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)

View File

@ -0,0 +1 @@
int* b = &a;

23
vlib/v/gen/c/testdata/addr.vv vendored Normal file
View 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
View 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
}