1// Copyright 2020 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package big
6
7import (
8	"bytes"
9	"internal/testenv"
10	"os"
11	"os/exec"
12	"path/filepath"
13	"testing"
14)
15
16// Tests that the linker is able to remove references to Float, Rat,
17// and Int if unused (notably, not used by init).
18func TestLinkerGC(t *testing.T) {
19	if testing.Short() {
20		t.Skip("skipping in short mode")
21	}
22	t.Parallel()
23	tmp := t.TempDir()
24	goBin := testenv.GoToolPath(t)
25	goFile := filepath.Join(tmp, "x.go")
26	file := []byte(`package main
27import _ "math/big"
28func main() {}
29`)
30	if err := os.WriteFile(goFile, file, 0644); err != nil {
31		t.Fatal(err)
32	}
33	cmd := exec.Command(goBin, "build", "-o", "x.exe", "x.go")
34	cmd.Dir = tmp
35	if out, err := cmd.CombinedOutput(); err != nil {
36		t.Fatalf("compile: %v, %s", err, out)
37	}
38
39	cmd = exec.Command(goBin, "tool", "nm", "x.exe")
40	cmd.Dir = tmp
41	nm, err := cmd.CombinedOutput()
42	if err != nil {
43		t.Fatalf("nm: %v, %s", err, nm)
44	}
45	const want = "runtime.main"
46	if !bytes.Contains(nm, []byte(want)) {
47		// Test the test.
48		t.Errorf("expected symbol %q not found", want)
49	}
50	bad := []string{
51		"math/big.(*Float)",
52		"math/big.(*Rat)",
53		"math/big.(*Int)",
54	}
55	for _, sym := range bad {
56		if bytes.Contains(nm, []byte(sym)) {
57			t.Errorf("unexpected symbol %q found", sym)
58		}
59	}
60	if t.Failed() {
61		t.Logf("Got: %s", nm)
62	}
63}
64