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

checker: check taking the address of map field outside unsafe block (#15737)

This commit is contained in:
yuyi 2022-09-13 15:04:21 +08:00 committed by GitHub
parent ac6167565e
commit e51f0be6db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 1 deletions

View File

@ -561,7 +561,9 @@ pub fn (mut p Parser) root_table() ? {
if p.tok.kind == .lsbr {
// Parse `[[table]]`
p.array_of_tables(mut &p.root_map)?
unsafe {
p.array_of_tables(mut &p.root_map)?
}
p.skip_next = true // skip calling p.next() in coming iteration
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'leaving double bracket at "$p.tok.kind" "$p.tok.lit". NEXT is "$p.peek_tok.kind "$p.peek_tok.lit"')
} else if peek_tok.kind == .period {

View File

@ -3328,6 +3328,12 @@ pub fn (mut c Checker) prefix_expr(mut node ast.PrefixExpr) ast.Type {
c.warn('cannot take an address of const outside `unsafe`', node.right.pos)
}
}
if node.right is ast.SelectorExpr {
typ_sym := c.table.sym(right_type)
if typ_sym.kind == .map && !c.inside_unsafe {
c.error('cannot take the address of map values outside `unsafe`', node.pos)
}
}
if mut node.right is ast.IndexExpr {
typ_sym := c.table.sym(node.right.left_type)
mut is_mut := false

View File

@ -0,0 +1,7 @@
vlib/v/checker/tests/struct_field_map_address_err.vv:12:26: error: cannot take the address of map values outside `unsafe`
10 | mut s := &StructWithMap{}
11 | s.m['abc'] = StructWithMap{'abc', {}}
12 | pointer_to_map_value := &s.m['abc'].m['xyz'].m
| ^
13 | dump(ptr_str(pointer_to_map_value))
14 | return s, pointer_to_map_value

View File

@ -0,0 +1,27 @@
import os
struct StructWithMap {
mut:
name string
m map[string]StructWithMap
}
fn abc() (&StructWithMap, &map[string]StructWithMap) {
mut s := &StructWithMap{}
s.m['abc'] = StructWithMap{'abc', {}}
pointer_to_map_value := &s.m['abc'].m['xyz'].m
dump(ptr_str(pointer_to_map_value))
return s, pointer_to_map_value
}
fn main() {
mut s, p := abc()
n := os.args[1] or { '2' }.int()
dump(n)
for i in 0 .. n {
s.m['$i'] = StructWithMap{}
}
dump(s.m['abc'])
dump(p)
eprintln('-----------------------------------------------------')
}