cgen: fix map value op-assign modification (#7101)
parent
1037d3a383
commit
c1b25dd61d
|
@ -353,3 +353,11 @@ fn test_map_str_after_delete() {
|
||||||
assert osm == "{'first': 1, 'second': 2, 'third': 3}"
|
assert osm == "{'first': 1, 'second': 2, 'third': 3}"
|
||||||
assert nsm == "{'first': 1, 'third': 3}"
|
assert nsm == "{'first': 1, 'third': 3}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_modify_map_value() {
|
||||||
|
mut m1 := {'foo': 3, 'bar': -7}
|
||||||
|
m1['foo'] += 5
|
||||||
|
m1['bar'] *= -2
|
||||||
|
assert m1['foo'] == 8
|
||||||
|
assert m1['bar'] == 14
|
||||||
|
}
|
||||||
|
|
|
@ -3779,6 +3779,43 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) {
|
||||||
} else {
|
} else {
|
||||||
g.write(', &($elem_type_str[]) { ')
|
g.write(', &($elem_type_str[]) { ')
|
||||||
}
|
}
|
||||||
|
if g.assign_op != .assign &&
|
||||||
|
g.assign_op in token.assign_tokens && info.value_type != table.string_type {
|
||||||
|
g.write('(*(int*)map_get(')
|
||||||
|
if left_is_ptr && !node.left_type.has_flag(.shared_f) {
|
||||||
|
g.write('*')
|
||||||
|
}
|
||||||
|
g.expr(node.left)
|
||||||
|
if node.left_type.has_flag(.shared_f) {
|
||||||
|
if left_is_ptr {
|
||||||
|
g.write('->val')
|
||||||
|
} else {
|
||||||
|
g.write('.val')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g.write(', ')
|
||||||
|
g.expr(node.index)
|
||||||
|
zero := g.type_default(info.value_type)
|
||||||
|
if elem_typ.kind == .function {
|
||||||
|
g.write(', &(voidptr[]){ $zero }))')
|
||||||
|
} else {
|
||||||
|
g.write(', &($elem_type_str[]){ $zero }))')
|
||||||
|
}
|
||||||
|
op := match g.assign_op {
|
||||||
|
.mult_assign { '*' }
|
||||||
|
.plus_assign { '+' }
|
||||||
|
.minus_assign { '-' }
|
||||||
|
.div_assign { '/' }
|
||||||
|
.xor_assign { '^' }
|
||||||
|
.mod_assign { '%' }
|
||||||
|
.or_assign { '|' }
|
||||||
|
.and_assign { '&' }
|
||||||
|
.left_shift_assign { '<<' }
|
||||||
|
.right_shift_assign { '>>' }
|
||||||
|
else { '' }
|
||||||
|
}
|
||||||
|
g.write(' $op ')
|
||||||
|
}
|
||||||
} else if (g.inside_map_postfix || g.inside_map_infix) ||
|
} else if (g.inside_map_postfix || g.inside_map_infix) ||
|
||||||
(g.is_assign_lhs && !g.is_array_set && get_and_set_types) {
|
(g.is_assign_lhs && !g.is_array_set && get_and_set_types) {
|
||||||
zero := g.type_default(info.value_type)
|
zero := g.type_default(info.value_type)
|
||||||
|
|
|
@ -10,7 +10,12 @@ fn incr(shared foo map[string]int, key string, sem sync.Semaphore) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_shared_array() {
|
fn test_shared_array() {
|
||||||
shared foo := &{'p': 10, 'q': 20}
|
shared foo := &{'p': 10, 'q': 0}
|
||||||
|
lock foo {
|
||||||
|
unsafe {
|
||||||
|
foo['q'] = 20
|
||||||
|
}
|
||||||
|
}
|
||||||
sem := sync.new_semaphore()
|
sem := sync.new_semaphore()
|
||||||
go incr(shared foo, 'p', sem)
|
go incr(shared foo, 'p', sem)
|
||||||
go incr(shared foo, 'q', sem)
|
go incr(shared foo, 'q', sem)
|
||||||
|
@ -19,8 +24,8 @@ fn test_shared_array() {
|
||||||
for _ in 0 .. 50000 {
|
for _ in 0 .. 50000 {
|
||||||
lock foo {
|
lock foo {
|
||||||
unsafe {
|
unsafe {
|
||||||
foo['p'] = foo['p'] - 2
|
foo['p'] -= 2
|
||||||
foo['q'] = foo['q'] + 3
|
foo['q'] += 3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue