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 netip
6
7import (
8	"internal/testenv"
9	"os/exec"
10	"regexp"
11	"runtime"
12	"strings"
13	"testing"
14)
15
16func TestInlining(t *testing.T) {
17	testenv.MustHaveGoBuild(t)
18	t.Parallel()
19	out, err := exec.Command(
20		testenv.GoToolPath(t),
21		"build",
22		"--gcflags=-m",
23		"net/netip").CombinedOutput()
24	if err != nil {
25		t.Fatalf("go build: %v, %s", err, out)
26	}
27	got := map[string]bool{}
28	regexp.MustCompile(` can inline (\S+)`).ReplaceAllFunc(out, func(match []byte) []byte {
29		got[strings.TrimPrefix(string(match), " can inline ")] = true
30		return nil
31	})
32	wantInlinable := []string{
33		"(*uint128).halves",
34		"Addr.BitLen",
35		"Addr.hasZone",
36		"Addr.Is4",
37		"Addr.Is4In6",
38		"Addr.Is6",
39		"Addr.IsInterfaceLocalMulticast",
40		"Addr.IsValid",
41		"Addr.IsUnspecified",
42		"Addr.Less",
43		"Addr.Unmap",
44		"Addr.Zone",
45		"Addr.v4",
46		"Addr.v6",
47		"Addr.v6u16",
48		"Addr.withoutZone",
49		"AddrPortFrom",
50		"AddrPort.Addr",
51		"AddrPort.Port",
52		"AddrPort.IsValid",
53		"Prefix.IsSingleIP",
54		"Prefix.Masked",
55		"Prefix.IsValid",
56		"PrefixFrom",
57		"Prefix.Addr",
58		"Prefix.Bits",
59		"AddrFrom4",
60		"IPv6LinkLocalAllNodes",
61		"IPv6Unspecified",
62		"MustParseAddr",
63		"MustParseAddrPort",
64		"MustParsePrefix",
65		"appendDecimal",
66		"appendHex",
67		"uint128.addOne",
68		"uint128.and",
69		"uint128.bitsClearedFrom",
70		"uint128.bitsSetFrom",
71		"uint128.isZero",
72		"uint128.not",
73		"uint128.or",
74		"uint128.subOne",
75		"uint128.xor",
76	}
77	switch runtime.GOARCH {
78	case "amd64", "arm64":
79		// These don't inline on 32-bit.
80		wantInlinable = append(wantInlinable,
81			"Addr.AsSlice",
82			"Addr.Next",
83			"Addr.Prev",
84		)
85	}
86
87	for _, want := range wantInlinable {
88		if !got[want] {
89			t.Errorf("%q is no longer inlinable", want)
90			continue
91		}
92		delete(got, want)
93	}
94	for sym := range got {
95		if strings.Contains(sym, ".func") {
96			continue
97		}
98		t.Logf("not in expected set, but also inlinable: %q", sym)
99
100	}
101}
102