From d2c4a36c258585c5a2a858673bc97d70634e6613 Mon Sep 17 00:00:00 2001 From: Nicholas Wiersma Date: Mon, 29 Jun 2020 09:40:03 +0200 Subject: [PATCH] fix: dont optimize map index assigns --- _test/assign13.go | 19 +++++++++++++++++++ interp/cfg.go | 2 +- interp/run.go | 8 ++++++-- 3 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 _test/assign13.go diff --git a/_test/assign13.go b/_test/assign13.go new file mode 100644 index 00000000..62bde505 --- /dev/null +++ b/_test/assign13.go @@ -0,0 +1,19 @@ +package main + +import "fmt" + +func getStr() string { + return "test" +} + +func main() { + m := make(map[string]string, 0) + m["a"] = fmt.Sprintf("%v", 0.1) + m["b"] = string(fmt.Sprintf("%v", 0.1)) + m["c"] = getStr() + + fmt.Println(m) +} + +// Output: +// map[a:0.1 b:0.1 c:test] diff --git a/interp/cfg.go b/interp/cfg.go index a3346321..e39be2e9 100644 --- a/interp/cfg.go +++ b/interp/cfg.go @@ -521,7 +521,7 @@ func (interp *Interpreter) cfg(root *node, pkgID string) ([]*node, error) { // Propagate type // TODO: Check that existing destination type matches source type switch { - case n.action == aAssign && isCall(src) && dest.typ.cat != interfaceT && !isRecursiveField(dest): + case n.action == aAssign && isCall(src) && dest.typ.cat != interfaceT && !isMapEntry(dest) && !isRecursiveField(dest): // Call action may perform the assignment directly. n.gen = nop src.level = level diff --git a/interp/run.go b/interp/run.go index 99afa401..9f41c47d 100644 --- a/interp/run.go +++ b/interp/run.go @@ -1121,9 +1121,11 @@ func callBin(n *node) { } default: switch n.anc.action { - case aAssign, aAssignX: + case aAssignX: // The function call is part of an assign expression, store results direcly // to assigned location, to avoid an additional frame copy. + // The optimization of aAssign is handled in assign(), and should not + // be handled here. rvalues := make([]func(*frame) reflect.Value, funcType.NumOut()) for i := range rvalues { c := n.anc.child[i] @@ -1166,7 +1168,9 @@ func callBin(n *node) { in[i] = v(f) } out := callFn(value(f), in) - copy(f.data[n.findex:], out) + for i := 0; i < len(out); i++ { + f.data[n.findex+i].Set(out[i]) + } return tnext } }