]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: check for non-negative index in tparamIndex
authorRobert Findley <rfindley@google.com>
Wed, 17 Nov 2021 14:38:16 +0000 (09:38 -0500)
committerRobert Findley <rfindley@google.com>
Wed, 17 Nov 2021 18:14:41 +0000 (18:14 +0000)
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 <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
Reviewed-by: Robert Griesemer <gri@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>

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

index 651bba1a6bfcebc75a34242cdfa97e0ddbff96e0..f663beec38bbcca373a5ef51d52715ba6e9a737a 100644 (file)
@@ -9,7 +9,6 @@ package types2
 import (
        "bytes"
        "fmt"
-       "internal/buildcfg"
 )
 
 // The unifier maintains two separate sets of type parameters x and y
@@ -162,13 +161,13 @@ func (d *tparamsList) index(typ Type) int {
 // If tpar is a type parameter in list, tparamIndex returns the type parameter index.
 // Otherwise, the result is < 0. tpar must not be nil.
 func tparamIndex(list []*TypeParam, tpar *TypeParam) int {
-       // Temporary work-around for getting around a crash
-       // with unified build.
-       // TODO(gri) investigate and implement proper fix
-       if buildcfg.Experiment.Unified && tpar.index < 0 {
-               return -1
-       }
-       if i := tpar.index; i < len(list) && list[i] == tpar {
+       // Once a type parameter is bound its index is >= 0. However, there are some
+       // code paths (namely tracing and type hashing) by which it is possible to
+       // arrive here with a type parameter that has not been bound, hence the check
+       // for 0 <= i below.
+       // TODO(rfindley): investigate a better approach for guarding against using
+       // unbound type parameters.
+       if i := tpar.index; 0 <= i && i < len(list) && list[i] == tpar {
                return i
        }
        return -1
index d3b86008ef246a3c00d32fea18fcfff22efb93a2..6cd653aee1bd9977fd701580a9838ddaba19d0d2 100644 (file)
@@ -159,9 +159,15 @@ func (d *tparamsList) index(typ Type) int {
 }
 
 // If tpar is a type parameter in list, tparamIndex returns the type parameter index.
-// Otherwise, the result is < 0. tpar must not be nil.
+// Otherwise, the result is < 0. tpar must not be nil.j
 func tparamIndex(list []*TypeParam, tpar *TypeParam) int {
-       if i := tpar.index; i < len(list) && list[i] == tpar {
+       // Once a type parameter is bound its index is >= 0. However, there are some
+       // code paths (namely tracing and type hashing) by which it is possible to
+       // arrive here with a type parameter that has not been bound, hence the check
+       // for 0 <= i below.
+       // TODO(rfindley): investigate a better approach for guarding against using
+       // unbound type parameters.
+       if i := tpar.index; 0 <= i && i < len(list) && list[i] == tpar {
                return i
        }
        return -1