From cc422e64d083b28a5f03e654970276c4bcac3677 Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Wed, 11 Jul 2018 16:43:51 -0700 Subject: [PATCH] cmd/compile: fix ICE due to missing inline function body For golang.org/cl/74110, I forgot that you can use range-based for loops to extract key values from a map value. This wasn't a problem for the binary format importer, because it was more tolerant about missing inline function bodies. However, the indexed importer is more particular about this. We could potentially just make it more lenient like the binary importer, but tweaking the logic here is easy enough and seems like the preferable solution. Fixes #26341. Change-Id: I54564dcd0be60ea393f8a0f6954b7d3d61e96ee5 Reviewed-on: https://go-review.googlesource.com/123475 Run-TryBot: Matthew Dempsky TryBot-Result: Gobot Gobot Reviewed-by: Heschi Kreinick --- src/cmd/compile/internal/gc/bexport.go | 25 ++++++++++++++----------- test/fixedbugs/issue26341.dir/a.go | 11 +++++++++++ test/fixedbugs/issue26341.dir/b.go | 13 +++++++++++++ test/fixedbugs/issue26341.go | 7 +++++++ 4 files changed, 45 insertions(+), 11 deletions(-) create mode 100644 test/fixedbugs/issue26341.dir/a.go create mode 100644 test/fixedbugs/issue26341.dir/b.go create mode 100644 test/fixedbugs/issue26341.go diff --git a/src/cmd/compile/internal/gc/bexport.go b/src/cmd/compile/internal/gc/bexport.go index 0d4997ccfc..d0b1804eb6 100644 --- a/src/cmd/compile/internal/gc/bexport.go +++ b/src/cmd/compile/internal/gc/bexport.go @@ -464,19 +464,22 @@ func (p *exporter) markType(t *types.Type) { } // Recursively mark any types that can be produced given a - // value of type t: dereferencing a pointer; indexing an - // array, slice, or map; receiving from a channel; accessing a - // struct field or interface method; or calling a function. + // value of type t: dereferencing a pointer; indexing or + // iterating over an array, slice, or map; receiving from a + // channel; accessing a struct field or interface method; or + // calling a function. // - // Notably, we don't mark map key or function parameter types, - // because the user already needs some way to construct values - // of those types. - // - // It's not critical for correctness that this algorithm is - // perfect. Worst case, we might miss opportunities to inline - // some function calls in downstream packages. + // Notably, we don't mark function parameter types, because + // the user already needs some way to construct values of + // those types. switch t.Etype { - case TPTR32, TPTR64, TARRAY, TSLICE, TCHAN, TMAP: + case TPTR32, TPTR64, TARRAY, TSLICE, TCHAN: + // TODO(mdempsky): Skip marking element type for + // send-only channels? + p.markType(t.Elem()) + + case TMAP: + p.markType(t.Key()) p.markType(t.Elem()) case TSTRUCT: diff --git a/test/fixedbugs/issue26341.dir/a.go b/test/fixedbugs/issue26341.dir/a.go new file mode 100644 index 0000000000..4fd23c796b --- /dev/null +++ b/test/fixedbugs/issue26341.dir/a.go @@ -0,0 +1,11 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package a + +type k int + +func (k) F() {} + +type M map[k]int diff --git a/test/fixedbugs/issue26341.dir/b.go b/test/fixedbugs/issue26341.dir/b.go new file mode 100644 index 0000000000..30b8c25a5c --- /dev/null +++ b/test/fixedbugs/issue26341.dir/b.go @@ -0,0 +1,13 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package b + +import "./a" + +func f() { + for k := range (a.M{}) { + k.F() + } +} diff --git a/test/fixedbugs/issue26341.go b/test/fixedbugs/issue26341.go new file mode 100644 index 0000000000..128cf9d06a --- /dev/null +++ b/test/fixedbugs/issue26341.go @@ -0,0 +1,7 @@ +// compiledir + +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ignored -- 2.50.0