Skip to content

Commit 0981724

Browse files
committed
go/types: check for non-negative index in tparamIndex
There are code paths (particularly error formatting or tracing) that call tparamIndex before the type parameter is bound. We cannot rely on the index being non-negative. Change-Id: Ibad91c691b4f319b0c7b465a750b679a8a7af6a1 Reviewed-on: https://go-review.googlesource.com/c/go/+/364715 Trust: Robert Findley <[email protected]> Run-TryBot: Robert Findley <[email protected]> Reviewed-by: Robert Griesemer <[email protected]> TryBot-Result: Go Bot <[email protected]>
1 parent 9bdbed1 commit 0981724

File tree

2 files changed

+15
-10
lines changed

2 files changed

+15
-10
lines changed

src/cmd/compile/internal/types2/unify.go

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ package types2
99
import (
1010
"bytes"
1111
"fmt"
12-
"internal/buildcfg"
1312
)
1413

1514
// The unifier maintains two separate sets of type parameters x and y
@@ -162,13 +161,13 @@ func (d *tparamsList) index(typ Type) int {
162161
// If tpar is a type parameter in list, tparamIndex returns the type parameter index.
163162
// Otherwise, the result is < 0. tpar must not be nil.
164163
func tparamIndex(list []*TypeParam, tpar *TypeParam) int {
165-
// Temporary work-around for getting around a crash
166-
// with unified build.
167-
// TODO(gri) investigate and implement proper fix
168-
if buildcfg.Experiment.Unified && tpar.index < 0 {
169-
return -1
170-
}
171-
if i := tpar.index; i < len(list) && list[i] == tpar {
164+
// Once a type parameter is bound its index is >= 0. However, there are some
165+
// code paths (namely tracing and type hashing) by which it is possible to
166+
// arrive here with a type parameter that has not been bound, hence the check
167+
// for 0 <= i below.
168+
// TODO(rfindley): investigate a better approach for guarding against using
169+
// unbound type parameters.
170+
if i := tpar.index; 0 <= i && i < len(list) && list[i] == tpar {
172171
return i
173172
}
174173
return -1

src/go/types/unify.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,15 @@ func (d *tparamsList) index(typ Type) int {
159159
}
160160

161161
// If tpar is a type parameter in list, tparamIndex returns the type parameter index.
162-
// Otherwise, the result is < 0. tpar must not be nil.
162+
// Otherwise, the result is < 0. tpar must not be nil.j
163163
func tparamIndex(list []*TypeParam, tpar *TypeParam) int {
164-
if i := tpar.index; i < len(list) && list[i] == tpar {
164+
// Once a type parameter is bound its index is >= 0. However, there are some
165+
// code paths (namely tracing and type hashing) by which it is possible to
166+
// arrive here with a type parameter that has not been bound, hence the check
167+
// for 0 <= i below.
168+
// TODO(rfindley): investigate a better approach for guarding against using
169+
// unbound type parameters.
170+
if i := tpar.index; 0 <= i && i < len(list) && list[i] == tpar {
165171
return i
166172
}
167173
return -1

0 commit comments

Comments
 (0)