cmd/compile: fix compile failure for lazily resolved shadowed types

If expanding an inline function body required lazily expanding a
package-scoped type whose identifier was shadowed within the function
body, the lazy expansion would instead overwrite the local symbol
definition instead of the package-scoped symbol. This was due to
importsym using s.Def instead of s.PkgDef.

Unfortunately, this is yet another consequence of the current awkward
scope handling code.

Passes toolstash-check.

Fixes #25984.

Change-Id: Ia7033e1749a883e6e979c854d4b12b0b28083dd8
Reviewed-on: https://go-review.googlesource.com/120456
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
Matthew Dempsky 2018-06-21 16:12:17 -07:00
parent 78a579316b
commit f422bea498
5 changed files with 46 additions and 4 deletions

View file

@ -89,7 +89,7 @@ func dumpexport(bout *bio.Writer) {
}
func importsym(ipkg *types.Pkg, pos src.XPos, s *types.Sym, op Op) *Node {
n := asNode(s.Def)
n := asNode(s.PkgDef())
if n == nil {
// iimport should have created a stub ONONAME
// declaration for all imported symbols. The exception
@ -100,7 +100,7 @@ func importsym(ipkg *types.Pkg, pos src.XPos, s *types.Sym, op Op) *Node {
}
n = dclname(s)
s.Def = asTypesNode(n)
s.SetPkgDef(asTypesNode(n))
s.Importdef = ipkg
}
if n.Op != ONONAME && n.Op != op {

View file

@ -80,15 +80,24 @@ func IsDclstackValid() bool {
// PkgDef returns the definition associated with s at package scope.
func (s *Sym) PkgDef() *Node {
return *s.pkgDefPtr()
}
// SetPkgDef sets the definition associated with s at package scope.
func (s *Sym) SetPkgDef(n *Node) {
*s.pkgDefPtr() = n
}
func (s *Sym) pkgDefPtr() **Node {
// Look for outermost saved declaration, which must be the
// package scope definition, if present.
for _, d := range dclstack {
if s == d.sym {
return d.def
return &d.def
}
}
// Otherwise, the declaration hasn't been shadowed within a
// function scope.
return s.Def
return &s.Def
}

View file

@ -0,0 +1,15 @@
// 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 p
type m struct {
link *m
}
var head *m
func F(m *int) bool {
return head != nil
}

View file

@ -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 q
import "./p"
func G() {
p.F(nil)
}

View file

@ -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