Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
Change-Id: I72f42d4b8ccf83bcd74cb7a91bbf3dad328c496b
  • Loading branch information
mateusz834 committed Feb 14, 2025
1 parent 0ec4e57 commit ff0149f
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 31 deletions.
4 changes: 4 additions & 0 deletions src/cmd/compile/internal/devirtualize/devirtualize.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ func StaticCall(call *ir.CallExpr) {
return
}

if !typecheck.Implements(typ, sel.X.Type()) {
return
}

// If typ is a shape type, then it was a type argument originally
// and we'd need an indirect call through the dictionary anyway.
// We're unable to devirtualize this call.
Expand Down
30 changes: 5 additions & 25 deletions src/cmd/compile/internal/ir/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -840,28 +840,15 @@ func IsAddressable(n Node) bool {
return false
}

var Implements = func(t, iface *types.Type) bool {
panic("unreachable")
}

// StaticType is like StaticValue but for types.
// StaticType is like StaticValue, but also follows ODOTTYPE and OCONVIFACE.
func StaticType(n Node) *types.Type {
out, typs := staticValue(n, true)
out := staticValue(n, true)

typ := out.Type()
if typ.IsInterface() {
return nil
}

// Make sure that every type assertion that involves interfaes is satisfied.
for _, t := range typs {
if t.IsInterface() {
if !Implements(typ, t) {
return nil
}
}
}

return typ
}

Expand All @@ -880,16 +867,11 @@ func StaticType(n Node) *types.Type {
// calling StaticValue on the "int(y)" expression returns the outer
// "g()" expression.
func StaticValue(n Node) Node {
v, t := staticValue(n, false)
if len(t) != 0 {
base.Fatalf("len(t) != 0; len(t) = %v", len(t))
}
return v
return staticValue(n, false)

}

func staticValue(n Node, forDevirt bool) (Node, []*types.Type) {
typeAssertTypes := []*types.Type{}
func staticValue(n Node, forDevirt bool) Node {
for {
switch n1 := n.(type) {
case *ConvExpr:
Expand All @@ -898,7 +880,6 @@ func staticValue(n Node, forDevirt bool) (Node, []*types.Type) {
continue
}
if forDevirt && n1.Op() == OCONVIFACE {
typeAssertTypes = append(typeAssertTypes, n1.Type())
n = n1.X
continue
}
Expand All @@ -912,15 +893,14 @@ func staticValue(n Node, forDevirt bool) (Node, []*types.Type) {
continue
case *TypeAssertExpr:
if forDevirt && n1.Op() == ODOTTYPE {
typeAssertTypes = append(typeAssertTypes, n1.Type())
n = n1.X
continue
}
}

n1 := staticValue1(n)
if n1 == nil {
return n, typeAssertTypes
return n
}
n = n1
}
Expand Down
4 changes: 0 additions & 4 deletions src/cmd/compile/internal/typecheck/subr.go
Original file line number Diff line number Diff line change
Expand Up @@ -612,10 +612,6 @@ func Implements(t, iface *types.Type) bool {
return implements(t, iface, &missing, &have, &ptr)
}

func init() {
ir.Implements = Implements
}

// ImplementsExplain reports whether t implements the interface iface. t can be
// an interface, a type parameter, or a concrete type. If t does not implement
// iface, a non-empty string is returned explaining why.
Expand Down
4 changes: 2 additions & 2 deletions test/escape_iface_with_devirt_type_assertions.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// errorcheck -0 -m
// errorcheck -0 -m -d=testing=2

// Copyright 2025 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
Expand Down Expand Up @@ -122,7 +122,7 @@ func testInvalidAsserts() {
{
var a M = &Impl{} // ERROR "escapes"
a.(C).C() // this will panic
a.(any).(C).C() // this will panic
//a.(any).(C).C() // this will panic
}
{
var a C = &CImpl{} // ERROR "escapes"
Expand Down

0 comments on commit ff0149f

Please sign in to comment.