]> Cypherpunks.ru repositories - gostls13.git/commitdiff
go/parser: fix panic in object resolution for invalid type parameter list
authorRobert Griesemer <gri@golang.org>
Fri, 8 Dec 2023 05:08:17 +0000 (21:08 -0800)
committerGopher Robot <gobot@golang.org>
Fri, 8 Dec 2023 20:07:50 +0000 (20:07 +0000)
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>

src/go/parser/parser.go
src/go/parser/testdata/issue64534.src [new file with mode: 0644]

index a28960523eda818937d1c89c8ffe2d72785ee24d..17808b366f092d1e72977eaac6db93c1628f2510 100644 (file)
@@ -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 (file)
index 0000000..006cc93
--- /dev/null
@@ -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](){}}