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.
This commit is contained in:
Marc Vertes
2020-07-13 15:35:04 +02:00
committed by GitHub
parent 0c8f538cd9
commit 0a79069dfc
2 changed files with 20 additions and 2 deletions

18
_test/issue-775.go Normal file
View File

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

View File

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