mirror of https://github.com/golang/go.git
go/parser: fix panic in object resolution for invalid type parameter list
This change restores the original logic in parseParameterList to what it was before CL 538858 (which caused the issue), not in exact wording but in identical semantic meaning, and thus restores this function to a state that we know was working fine. However, the change keeps the improved error reporting introduced by CL 538858. To keep the code changes somewhat minimal as we are close to RC1, the improved error handling exists twice for now even though it could be factored out. Fixes #64534. Change-Id: I0b7bbf74d28811e8aae74f838f2d424f78af1f38 Reviewed-on: https://go-review.googlesource.com/c/go/+/548395 Reviewed-by: Alan Donovan <adonovan@google.com> Run-TryBot: Robert Griesemer <gri@google.com> Reviewed-by: Robert Griesemer <gri@google.com> Auto-Submit: Robert Griesemer <gri@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
6cdf2ccae8
commit
e1cba47ee0
|
|
@ -881,6 +881,13 @@ func (p *parser) parseParameterList(name0 *ast.Ident, typ0 ast.Expr, closing tok
|
|||
// Type parameters are the only parameter list closed by ']'.
|
||||
tparams := closing == token.RBRACK
|
||||
|
||||
pos0 := p.pos
|
||||
if name0 != nil {
|
||||
pos0 = name0.Pos()
|
||||
} else if typ0 != nil {
|
||||
pos0 = typ0.Pos()
|
||||
}
|
||||
|
||||
// Note: The code below matches the corresponding code in the syntax
|
||||
// parser closely. Changes must be reflected in either parser.
|
||||
// For the code to match, we use the local []field list that
|
||||
|
|
@ -923,8 +930,8 @@ func (p *parser) parseParameterList(name0 *ast.Ident, typ0 ast.Expr, closing tok
|
|||
}
|
||||
|
||||
// distribute parameter types (len(list) > 0)
|
||||
if named == 0 && !tparams {
|
||||
// all unnamed and we're not in a type parameter list => found names are type names
|
||||
if named == 0 {
|
||||
// all unnamed => found names are type names
|
||||
for i := 0; i < len(list); i++ {
|
||||
par := &list[i]
|
||||
if typ := par.name; typ != nil {
|
||||
|
|
@ -932,6 +939,23 @@ func (p *parser) parseParameterList(name0 *ast.Ident, typ0 ast.Expr, closing tok
|
|||
par.name = nil
|
||||
}
|
||||
}
|
||||
if tparams {
|
||||
// This is the same error handling as below, adjusted for type parameters only.
|
||||
// See comment below for details. (go.dev/issue/64534)
|
||||
var errPos token.Pos
|
||||
var msg string
|
||||
if named == typed /* same as typed == 0 */ {
|
||||
errPos = p.pos // position error at closing ]
|
||||
msg = "missing type constraint"
|
||||
} else {
|
||||
errPos = pos0 // position at opening [ or first name
|
||||
msg = "missing type parameter name"
|
||||
if len(list) == 1 {
|
||||
msg += " or invalid array length"
|
||||
}
|
||||
}
|
||||
p.error(errPos, msg)
|
||||
}
|
||||
} else if named != len(list) {
|
||||
// some named or we're in a type parameter list => all must be named
|
||||
var errPos token.Pos // left-most error position (or invalid)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
// Copyright 2023 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.
|
||||
|
||||
// Test case for go.dev/issue/64534.
|
||||
// Parser should not panic during object resolution.
|
||||
|
||||
package main
|
||||
|
||||
func _[A /* ERROR "missing type parameter name" */ $(B](){}}
|
||||
Loading…
Reference in New Issue