fix bug where structs would get garbled in some packages but not in others

pull/161/head
Andrew LeFevre 5 years ago
parent 047aa254e2
commit 635f623a00

@ -940,14 +940,7 @@ func buildBlacklist(files []*ast.File, info *types.Info, pkg *types.Package) map
if obj == nil || obj.Pkg() != pkg {
return true
}
blacklist[obj] = struct{}{}
strct, _ := named.Underlying().(*types.Struct)
if strct != nil {
for i := 0; i < strct.NumFields(); i++ {
blacklist[strct.Field(i)] = struct{}{}
}
}
blacklistStruct(named, blacklist)
return true
}
@ -1058,17 +1051,62 @@ func transformGo(file *ast.File, info *types.Info, blacklist map[types.Object]st
}
// log.Printf("%#v %T", node, obj)
path := pkg.Path()
switch x := obj.(type) {
case *types.Var:
if parent := obj.Parent(); parent != nil && parent != pkg.Scope() {
// identifiers of non-global variables never show up in the binary
return true
}
// if the struct of this field was not garbled, do not garble
// any of that struct's fields
if x.IsField() && !x.Embedded() {
parent, ok := cursor.Parent().(*ast.SelectorExpr)
if !ok {
break
}
parentType := info.TypeOf(parent.X)
if parentType == nil {
break
}
named := namedType(parentType)
if named == nil {
break
}
if _, ok := buildInfo.imports[path]; ok {
garbledPkg, err := garbledImport(path)
if err != nil {
panic(err) // shouldn't happen
}
if garbledPkg.Scope().Lookup(named.Obj().Name()) != nil {
blacklistStruct(named, blacklist)
return true
}
}
}
case *types.TypeName:
if obj.Parent() != pkg.Scope() {
// identifiers of non-global types never show up in the binary
return true
}
// if the type was not garbled in the package were it was defined,
// do not garble it here
named := namedType(x.Type())
if named == nil {
break
}
if _, ok := buildInfo.imports[path]; ok {
garbledPkg, err := garbledImport(path)
if err != nil {
panic(err) // shouldn't happen
}
if garbledPkg.Scope().Lookup(x.Name()) != nil {
blacklistStruct(named, blacklist)
return true
}
}
case *types.Func:
sign := obj.Type().(*types.Signature)
if obj.Exported() && sign.Recv() != nil {
@ -1088,7 +1126,6 @@ func transformGo(file *ast.File, info *types.Info, blacklist map[types.Object]st
return true // we only want to rename the above
}
actionID := buildInfo.actionID
path := pkg.Path()
if !isPrivate(path) {
return true // only private packages are transformed
}
@ -1134,6 +1171,17 @@ func transformGo(file *ast.File, info *types.Info, blacklist map[types.Object]st
return astutil.Apply(file, pre, nil).(*ast.File)
}
func blacklistStruct(named *types.Named, blacklist map[types.Object]struct{}) {
blacklist[named.Obj()] = struct{}{}
strct, ok := named.Underlying().(*types.Struct)
if !ok {
return
}
for i := 0; i < strct.NumFields(); i++ {
blacklist[strct.Field(i)] = struct{}{}
}
}
// implementedOutsideGo returns whether a *types.Func does not have a body, for
// example when it's implemented in assembly, or when one uses go:linkname.
//

@ -6,6 +6,7 @@ exec ./main
cmp stdout main.stdout
! binsubstr main$exe 'ImportedVar' 'ImportedConst' 'ImportedFunc' 'ImportedType' 'main.go' 'test/main' 'imported.' 'NormalStruct' 'NormalExportedField' 'normalUnexportedField'
binsubstr main$exe 'ReflectInDefined' 'ExportedField2' 'unexportedField2'
[short] stop # checking that the build is reproducible is slow
@ -50,6 +51,7 @@ func main() {
fmt.Println(imported.ImportedConst)
fmt.Println(imported.ImportedFunc('x'))
fmt.Println(imported.ImportedType(3))
fmt.Println(imported.ReflectInDefinedVar.ExportedField2)
fmt.Println(imported.NormalStruct{})
printfWithoutPackage("%T\n", imported.ReflectTypeOf(2))
@ -118,6 +120,16 @@ var ReflectValueOfVar = ReflectValueOf{ExportedField: "abc"}
var _ = reflect.TypeOf(ReflectValueOfVar)
type ReflectInDefined struct {
ExportedField2 int
unexportedField2 int
}
var ReflectInDefinedVar = ReflectInDefined{ExportedField2: 9000}
var _ = reflect.TypeOf(ReflectInDefinedVar)
type NormalStruct struct {
NormalExportedField int
normalUnexportedField int
@ -132,6 +144,7 @@ imported var value
imported const value
x
3
9000
{0 0}
ReflectTypeOf
ReflectTypeOfIndirect

Loading…
Cancel
Save