cmd/compile: make for loops with range statements not terminating

Fixes #49003

Change-Id: If09c6f028dce5440b1be238612653ffdd626113a
Reviewed-on: https://go-review.googlesource.com/c/go/+/356189
Trust: Keith Randall <khr@golang.org>
Reviewed-by: roger peppe <rogpeppe@gmail.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Robert Griesemer <gri@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
This commit is contained in:
Keith Randall 2021-10-15 08:06:58 -07:00
parent cfe6763783
commit 22951fbc89
3 changed files with 20 additions and 2 deletions

View File

@ -1,6 +1,6 @@
<!--{
"Title": "The Go Programming Language Specification",
"Subtitle": "Version of Sep 16, 2021",
"Subtitle": "Version of Oct 15, 2021",
"Path": "/ref/spec"
}-->
@ -4598,7 +4598,8 @@ a <a href="#Blocks">block</a>. The following statements are terminating:
A <a href="#For_statements">"for" statement</a> in which:
<ul>
<li>there are no "break" statements referring to the "for" statement, and</li>
<li>the loop condition is absent.</li>
<li>the loop condition is absent, and</li>
<li>the "for" statement does not use a range clause.</li>
</ul>
</li>

View File

@ -62,6 +62,11 @@ func (check *Checker) isTerminating(s syntax.Stmt, label string) bool {
return true
case *syntax.ForStmt:
if _, ok := s.Init.(*syntax.RangeClause); ok {
// Range clauses guarantee that the loop terminates,
// so the loop is not a terminating statement. See issue 49003.
break
}
if s.Cond == nil && !hasBreak(s.Body, label, true) {
return true
}

View File

@ -0,0 +1,12 @@
// errorcheck
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package p
func f(s string) int {
for range s {
}
} // ERROR "missing return"