From de2318e3c68530cd3ff6d3a1d378239598301fb0 Mon Sep 17 00:00:00 2001 From: Cherry Zhang Date: Sat, 18 Apr 2020 01:38:31 -0400 Subject: [PATCH] cmd/link: add a test that reflect.Value.Call does not bring methods live reflect.Value.Call, if reachable, used to bring all exported methods live. CL 228792 fixes this, removing the check of reflect.Value.Call. This CL adds a test. Updates #38505. Change-Id: Ib4cab3c3c86c9c9702d041266e59b159d0ff0a97 Reviewed-on: https://go-review.googlesource.com/c/go/+/228878 Reviewed-by: Brad Fitzpatrick --- src/cmd/link/internal/ld/deadcode_test.go | 61 +++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 src/cmd/link/internal/ld/deadcode_test.go diff --git a/src/cmd/link/internal/ld/deadcode_test.go b/src/cmd/link/internal/ld/deadcode_test.go new file mode 100644 index 0000000000..197a057c2f --- /dev/null +++ b/src/cmd/link/internal/ld/deadcode_test.go @@ -0,0 +1,61 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ld + +import ( + "bytes" + "internal/testenv" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "testing" +) + +// This example uses reflect.Value.Call, but not +// reflect.{Value,Type}.Method. This should not +// need to bring all methods live. +const deadcodeTestSrc = ` +package main +import "reflect" + +func f() { println("call") } + +type T int +func (T) M() {} + +func main() { + v := reflect.ValueOf(f) + v.Call(nil) + i := interface{}(T(1)) + println(i) +} +` + +func TestDeadcode(t *testing.T) { + testenv.MustHaveGoBuild(t) + + tmpdir, err := ioutil.TempDir("", "TestDeadcode") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpdir) + + src := filepath.Join(tmpdir, "main.go") + err = ioutil.WriteFile(src, []byte(deadcodeTestSrc), 0666) + if err != nil { + t.Fatal(err) + } + exe := filepath.Join(tmpdir, "main.exe") + + cmd := exec.Command(testenv.GoToolPath(t), "build", "-ldflags=-dumpdep", "-o", exe, src) + out, err := cmd.CombinedOutput() + if err != nil { + t.Fatalf("%v: %v:\n%s", cmd.Args, err, out) + } + if bytes.Contains(out, []byte("main.T.M")) { + t.Errorf("main.T.M should not be reachable. Output:\n%s", out) + } +}