]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: fix crash following misuse of [...]T in composite literal
authorRebecca Stambler <rstambler@golang.org>
Thu, 30 Aug 2018 20:01:15 +0000 (16:01 -0400)
committerRebecca Stambler <rstambler@golang.org>
Thu, 30 Aug 2018 21:07:35 +0000 (21:07 +0000)
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 <adonovan@google.com>
src/go/types/api_test.go
src/go/types/expr.go

index cde07f2b4bba6cb22e2bcff1dc7055344726cefc..c34ecbf9d160d37b9f131284851ccdccaab35708 100644 (file)
@@ -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 {
index c1deaf8325aaf85177f254cec814ad73ae2d67dc..143a9581822cee24add304c8c3a5fde7486e5113 100644 (file)
@@ -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: