Skip to content

Commit

Permalink
fix: correct control flow graph for range init expression
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
mvertes authored Jul 13, 2020
1 parent 0c8f538 commit 0a79069
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 2 deletions.
18 changes: 18 additions & 0 deletions _test/issue-775.go
Original file line number Diff line number Diff line change
@@ -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]
4 changes: 2 additions & 2 deletions interp/cfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down

0 comments on commit 0a79069

Please sign in to comment.