From 6c0b8b5f8c74560007ae5929c7a2bfe3b9b875a8 Mon Sep 17 00:00:00 2001 From: Rebecca Stambler Date: Thu, 30 Aug 2018 16:01:15 -0400 Subject: [PATCH] go/types: fix crash following misuse of [...]T in composite literal The type-checker currently crashes when checking code such as: _ = map[string][...]int{"": {1, 2, 3}} In this case, the type checker reports an error for map[string][...]int, then proceeds to type-check the values of the map literal using a hint type of [...]int. When type-checking the inner composite (array) literal, the length of the open array type is computed from the elements, then the array type is recorded, but the literal has no explicit type syntax against which to record the type, so this code causes the type-checker to panic. Add a nil check before calling check.recordTypeAndValue to avoid that. Updates #22467 Change-Id: Ic4453ba485b7b88ede2a89f209365eda9e032abc Reviewed-on: https://go-review.googlesource.com/132355 Reviewed-by: Alan Donovan --- src/go/types/api_test.go | 1 + src/go/types/expr.go | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/go/types/api_test.go b/src/go/types/api_test.go index cde07f2b4b..c34ecbf9d1 100644 --- a/src/go/types/api_test.go +++ b/src/go/types/api_test.go @@ -263,6 +263,7 @@ func TestTypesInfo(t *testing.T) { {`package x2; func _() { var a, b string; type x struct {f string}; z := &x{f: a; f: b;}}`, `b`, `string`}, {`package x3; var x = panic("");`, `panic`, `func(interface{})`}, {`package x4; func _() { panic("") }`, `panic`, `func(interface{})`}, + {`package x5; func _() { var x map[string][...]int; x = map[string][...]int{"": {1,2,3}} }`, `x`, `map[string][-1]int`}, } for _, test := range tests { diff --git a/src/go/types/expr.go b/src/go/types/expr.go index c1deaf8325..143a958182 100644 --- a/src/go/types/expr.go +++ b/src/go/types/expr.go @@ -1161,7 +1161,13 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { // not called for [...]). if utyp.len < 0 { utyp.len = n - check.recordTypeAndValue(e.Type, typexpr, utyp, nil) + // e.Type may be missing in case of errors. + // In "map[string][...]int{"": {1, 2, 3}}}, + // an error is reported for the outer literal, + // then [...]int is used as a hint for the inner literal. + if e.Type != nil { + check.recordTypeAndValue(e.Type, typexpr, utyp, nil) + } } case *Slice: