Fix type assertion failures with latest tools packages.

PiperOrigin-RevId: 511564602
This commit is contained in:
Adin Scannell
2023-02-22 12:23:43 -08:00
committed by gVisor bot
parent 118c0c5437
commit 442b16ee24
2 changed files with 40 additions and 16 deletions
+31 -14
View File
@@ -75,14 +75,16 @@ func (p *pkg) walkObject(pass *analysis.Pass, obj types.Object) {
case *types.Var:
// Skip if the var's type is a type parameter.
typ := x.Type()
if _, ok := typ.(*types.TypeParam); ok {
if _, ok := typ.Underlying().(*types.TypeParam); ok {
break
}
// Add information as a field.
a := Align(pass.TypesSizes.Alignof(typ))
s := Size(pass.TypesSizes.Sizeof(typ))
pass.ExportObjectFact(obj, &a)
pass.ExportObjectFact(obj, &s)
bestEffort(func() {
a := Align(pass.TypesSizes.Alignof(typ))
s := Size(pass.TypesSizes.Sizeof(typ))
pass.ExportObjectFact(obj, &a)
pass.ExportObjectFact(obj, &s)
})
case *types.TypeName:
// Skip if just an alias, or if not underlying type, or if a
// type parameter. If it is not an alias, then it must be
@@ -91,14 +93,16 @@ func (p *pkg) walkObject(pass *analysis.Pass, obj types.Object) {
if x.IsAlias() || typ == nil || typ.Underlying() == nil {
break
}
if _, ok := typ.(*types.TypeParam); ok {
if _, ok := typ.Underlying().(*types.TypeParam); ok {
break
}
// Add basic information.
a := Align(pass.TypesSizes.Alignof(typ))
s := Size(pass.TypesSizes.Sizeof(typ))
pass.ExportObjectFact(obj, &a)
pass.ExportObjectFact(obj, &s)
bestEffort(func() {
a := Align(pass.TypesSizes.Alignof(typ))
s := Size(pass.TypesSizes.Sizeof(typ))
pass.ExportObjectFact(obj, &a)
pass.ExportObjectFact(obj, &s)
})
// Recurse to fields if this is a definition.
if structType, ok := typ.Underlying().(*types.Struct); ok {
fields := make([]*types.Var, 0, structType.NumFields())
@@ -107,10 +111,12 @@ func (p *pkg) walkObject(pass *analysis.Pass, obj types.Object) {
fields = append(fields, fieldObj)
p.walkObject(pass, fieldObj)
}
offsets := pass.TypesSizes.Offsetsof(fields)
for i, field := range fields {
pass.ExportObjectFact(field, (*Offset)(&offsets[i]))
}
bestEffort(func() {
offsets := pass.TypesSizes.Offsetsof(fields)
for i, field := range fields {
pass.ExportObjectFact(field, (*Offset)(&offsets[i]))
}
})
}
case *types.Func:
// Skip if no underlying type.
@@ -136,6 +142,17 @@ func (p *pkg) walkObject(pass *analysis.Pass, obj types.Object) {
}
}
// bestEffort is a panic/recover wrapper. This is used because the tools
// package occasionally panics due to some type parameter use, and there is no
// simple or obvious way to detect these conditions. This should only be used
// when absolutely necessary.
func bestEffort(fn func()) {
defer func() {
recover()
}()
fn()
}
// walkScope recursively resolves a scope.
func (p *pkg) walkScope(pass *analysis.Pass, scope *types.Scope) {
for _, name := range scope.Names() {
+9 -2
View File
@@ -56,7 +56,7 @@ func (pc *passContext) typeAlignment(pkg *types.Package, obj types.Object) atomi
}
case *types.Array:
// Export direct alignment requirements.
if named, ok := x.Elem().(*types.Named); ok {
if named, ok := x.Elem().(*types.Named); ok && !hasTypeParams(named) {
requiredOffset = pc.typeAlignment(pkg, named.Obj())
}
default:
@@ -75,12 +75,19 @@ func (pc *passContext) typeAlignment(pkg *types.Package, obj types.Object) atomi
return requiredOffset
}
// hasTypeParams returns true iff the named type has type parameters.
func hasTypeParams(typ *types.Named) bool {
return typ.TypeParams() != nil && typ.TypeParams().Len() > 0
}
// checkTypeAlignment checks the alignment of the given type.
//
// This calls typeAlignment, which resolves all types recursively. This method
// should be called for all types individual to ensure full coverage.
func (pc *passContext) checkTypeAlignment(pkg *types.Package, typ *types.Named) {
_ = pc.typeAlignment(pkg, typ.Obj())
if !hasTypeParams(typ) {
_ = pc.typeAlignment(pkg, typ.Obj())
}
}
// atomicRules specify read constraints.