]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: add check for map value completeness in IndexExpr
authorMark Freeman <mark@golang.org>
Tue, 20 Jan 2026 19:23:19 +0000 (14:23 -0500)
committerGopher Robot <gobot@golang.org>
Tue, 27 Jan 2026 15:52:07 +0000 (07:52 -0800)
An index expression can also go from map[K]V to V. Since V could be
incomplete (due to some admittedly contrived syntax), we need a
check.

Change-Id: I03ffbfc0e5bcc9129591d60dfbaa5fafcf8fb183
Reviewed-on: https://go-review.googlesource.com/c/go/+/737620
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Auto-Submit: Mark Freeman <markfreeman@google.com>

src/cmd/compile/internal/types2/index.go
src/go/types/index.go
src/internal/types/testdata/check/cycles6.go

index 98d83833c82e1f70fd9b8404294fb86204674f3d..5b52cea83774db3127ba7602c16a781b05d6f1e5 100644 (file)
@@ -52,11 +52,21 @@ func (check *Checker) indexExpr(x *operand, e *syntax.IndexExpr) (isFuncInst boo
                x.mode = invalid
                return false
        }
-       // Additionally, if x.typ is a pointer to an array type, indexing implicitly dereferences the value, meaning
-       // its base type must also be complete.
-       if p, ok := x.typ.Underlying().(*Pointer); ok && !check.isComplete(p.base) {
-               x.mode = invalid
-               return false
+       switch typ := x.typ.Underlying().(type) {
+       case *Pointer:
+               // Additionally, if x.typ is a pointer to an array type, indexing implicitly dereferences the value, meaning
+               // its base type must also be complete.
+               if !check.isComplete(typ.base) {
+                       x.mode = invalid
+                       return false
+               }
+       case *Map:
+               // Lastly, if x.typ is a map type, indexing must produce a value of a complete type, meaning
+               // its element type must also be complete.
+               if !check.isComplete(typ.elem) {
+                       x.mode = invalid
+                       return false
+               }
        }
 
        // ordinary index expression
index 720cbbf0ea2c6c549d41323f877f34eb268743f6..9089092e52be2d7024f2021bc6e486755462e059 100644 (file)
@@ -53,11 +53,21 @@ func (check *Checker) indexExpr(x *operand, e *indexedExpr) (isFuncInst bool) {
                x.mode = invalid
                return false
        }
-       // Additionally, if x.typ is a pointer to an array type, indexing implicitly dereferences the value, meaning
-       // its base type must also be complete.
-       if p, ok := x.typ.Underlying().(*Pointer); ok && !check.isComplete(p.base) {
-               x.mode = invalid
-               return false
+       switch typ := x.typ.Underlying().(type) {
+       case *Pointer:
+               // Additionally, if x.typ is a pointer to an array type, indexing implicitly dereferences the value, meaning
+               // its base type must also be complete.
+               if !check.isComplete(typ.base) {
+                       x.mode = invalid
+                       return false
+               }
+       case *Map:
+               // Lastly, if x.typ is a map type, indexing must produce a value of a complete type, meaning
+               // its element type must also be complete.
+               if !check.isComplete(typ.elem) {
+                       x.mode = invalid
+                       return false
+               }
        }
 
        // ordinary index expression
index e5635ed4566c4ec460dddb92538cc0d366eae63d..7c627749a467fdb4b5417833cbacf4b38856ba7f 100644 (file)
@@ -69,3 +69,5 @@ type T11 /* ERROR "invalid recursive type" */ [unsafe.Sizeof(new(T11)[:])]int
 type T12 /* ERROR "invalid recursive type" */ [unsafe.Sizeof(T12{}[42])]int
 // index on pointer                                                             (case 3)
 type T13 /* ERROR "invalid recursive type" */ [unsafe.Sizeof(new(T13)[42])]int
+// index on map                                                                            (case 1)
+type T14 /* ERROR "invalid recursive type" */ [unsafe.Sizeof((*new(map[int]T14))[42])]int