]> Cypherpunks.ru repositories - gostls13.git/commitdiff
go/types, types2: explicitly check for non-nil type in LookupFieldOrMethod
authorRobert Griesemer <gri@golang.org>
Wed, 19 Jan 2022 03:58:14 +0000 (19:58 -0800)
committerRobert Griesemer <gri@golang.org>
Wed, 19 Jan 2022 16:33:42 +0000 (16:33 +0000)
Document and enforce API expectation. Add a test so we don't
inadvertently change the function behavior with respect to nil
type arguments.

Fixes #50620.

Change-Id: Ic000bff7504a03006bd248a319c7a2d49dcf09c8
Reviewed-on: https://go-review.googlesource.com/c/go/+/379374
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/compile/internal/types2/api_test.go
src/cmd/compile/internal/types2/lookup.go
src/go/types/api_test.go
src/go/types/lookup.go

index 2493bfb200e706fd4fa2901b12558766aeca5a3a..3b75818d56e0ddc44d2a80e5eca2b505006ef1ae 100644 (file)
@@ -1443,6 +1443,18 @@ var _ = a.C2
        makePkg("main", mainSrc) // don't crash when type-checking this package
 }
 
+func TestLookupFieldOrMethodOnNil(t *testing.T) {
+       // LookupFieldOrMethod on a nil type is expected to produce a run-time panic.
+       defer func() {
+               const want = "LookupFieldOrMethod on nil type"
+               p := recover()
+               if s, ok := p.(string); !ok || s != want {
+                       t.Fatalf("got %v, want %s", p, want)
+               }
+       }()
+       LookupFieldOrMethod(nil, false, nil, "")
+}
+
 func TestLookupFieldOrMethod(t *testing.T) {
        // Test cases assume a lookup of the form a.f or x.f, where a stands for an
        // addressable value, and x for a non-addressable value (even though a variable
index 2b710040a48cb45410a3d1c239e45c3253833e5d..61e8aa5054b169512c7a5685c5c1a2797b4c1825 100644 (file)
@@ -19,7 +19,7 @@ import (
 // in T and returns the corresponding *Var or *Func, an index sequence, and a
 // bool indicating if there were any pointer indirections on the path to the
 // field or method. If addressable is set, T is the type of an addressable
-// variable (only matters for method lookups).
+// variable (only matters for method lookups). T must not be nil.
 //
 // The last index entry is the field or method index in the (possibly embedded)
 // type where the entry was found, either:
@@ -42,6 +42,10 @@ import (
 //     the method's formal receiver base type, nor was the receiver addressable.
 //
 func LookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (obj Object, index []int, indirect bool) {
+       if T == nil {
+               panic("LookupFieldOrMethod on nil type")
+       }
+
        // Methods cannot be associated to a named pointer type.
        // (spec: "The type denoted by T is called the receiver base type;
        // it must not be a pointer or interface type and it must be declared
index 8c80494de73e4e790c8d9f7bc1fd7bb87b53fcf1..7986534e78b0bef3d82b30cedd9b7ec0f39da2b0 100644 (file)
@@ -1426,6 +1426,18 @@ var _ = a.C2
        makePkg("main", mainSrc) // don't crash when type-checking this package
 }
 
+func TestLookupFieldOrMethodOnNil(t *testing.T) {
+       // LookupFieldOrMethod on a nil type is expected to produce a run-time panic.
+       defer func() {
+               const want = "LookupFieldOrMethod on nil type"
+               p := recover()
+               if s, ok := p.(string); !ok || s != want {
+                       t.Fatalf("got %v, want %s", p, want)
+               }
+       }()
+       LookupFieldOrMethod(nil, false, nil, "")
+}
+
 func TestLookupFieldOrMethod(t *testing.T) {
        // Test cases assume a lookup of the form a.f or x.f, where a stands for an
        // addressable value, and x for a non-addressable value (even though a variable
index b9c5048b5d32e66f9ec9cc617934e49e6a545191..d35e53aa107fe5b85b6d668ec30feec8efa9e832 100644 (file)
@@ -19,7 +19,7 @@ import (
 // in T and returns the corresponding *Var or *Func, an index sequence, and a
 // bool indicating if there were any pointer indirections on the path to the
 // field or method. If addressable is set, T is the type of an addressable
-// variable (only matters for method lookups).
+// variable (only matters for method lookups). T must not be nil.
 //
 // The last index entry is the field or method index in the (possibly embedded)
 // type where the entry was found, either:
@@ -42,6 +42,10 @@ import (
 //     the method's formal receiver base type, nor was the receiver addressable.
 //
 func LookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (obj Object, index []int, indirect bool) {
+       if T == nil {
+               panic("LookupFieldOrMethod on nil type")
+       }
+
        // Methods cannot be associated to a named pointer type.
        // (spec: "The type denoted by T is called the receiver base type;
        // it must not be a pointer or interface type and it must be declared