cgen: fix map value op-assign modification (#7101)

pull/7104/head
Uwe Krüger 2020-12-03 00:40:11 +01:00 committed by GitHub
parent 1037d3a383
commit c1b25dd61d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 3 deletions

View File

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

View File

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

View File

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