From: Robert Griesemer Date: Fri, 8 Dec 2023 05:08:17 +0000 (-0800) Subject: go/parser: fix panic in object resolution for invalid type parameter list X-Git-Tag: go1.22rc1~59 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=e1cba47ee06d59751e09fc8777ee9c57211018a5;p=gostls13.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 Run-TryBot: Robert Griesemer Reviewed-by: Robert Griesemer Auto-Submit: Robert Griesemer TryBot-Result: Gopher Robot --- diff --git a/src/go/parser/parser.go b/src/go/parser/parser.go index a28960523e..17808b366f 100644 --- a/src/go/parser/parser.go +++ b/src/go/parser/parser.go @@ -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) diff --git a/src/go/parser/testdata/issue64534.src b/src/go/parser/testdata/issue64534.src new file mode 100644 index 0000000000..006cc934a1 --- /dev/null +++ b/src/go/parser/testdata/issue64534.src @@ -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](){}}