mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
parent
5f0ad64155
commit
3e3b289583
@ -164,6 +164,12 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
|
|||||||
mut right := if i < node.right.len { node.right[i] } else { node.right[0] }
|
mut right := if i < node.right.len { node.right[i] } else { node.right[0] }
|
||||||
mut right_type := node.right_types[i]
|
mut right_type := node.right_types[i]
|
||||||
if mut right is ast.Ident {
|
if mut right is ast.Ident {
|
||||||
|
// resolve shared right vairable
|
||||||
|
if right_type.has_flag(.shared_f) {
|
||||||
|
if c.fail_if_unreadable(right, right_type, 'right-hand side of assignment') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
right_sym := c.table.sym(right_type)
|
right_sym := c.table.sym(right_type)
|
||||||
if right_sym.info is ast.Struct {
|
if right_sym.info is ast.Struct {
|
||||||
if right_sym.info.generic_types.len > 0 {
|
if right_sym.info.generic_types.len > 0 {
|
||||||
|
@ -4664,7 +4664,8 @@ fn (mut c Checker) ensure_type_exists(typ ast.Type, pos token.Pos) ? {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut c Checker) fail_if_unreadable(expr ast.Expr, typ ast.Type, what string) {
|
// return true if a violation of a shared variable access rule is detected
|
||||||
|
fn (mut c Checker) fail_if_unreadable(expr ast.Expr, typ ast.Type, what string) bool {
|
||||||
mut pos := token.Pos{}
|
mut pos := token.Pos{}
|
||||||
match expr {
|
match expr {
|
||||||
ast.Ident {
|
ast.Ident {
|
||||||
@ -4673,9 +4674,10 @@ fn (mut c Checker) fail_if_unreadable(expr ast.Expr, typ ast.Type, what string)
|
|||||||
action := if what == 'argument' { 'passed' } else { 'used' }
|
action := if what == 'argument' { 'passed' } else { 'used' }
|
||||||
c.error('`${expr.name}` is `shared` and must be `rlock`ed or `lock`ed to be ${action} as non-mut ${what}',
|
c.error('`${expr.name}` is `shared` and must be `rlock`ed or `lock`ed to be ${action} as non-mut ${what}',
|
||||||
expr.pos)
|
expr.pos)
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return false
|
||||||
}
|
}
|
||||||
ast.SelectorExpr {
|
ast.SelectorExpr {
|
||||||
pos = expr.pos
|
pos = expr.pos
|
||||||
@ -4685,31 +4687,42 @@ fn (mut c Checker) fail_if_unreadable(expr ast.Expr, typ ast.Type, what string)
|
|||||||
action := if what == 'argument' { 'passed' } else { 'used' }
|
action := if what == 'argument' { 'passed' } else { 'used' }
|
||||||
c.error('`${expr_name}` is `shared` and must be `rlock`ed or `lock`ed to be ${action} as non-mut ${what}',
|
c.error('`${expr_name}` is `shared` and must be `rlock`ed or `lock`ed to be ${action} as non-mut ${what}',
|
||||||
expr.pos)
|
expr.pos)
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
return
|
return false
|
||||||
} else {
|
} else {
|
||||||
c.fail_if_unreadable(expr.expr, expr.expr_type, what)
|
if c.fail_if_unreadable(expr.expr, expr.expr_type, what) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast.CallExpr {
|
ast.CallExpr {
|
||||||
pos = expr.pos
|
pos = expr.pos
|
||||||
if expr.is_method {
|
if expr.is_method {
|
||||||
c.fail_if_unreadable(expr.left, expr.left_type, what)
|
if c.fail_if_unreadable(expr.left, expr.left_type, what) {
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
return
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
ast.LockExpr {
|
ast.LockExpr {
|
||||||
// TODO: check expressions inside the lock by appending to c.(r)locked_names
|
// TODO: check expressions inside the lock by appending to c.(r)locked_names
|
||||||
return
|
return false
|
||||||
}
|
}
|
||||||
ast.IndexExpr {
|
ast.IndexExpr {
|
||||||
pos = expr.left.pos().extend(expr.pos)
|
pos = expr.left.pos().extend(expr.pos)
|
||||||
c.fail_if_unreadable(expr.left, expr.left_type, what)
|
if c.fail_if_unreadable(expr.left, expr.left_type, what) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ast.InfixExpr {
|
ast.InfixExpr {
|
||||||
pos = expr.left.pos().extend(expr.pos)
|
pos = expr.left.pos().extend(expr.pos)
|
||||||
c.fail_if_unreadable(expr.left, expr.left_type, what)
|
if c.fail_if_unreadable(expr.left, expr.left_type, what) {
|
||||||
c.fail_if_unreadable(expr.right, expr.right_type, what)
|
return true
|
||||||
|
}
|
||||||
|
if c.fail_if_unreadable(expr.right, expr.right_type, what) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pos = expr.pos()
|
pos = expr.pos()
|
||||||
@ -4718,7 +4731,9 @@ fn (mut c Checker) fail_if_unreadable(expr ast.Expr, typ ast.Type, what string)
|
|||||||
if typ.has_flag(.shared_f) {
|
if typ.has_flag(.shared_f) {
|
||||||
c.error('you have to create a handle and `rlock` it to use a `shared` element as non-mut ${what}',
|
c.error('you have to create a handle and `rlock` it to use a `shared` element as non-mut ${what}',
|
||||||
pos)
|
pos)
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut c Checker) fail_if_stack_struct_action_outside_unsafe(mut ident ast.Ident, failed_action string) {
|
fn (mut c Checker) fail_if_stack_struct_action_outside_unsafe(mut ident ast.Ident, failed_action string) {
|
||||||
|
13
vlib/v/checker/tests/shared_param_assign_err.out
Normal file
13
vlib/v/checker/tests/shared_param_assign_err.out
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
vlib/v/checker/tests/shared_param_assign_err.vv:2:10: error: `arr` is `shared` and must be `rlock`ed or `lock`ed to be used as non-mut right-hand side of assignment
|
||||||
|
1 | fn foo(shared arr []string) {
|
||||||
|
2 | arr2 := arr
|
||||||
|
| ~~~
|
||||||
|
3 | println(arr2)
|
||||||
|
4 | }
|
||||||
|
vlib/v/checker/tests/shared_param_assign_err.vv:3:10: error: `arr2` is `shared` and must be `rlock`ed or `lock`ed to be used as non-mut argument to print
|
||||||
|
1 | fn foo(shared arr []string) {
|
||||||
|
2 | arr2 := arr
|
||||||
|
3 | println(arr2)
|
||||||
|
| ~~~~
|
||||||
|
4 | }
|
||||||
|
5 |
|
9
vlib/v/checker/tests/shared_param_assign_err.vv
Normal file
9
vlib/v/checker/tests/shared_param_assign_err.vv
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
fn foo(shared arr []string) {
|
||||||
|
arr2 := arr
|
||||||
|
println(arr2)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
shared arr := ['']
|
||||||
|
foo(shared arr)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user