From 0a79069dfc7f1608f66d064ce5c44944f68d99c3 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Mon, 13 Jul 2020 15:35:04 +0200 Subject: [PATCH] fix: correct control flow graph for range init expression The range init AST execution was skipped, and range could work only over variables or direct function calls. By setting the start node to the start of init and not init itself, we ensure that the init AST is always taken into account. Fixes #775. --- _test/issue-775.go | 18 ++++++++++++++++++ interp/cfg.go | 4 ++-- 2 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 _test/issue-775.go diff --git a/_test/issue-775.go b/_test/issue-775.go new file mode 100644 index 00000000..69f46fa1 --- /dev/null +++ b/_test/issue-775.go @@ -0,0 +1,18 @@ +package main + +import ( + "fmt" + "net/http/httptest" +) + +func main() { + recorder := httptest.NewRecorder() + recorder.Header().Add("Foo", "Bar") + + for key, value := range recorder.Header() { + fmt.Println(key, value) + } +} + +// Output: +// Foo [Bar] diff --git a/interp/cfg.go b/interp/cfg.go index 85d00aaa..cb5f63a3 100644 --- a/interp/cfg.go +++ b/interp/cfg.go @@ -1334,7 +1334,7 @@ func (interp *Interpreter) cfg(root *node, pkgID string) ([]*node, error) { case rangeStmt: if sc.rangeChanType(n) != nil { - n.start = n.child[1] // Get chan + n.start = n.child[1].start // Get chan n.child[1].tnext = n // then go to range function n.tnext = n.child[2].start // then go to range body n.child[2].tnext = n // then body go to range function (loop) @@ -1346,7 +1346,7 @@ func (interp *Interpreter) cfg(root *node, pkgID string) ([]*node, error) { } else { k, o, body = n.child[0], n.child[1], n.child[2] } - n.start = o // Get array or map object + n.start = o.start // Get array or map object o.tnext = k.start // then go to iterator init k.tnext = n // then go to range function n.tnext = body.start // then go to range body