cgen: fix cross assign of struct fields (#5606)

pull/5612/head
yuyi 2020-07-02 00:43:14 +08:00 committed by GitHub
parent 56ae814cbc
commit 40a393926d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 0 deletions

View File

@ -1108,6 +1108,12 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
g.writeln(', &($styp[]){ $zero });')
}
}
ast.SelectorExpr {
styp := g.typ(left.typ)
g.write('$styp _var_$left.pos.pos = ')
g.expr(left.expr)
g.writeln('.$left.field_name;')
}
else {}
}
}
@ -1331,6 +1337,19 @@ fn (mut g Gen) gen_cross_tmp_variable(left []ast.Expr, val ast.Expr) {
g.gen_cross_tmp_variable(left, val.expr)
g.write(val.op.str())
}
ast.SelectorExpr {
mut has_var := false
for lx in left {
if val_.str() == lx.str() {
g.write('_var_${lx.position().pos}')
has_var = true
break
}
}
if !has_var {
g.expr(val_)
}
}
else {
g.expr(val_)
}

View File

@ -66,6 +66,13 @@ fn (mut p Parser) check_cross_variables(exprs []ast.Expr, val ast.Expr) bool {
ast.InfixExpr { return p.check_cross_variables(exprs, val_.left) || p.check_cross_variables(exprs, val_.right) }
ast.PrefixExpr { return p.check_cross_variables(exprs, val_.right) }
ast.PostfixExpr { return p.check_cross_variables(exprs, val_.expr) }
ast.SelectorExpr {
for expr in exprs {
if expr.str() == val.str() {
return true
}
}
}
else {}
}
return false

View File

@ -313,3 +313,17 @@ fn test_struct_with_default_values_no_init() {
assert s2.field_optional == 3
assert s3.field_optional == 2
}
struct Zoo {
mut:
a int
b int
}
fn test_struct_field_cross_assign() {
mut x := Zoo{a:1, b:2}
x.a, x.b = x.b, x.a
//println(x)
assert x.a == 2
assert x.b == 1
}