handle embedded struct fields with universe scope

Whilst it may not be particularly common, it is legal to embed fields
where the type has universe scope (e.g. int, error, etc). This can
cause a panic in 2 difference places:

- When embedding `error`, a named type is resolved but the package is
nil. The call to `pkg.Name()` results in a panic
- When embedding a basic type such as `int`, no named type is resolved
at all. The call to `namedType(obj.Type()).Obj()` results in a panic

I'm assuming it is OK to return early when a named type cannot be
resolved.. we could let it continue but I think `pkg` should be set to
nil to be correct, so it'd end up returning straight away anyway.
pull/33/head
Nicholas Jones 4 years ago committed by GitHub
parent 04e8beed32
commit ecbcc61a62
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -668,15 +668,19 @@ func transformGo(file *ast.File, info *types.Info, blacklist map[types.Object]st
return true
}
pkg := obj.Pkg()
if pkg == nil {
return true // universe scope
}
if vr, ok := obj.(*types.Var); ok && vr.Embedded() {
// ObjectOf returns the field for embedded struct
// fields, not the type it uses. Use the type.
obj = namedType(obj.Type()).Obj()
named := namedType(obj.Type())
if named == nil {
return true // unnamed type (probably a basic type, e.g. int)
}
obj = named.Obj()
pkg = obj.Pkg()
}
if pkg == nil {
return true // universe scope
}
if pkg.Name() == "main" && obj.Exported() && obj.Parent() == pkg.Scope() {
// TODO: only do this when -buildmode is plugin? what

@ -36,6 +36,13 @@ type embedding struct {
embedded
}
// embedded fields whose type is in the universe scope used to crash garble
type EmbeddingUniverseScope struct {
error
int
string
}
func main() {
switch V := V.(type) {
case int:

Loading…
Cancel
Save