From 86040b7505c0e138ef6b476614a03e35c0706c05 Mon Sep 17 00:00:00 2001 From: Alan Donovan Date: Mon, 12 Jan 2015 12:48:42 -0500 Subject: [PATCH] go/types: close scope for each "select" case after its body Classic Go pitfall: "defer" in a loop does not do what you might expect. + test case Fixes issue 9570 Fixes issue 9569 Change-Id: Iec05420872ef71190083a7192f76c92f54f4a2a1 Reviewed-on: https://go-review.googlesource.com/2655 Reviewed-by: Robert Griesemer --- go/types/stmt.go | 2 +- go/types/testdata/stmt0.src | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/go/types/stmt.go b/go/types/stmt.go index 42580bdd..fa60f64d 100644 --- a/go/types/stmt.go +++ b/go/types/stmt.go @@ -569,11 +569,11 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { } check.openScope(s, "case") - defer check.closeScope() if clause.Comm != nil { check.stmt(inner, clause.Comm) } check.stmtList(inner, clause.Body) + check.closeScope() } case *ast.ForStmt: diff --git a/go/types/testdata/stmt0.src b/go/types/testdata/stmt0.src index 646c4189..4c840367 100644 --- a/go/types/testdata/stmt0.src +++ b/go/types/testdata/stmt0.src @@ -215,6 +215,17 @@ func selects() { case x /* ERROR send or receive */ : case a /* ERROR send or receive */ := ch: } + + // test for issue 9570: ch2 in second case falsely resolved to + // ch2 declared in body of first case + ch1 := make(chan int) + ch2 := make(chan int) + select { + case <-ch1: + var ch2 /* ERROR ch2 declared but not used */ chan bool + case i := <-ch2: + print(i + 1) + } } func gos() {