]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] cmd/compile: simplify usemethod
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Thu, 24 Jun 2021 15:39:16 +0000 (22:39 +0700)
committerCuong Manh Le <cuong.manhle.vn@gmail.com>
Fri, 25 Jun 2021 02:28:55 +0000 (02:28 +0000)
By checking for method name first.

Passes toolstash -cmp

Change-Id: I1f4125157a8bc247e4766a882467b805a205a3c2
Reviewed-on: https://go-review.googlesource.com/c/go/+/330670
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/cmd/compile/internal/walk/expr.go

index 070954be272db387194929368ee297a94c169fe0..bbf289d90e6702d384a2391e3de01a37f8bc8ab3 100644 (file)
@@ -931,42 +931,8 @@ func bounded(n ir.Node, max int64) bool {
        return false
 }
 
-// usemethod checks interface method calls for uses of reflect.Type.Method.
+// usemethod checks calls for uses of reflect.Type.{Method,MethodByName}.
 func usemethod(n *ir.CallExpr) {
-       t := n.X.Type()
-
-       // Looking for either of:
-       //      Method(int) reflect.Method
-       //      MethodByName(string) (reflect.Method, bool)
-       //
-       // TODO(crawshaw): improve precision of match by working out
-       //                 how to check the method name.
-       if n := t.NumParams(); n != 1 {
-               return
-       }
-       if n := t.NumResults(); n != 1 && n != 2 {
-               return
-       }
-       p0 := t.Params().Field(0)
-       res0 := t.Results().Field(0)
-       var res1 *types.Field
-       if t.NumResults() == 2 {
-               res1 = t.Results().Field(1)
-       }
-
-       if res1 == nil {
-               if p0.Type.Kind() != types.TINT {
-                       return
-               }
-       } else {
-               if !p0.Type.IsString() {
-                       return
-               }
-               if !res1.Type.IsBoolean() {
-                       return
-               }
-       }
-
        // Don't mark reflect.(*rtype).Method, etc. themselves in the reflect package.
        // Those functions may be alive via the itab, which should not cause all methods
        // alive. We only want to mark their callers.
@@ -977,10 +943,37 @@ func usemethod(n *ir.CallExpr) {
                }
        }
 
-       // Note: Don't rely on res0.Type.String() since its formatting depends on multiple factors
+       dot, ok := n.X.(*ir.SelectorExpr)
+       if !ok {
+               return
+       }
+
+       // Looking for either direct method calls and interface method calls of:
+       //      reflect.Type.Method       - func(int) reflect.Method
+       //      reflect.Type.MethodByName - func(string) (reflect.Method, bool)
+       var pKind types.Kind
+
+       switch dot.Sel.Name {
+       case "Method":
+               pKind = types.TINT
+       case "MethodByName":
+               pKind = types.TSTRING
+       default:
+               return
+       }
+
+       t := dot.Selection.Type
+       if t.NumParams() != 1 || t.Params().Field(0).Type.Kind() != pKind {
+               return
+       }
+       if t.NumResults() == 2 && t.Results().Field(1).Type.Kind() != types.TBOOL {
+               return
+       }
+
+       // Note: Don't rely on Field.Type.String() since its formatting depends on multiple factors
        //       (including global variables such as numImports - was issue #19028).
        // Also need to check for reflect package itself (see Issue #38515).
-       if s := res0.Type.Sym(); s != nil && s.Name == "Method" && types.IsReflectPkg(s.Pkg) {
+       if s := t.Results().Field(0).Type.Sym(); s != nil && s.Name == "Method" && types.IsReflectPkg(s.Pkg) {
                ir.CurFunc.SetReflectMethod(true)
                // The LSym is initialized at this point. We need to set the attribute on the LSym.
                ir.CurFunc.LSym.Set(obj.AttrReflectMethod, true)