cmd/compile: set LocalPkg.Path to -p flag

Since CL 391014, cmd/compile now requires the -p flag to be set the
build system. This CL changes it to initialize LocalPkg.Path to the
provided path, rather than relying on writing out `"".` into object
files and expecting cmd/link to substitute them.

However, this actually involved a rather long tail of fixes. Many have
already been submitted, but a few notable ones that have to land
simultaneously with changing LocalPkg:

1. When compiling package runtime, there are really two "runtime"
packages: types.LocalPkg (the source package itself) and
ir.Pkgs.Runtime (the compiler's internal representation, for synthetic
references). Previously, these ended up creating separate link
symbols (`"".xxx` and `runtime.xxx`, respectively), but now they both
end up as `runtime.xxx`, which causes lsym collisions (notably
inittask and funcsyms).

2. test/codegen tests need to be updated to expect symbols to be named
`command-line-arguments.xxx` rather than `"".foo`.

3. The issue20014 test case is sensitive to the sort order of field
tracking symbols. In particular, the local package now sorts to its
natural place in the list, rather than to the front.

Thanks to David Chase for helping track down all of the fixes needed
for this CL.

Updates #51734.

Change-Id: Iba3041cf7ad967d18c6e17922fa06ba11798b565
Reviewed-on: https://go-review.googlesource.com/c/go/+/393715
Reviewed-by: David Chase <drchase@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
This commit is contained in:
Matthew Dempsky 2022-03-17 13:27:40 -07:00
parent db875f4d1b
commit ab8d7dd75e
25 changed files with 100 additions and 100 deletions

View File

@ -73,8 +73,7 @@ func Main(archInit func(*ssagen.ArchInfo)) {
base.DebugSSA = ssa.PhaseOption base.DebugSSA = ssa.PhaseOption
base.ParseFlags() base.ParseFlags()
types.LocalPkg = types.NewPkg("", "") types.LocalPkg = types.NewPkg(base.Ctxt.Pkgpath, "")
types.LocalPkg.Prefix = "\"\""
// We won't know localpkg's height until after import // We won't know localpkg's height until after import
// processing. In the mean time, set to MaxPkgHeight to ensure // processing. In the mean time, set to MaxPkgHeight to ensure
@ -140,7 +139,7 @@ func Main(archInit func(*ssagen.ArchInfo)) {
types.ParseLangFlag() types.ParseLangFlag()
symABIs := ssagen.NewSymABIs(base.Ctxt.Pkgpath) symABIs := ssagen.NewSymABIs()
if base.Flag.SymABIs != "" { if base.Flag.SymABIs != "" {
symABIs.ReadSymABIs(base.Flag.SymABIs) symABIs.ReadSymABIs(base.Flag.SymABIs)
} }
@ -188,8 +187,14 @@ func Main(archInit func(*ssagen.ArchInfo)) {
// Parse and typecheck input. // Parse and typecheck input.
noder.LoadPackage(flag.Args()) noder.LoadPackage(flag.Args())
// As a convenience to users (toolchain maintainers, in particular),
// when compiling a package named "main", we default the package
// path to "main" if the -p flag was not specified.
if base.Ctxt.Pkgpath == obj.UnlinkablePkg && types.LocalPkg.Name == "main" { if base.Ctxt.Pkgpath == obj.UnlinkablePkg && types.LocalPkg.Name == "main" {
base.Ctxt.Pkgpath = "main" base.Ctxt.Pkgpath = "main"
types.LocalPkg.Path = "main"
types.LocalPkg.Prefix = "main"
} }
dwarfgen.RecordPackageName() dwarfgen.RecordPackageName()

View File

@ -20,6 +20,7 @@ import (
"cmd/internal/objabi" "cmd/internal/objabi"
"encoding/json" "encoding/json"
"fmt" "fmt"
"strings"
) )
// These modes say which kind of object file to generate. // These modes say which kind of object file to generate.
@ -279,6 +280,17 @@ func addGCLocals() {
func ggloblnod(nam *ir.Name) { func ggloblnod(nam *ir.Name) {
s := nam.Linksym() s := nam.Linksym()
// main_inittask and runtime_inittask in package runtime (and in
// test/initempty.go) aren't real variable declarations, but
// linknamed variables pointing to the compiler's generated
// .inittask symbol. The real symbol was already written out in
// pkginit.Task, so we need to avoid writing them out a second time
// here, otherwise base.Ctxt.Globl will fail.
if strings.HasSuffix(s.Name, "..inittask") && s.OnList() {
return
}
s.Gotype = reflectdata.TypeLinksym(nam.Type()) s.Gotype = reflectdata.TypeLinksym(nam.Type())
flags := 0 flags := 0
if nam.Readonly() { if nam.Readonly() {

View File

@ -44,7 +44,7 @@ func compile(t *testing.T, dirname, filename, outdirname string) string {
} }
basename := filepath.Base(filename) basename := filepath.Base(filename)
outname := filepath.Join(outdirname, basename[:len(basename)-2]+"o") outname := filepath.Join(outdirname, basename[:len(basename)-2]+"o")
cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-p=p", "-o", outname, filename) cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-p", strings.TrimSuffix(outname, ".o"), "-o", outname, filename)
cmd.Dir = dirname cmd.Dir = dirname
out, err := cmd.CombinedOutput() out, err := cmd.CombinedOutput()
if err != nil { if err != nil {

View File

@ -82,7 +82,6 @@ func unified(noders []*noder) {
base.Flag.Lang = fmt.Sprintf("go1.%d", goversion.Version) base.Flag.Lang = fmt.Sprintf("go1.%d", goversion.Version)
types.ParseLangFlag() types.ParseLangFlag()
assert(types.LocalPkg.Path == "")
types.LocalPkg.Height = 0 // reset so pkgReader.pkgIdx doesn't complain types.LocalPkg.Height = 0 // reset so pkgReader.pkgIdx doesn't complain
target := typecheck.Target target := typecheck.Target

View File

@ -224,6 +224,7 @@ func (pw *pkgWriter) pkgIdx(pkg *types2.Package) int {
case types2.Unsafe: case types2.Unsafe:
w.String("unsafe") w.String("unsafe")
default: default:
// TODO(mdempsky): Write out pkg.Path() for curpkg too.
var path string var path string
if pkg != w.p.curpkg { if pkg != w.p.curpkg {
path = pkg.Path() path = pkg.Path()

View File

@ -411,14 +411,8 @@ func dimportpath(p *types.Pkg) {
return return
} }
str := p.Path
if p == types.LocalPkg {
// Note: myimportpath != "", or else dgopkgpath won't call dimportpath.
str = base.Ctxt.Pkgpath
}
s := base.Ctxt.Lookup("type..importpath." + p.Prefix + ".") s := base.Ctxt.Lookup("type..importpath." + p.Prefix + ".")
ot := dnameData(s, 0, str, "", nil, false) ot := dnameData(s, 0, p.Path, "", nil, false)
objw.Global(s, int32(ot), obj.DUPOK|obj.RODATA) objw.Global(s, int32(ot), obj.DUPOK|obj.RODATA)
s.Set(obj.AttrContentAddressable, true) s.Set(obj.AttrContentAddressable, true)
p.Pathsym = s p.Pathsym = s

View File

@ -392,6 +392,14 @@ func (f *Func) computeZeroMap() map[ID]ZeroRegion {
for _, b := range f.Blocks { for _, b := range f.Blocks {
for _, v := range b.Values { for _, v := range b.Values {
if mem, ok := IsNewObject(v); ok { if mem, ok := IsNewObject(v); ok {
// While compiling package runtime itself, we might see user
// calls to newobject, which will have result type
// unsafe.Pointer instead. We can't easily infer how large the
// allocated memory is, so just skip it.
if types.LocalPkg.Path == "runtime" && v.Type.IsUnsafePtr() {
continue
}
nptr := v.Type.Elem().Size() / ptrSize nptr := v.Type.Elem().Size() / ptrSize
if nptr > 64 { if nptr > 64 {
nptr = 64 nptr = 64

View File

@ -17,7 +17,6 @@ import (
"cmd/compile/internal/typecheck" "cmd/compile/internal/typecheck"
"cmd/compile/internal/types" "cmd/compile/internal/types"
"cmd/internal/obj" "cmd/internal/obj"
"cmd/internal/objabi"
) )
// SymABIs records information provided by the assembler about symbol // SymABIs records information provided by the assembler about symbol
@ -25,33 +24,27 @@ import (
type SymABIs struct { type SymABIs struct {
defs map[string]obj.ABI defs map[string]obj.ABI
refs map[string]obj.ABISet refs map[string]obj.ABISet
localPrefix string
} }
func NewSymABIs(myimportpath string) *SymABIs { func NewSymABIs() *SymABIs {
var localPrefix string
if myimportpath != "" {
localPrefix = objabi.PathToPrefix(myimportpath) + "."
}
return &SymABIs{ return &SymABIs{
defs: make(map[string]obj.ABI), defs: make(map[string]obj.ABI),
refs: make(map[string]obj.ABISet), refs: make(map[string]obj.ABISet),
localPrefix: localPrefix,
} }
} }
// canonicalize returns the canonical name used for a linker symbol in // canonicalize returns the canonical name used for a linker symbol in
// s's maps. Symbols in this package may be written either as "".X or // s's maps. Symbols in this package may be written either as "".X or
// with the package's import path already in the symbol. This rewrites // with the package's import path already in the symbol. This rewrites
// both to `"".`, which matches compiler-generated linker symbol names. // both to use the full path, which matches compiler-generated linker
// symbol names.
func (s *SymABIs) canonicalize(linksym string) string { func (s *SymABIs) canonicalize(linksym string) string {
// If the symbol is already prefixed with localPrefix, // If the symbol is already prefixed with "", rewrite it to start
// rewrite it to start with "" so it matches the // with LocalPkg.Prefix.
// compiler's internal symbol names. //
if s.localPrefix != "" && strings.HasPrefix(linksym, s.localPrefix) { // TODO(mdempsky): Have cmd/asm stop writing out symbols like this.
return `"".` + linksym[len(s.localPrefix):] if strings.HasPrefix(linksym, `"".`) {
return types.LocalPkg.Prefix + linksym[2:]
} }
return linksym return linksym
} }
@ -140,13 +133,12 @@ func (s *SymABIs) GenABIWrappers() {
continue continue
} }
sym := nam.Sym() sym := nam.Sym()
var symName string
if sym.Linkname != "" { symName := sym.Linkname
symName = s.canonicalize(sym.Linkname) if symName == "" {
} else {
// These names will already be canonical.
symName = sym.Pkg.Prefix + "." + sym.Name symName = sym.Pkg.Prefix + "." + sym.Name
} }
symName = s.canonicalize(symName)
// Apply definitions. // Apply definitions.
defABI, hasDefABI := s.defs[symName] defABI, hasDefABI := s.defs[symName]

View File

@ -266,6 +266,14 @@ func WriteFuncSyms() {
for _, nam := range funcsyms { for _, nam := range funcsyms {
s := nam.Sym() s := nam.Sym()
sf := s.Pkg.Lookup(ir.FuncSymName(s)).Linksym() sf := s.Pkg.Lookup(ir.FuncSymName(s)).Linksym()
// While compiling package runtime, we might try to create
// funcsyms for functions from both types.LocalPkg and
// ir.Pkgs.Runtime.
if base.Flag.CompilingRuntime && sf.OnList() {
continue
}
// Function values must always reference ABIInternal // Function values must always reference ABIInternal
// entry points. // entry points.
target := s.Linksym() target := s.Linksym()

View File

@ -459,6 +459,7 @@ func StaticName(t *types.Type) *ir.Name {
statuniqgen++ statuniqgen++
typecheck.Declare(n, ir.PEXTERN) typecheck.Declare(n, ir.PEXTERN)
n.SetType(t) n.SetType(t)
n.Linksym().Set(obj.AttrStatic, true)
return n return n
} }

View File

@ -145,10 +145,6 @@ func symfmt(b *bytes.Buffer, s *Sym, verb rune, mode fmtMode) {
b.WriteString(q) b.WriteString(q)
b.WriteByte('.') b.WriteByte('.')
switch mode { switch mode {
case fmtTypeIDName:
// If name is a generic instantiation, it might have local package placeholders
// in it. Replace those placeholders with the package name. See issue 49547.
name = strings.Replace(name, LocalPkg.Prefix, q, -1)
case fmtTypeIDHash: case fmtTypeIDHash:
// If name is a generic instantiation, don't hash the instantiating types. // If name is a generic instantiation, don't hash the instantiating types.
// This isn't great, but it is safe. If we hash the instantiating types, then // This isn't great, but it is safe. If we hash the instantiating types, then
@ -261,24 +257,13 @@ func (t *Type) String() string {
return tconv(t, 0, fmtGo) return tconv(t, 0, fmtGo)
} }
// LinkString returns an unexpanded string description of t, suitable // LinkString returns a string description of t, suitable for use in
// for use in link symbols. "Unexpanded" here means that the // link symbols.
// description uses `"".` to qualify identifiers from the current
// package, and "expansion" refers to the renaming step performed by
// the linker to replace these qualifiers with proper `path/to/pkg.`
// qualifiers.
// //
// After expansion, the description corresponds to type identity. That // The description corresponds to type identity. That is, for any pair
// is, for any pair of types t1 and t2, Identical(t1, t2) and // of types t1 and t2, Identical(t1, t2) == (t1.LinkString() ==
// expand(t1.LinkString()) == expand(t2.LinkString()) report the same // t2.LinkString()) is true. Thus it's safe to use as a map key to
// value. // implement a type-identity-keyed map.
//
// Within a single compilation unit, LinkString always returns the
// same unexpanded description for identical types. Thus it's safe to
// use as a map key to implement a type-identity-keyed map. However,
// make sure all LinkString calls used for this purpose happen within
// the same compile process; the string keys are not stable across
// multiple processes.
func (t *Type) LinkString() string { func (t *Type) LinkString() string {
return tconv(t, 0, fmtTypeID) return tconv(t, 0, fmtTypeID)
} }

View File

@ -408,15 +408,7 @@ func (ctxt *Link) DwarfGlobal(myimportpath, typename string, varSym *LSym) {
if myimportpath == "" || varSym.Local() { if myimportpath == "" || varSym.Local() {
return return
} }
var varname string varname := varSym.Name
if varSym.Pkg == "_" {
// The frontend uses package "_" to mark symbols that should not
// be referenced by index, e.g. linkname'd symbols.
varname = varSym.Name
} else {
// Convert "".<name> into a fully qualified package.sym name.
varname = objabi.PathToPrefix(myimportpath) + varSym.Name[len(`""`):]
}
dieSymName := dwarf.InfoPrefix + varname dieSymName := dwarf.InfoPrefix + varname
dieSym := ctxt.LookupInit(dieSymName, func(s *LSym) { dieSym := ctxt.LookupInit(dieSymName, func(s *LSym) {
s.Type = objabi.SDWARFVAR s.Type = objabi.SDWARFVAR

View File

@ -904,7 +904,7 @@ type Link struct {
Flag_maymorestack string // If not "", call this function before stack checks Flag_maymorestack string // If not "", call this function before stack checks
Bso *bufio.Writer Bso *bufio.Writer
Pathname string Pathname string
Pkgpath string // the current package's import path, "" if unknown Pkgpath string // the current package's import path
hashmu sync.Mutex // protects hash, funchash hashmu sync.Mutex // protects hash, funchash
hash map[string]*LSym // name -> sym mapping hash map[string]*LSym // name -> sym mapping
funchash map[string]*LSym // name -> sym mapping for ABIInternal syms funchash map[string]*LSym // name -> sym mapping for ABIInternal syms

View File

@ -171,6 +171,7 @@ func (ctxt *Link) InitTextSym(s *LSym, flag int) {
if s.OnList() { if s.OnList() {
ctxt.Diag("symbol %s listed multiple times", s.Name) ctxt.Diag("symbol %s listed multiple times", s.Name)
} }
// TODO(mdempsky): Remove once cmd/asm stops writing "" symbols.
name := strings.Replace(s.Name, "\"\"", ctxt.Pkgpath, -1) name := strings.Replace(s.Name, "\"\"", ctxt.Pkgpath, -1)
s.Func().FuncID = objabi.GetFuncID(name, flag&WRAPPER != 0 || flag&ABIWRAPPER != 0) s.Func().FuncID = objabi.GetFuncID(name, flag&WRAPPER != 0 || flag&ABIWRAPPER != 0)
s.Func().FuncFlag = ctxt.toFuncFlag(flag) s.Func().FuncFlag = ctxt.toFuncFlag(flag)
@ -224,9 +225,6 @@ func (ctxt *Link) Globl(s *LSym, size int64, flag int) {
} else if flag&TLSBSS != 0 { } else if flag&TLSBSS != 0 {
s.Type = objabi.STLSBSS s.Type = objabi.STLSBSS
} }
if strings.HasPrefix(s.Name, "\"\"."+StaticNamePref) {
s.Set(AttrStatic, true)
}
} }
// EmitEntryLiveness generates PCDATA Progs after p to switch to the // EmitEntryLiveness generates PCDATA Progs after p to switch to the

View File

@ -9,6 +9,7 @@ import (
"bytes" "bytes"
"cmd/internal/sys" "cmd/internal/sys"
"debug/macho" "debug/macho"
"internal/buildcfg"
"internal/testenv" "internal/testenv"
"io/ioutil" "io/ioutil"
"os" "os"
@ -1077,6 +1078,10 @@ func TestUnlinkableObj(t *testing.T) {
testenv.MustHaveGoBuild(t) testenv.MustHaveGoBuild(t)
t.Parallel() t.Parallel()
if buildcfg.Experiment.Unified {
t.Skip("TODO(mdempsky): Fix ICE when importing unlinkable objects for GOEXPERIMENT=unified")
}
tmpdir := t.TempDir() tmpdir := t.TempDir()
xSrc := filepath.Join(tmpdir, "x.go") xSrc := filepath.Join(tmpdir, "x.go")

View File

@ -51,7 +51,7 @@ func compile(t *testing.T, dirname, filename, outdirname string) string {
} }
basename := filepath.Base(filename) basename := filepath.Base(filename)
outname := filepath.Join(outdirname, basename[:len(basename)-2]+"o") outname := filepath.Join(outdirname, basename[:len(basename)-2]+"o")
cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-p=p", "-o", outname, filename) cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-p", strings.TrimSuffix(outname, ".o"), "-o", outname, filename)
cmd.Dir = dirname cmd.Dir = dirname
out, err := cmd.CombinedOutput() out, err := cmd.CombinedOutput()
if err != nil { if err != nil {

View File

@ -974,8 +974,8 @@ var nameTests = []nameTest{
F() F()
})(nil), ""}, })(nil), ""},
{(*TheNameOfThisTypeIsExactly255BytesLongSoWhenTheCompilerPrependsTheReflectTestPackageNameAndExtraStarTheLinkerRuntimeAndReflectPackagesWillHaveToCorrectlyDecodeTheSecondLengthByte0123456789_0123456789_0123456789_0123456789_0123456789_012345678)(nil), "TheNameOfThisTypeIsExactly255BytesLongSoWhenTheCompilerPrependsTheReflectTestPackageNameAndExtraStarTheLinkerRuntimeAndReflectPackagesWillHaveToCorrectlyDecodeTheSecondLengthByte0123456789_0123456789_0123456789_0123456789_0123456789_012345678"}, {(*TheNameOfThisTypeIsExactly255BytesLongSoWhenTheCompilerPrependsTheReflectTestPackageNameAndExtraStarTheLinkerRuntimeAndReflectPackagesWillHaveToCorrectlyDecodeTheSecondLengthByte0123456789_0123456789_0123456789_0123456789_0123456789_012345678)(nil), "TheNameOfThisTypeIsExactly255BytesLongSoWhenTheCompilerPrependsTheReflectTestPackageNameAndExtraStarTheLinkerRuntimeAndReflectPackagesWillHaveToCorrectlyDecodeTheSecondLengthByte0123456789_0123456789_0123456789_0123456789_0123456789_012345678"},
{(*B[A])(nil), "B[reflectlite_test.A]"}, {(*B[A])(nil), "B[internal/reflectlite_test.A]"},
{(*B[B[A]])(nil), "B[reflectlite_test.B[reflectlite_test.A]]"}, {(*B[B[A]])(nil), "B[internal/reflectlite_test.B[internal/reflectlite_test.A]]"},
} }
func TestNames(t *testing.T) { func TestNames(t *testing.T) {

View File

@ -15,16 +15,16 @@ var p1, p2, p3 T
func F() { func F() {
// 3735936685 is 0xdeaddead. On ARM64 R27 is REGTMP. // 3735936685 is 0xdeaddead. On ARM64 R27 is REGTMP.
// clobber x, y at entry. not clobber z (stack object). // clobber x, y at entry. not clobber z (stack object).
// amd64:`MOVL\t\$3735936685, ""\.x`, `MOVL\t\$3735936685, ""\.y`, -`MOVL\t\$3735936685, ""\.z` // amd64:`MOVL\t\$3735936685, command-line-arguments\.x`, `MOVL\t\$3735936685, command-line-arguments\.y`, -`MOVL\t\$3735936685, command-line-arguments\.z`
// arm64:`MOVW\tR27, ""\.x`, `MOVW\tR27, ""\.y`, -`MOVW\tR27, ""\.z` // arm64:`MOVW\tR27, command-line-arguments\.x`, `MOVW\tR27, command-line-arguments\.y`, -`MOVW\tR27, command-line-arguments\.z`
x, y, z := p1, p2, p3 x, y, z := p1, p2, p3
addrTaken(&z) addrTaken(&z)
// x is dead at the call (the value of x is loaded before the CALL), y is not // x is dead at the call (the value of x is loaded before the CALL), y is not
// amd64:`MOVL\t\$3735936685, ""\.x`, -`MOVL\t\$3735936685, ""\.y` // amd64:`MOVL\t\$3735936685, command-line-arguments\.x`, -`MOVL\t\$3735936685, command-line-arguments\.y`
// arm64:`MOVW\tR27, ""\.x`, -`MOVW\tR27, ""\.y` // arm64:`MOVW\tR27, command-line-arguments\.x`, -`MOVW\tR27, command-line-arguments\.y`
use(x) use(x)
// amd64:`MOVL\t\$3735936685, ""\.x`, `MOVL\t\$3735936685, ""\.y` // amd64:`MOVL\t\$3735936685, command-line-arguments\.x`, `MOVL\t\$3735936685, command-line-arguments\.y`
// arm64:`MOVW\tR27, ""\.x`, `MOVW\tR27, ""\.y` // arm64:`MOVW\tR27, command-line-arguments\.x`, `MOVW\tR27, command-line-arguments\.y`
use(y) use(y)
} }

View File

@ -45,7 +45,7 @@ func CompareString3(s string) bool {
// Check that arrays compare use 2/4/8 byte compares // Check that arrays compare use 2/4/8 byte compares
func CompareArray1(a, b [2]byte) bool { func CompareArray1(a, b [2]byte) bool {
// amd64:`CMPW\t""[.+_a-z0-9]+\(SP\), [A-Z]` // amd64:`CMPW\tcommand-line-arguments[.+_a-z0-9]+\(SP\), [A-Z]`
// arm64:-`MOVBU\t` // arm64:-`MOVBU\t`
// ppc64le:-`MOVBZ\t` // ppc64le:-`MOVBZ\t`
// s390x:-`MOVBZ\t` // s390x:-`MOVBZ\t`
@ -53,25 +53,25 @@ func CompareArray1(a, b [2]byte) bool {
} }
func CompareArray2(a, b [3]uint16) bool { func CompareArray2(a, b [3]uint16) bool {
// amd64:`CMPL\t""[.+_a-z0-9]+\(SP\), [A-Z]` // amd64:`CMPL\tcommand-line-arguments[.+_a-z0-9]+\(SP\), [A-Z]`
// amd64:`CMPW\t""[.+_a-z0-9]+\(SP\), [A-Z]` // amd64:`CMPW\tcommand-line-arguments[.+_a-z0-9]+\(SP\), [A-Z]`
return a == b return a == b
} }
func CompareArray3(a, b [3]int16) bool { func CompareArray3(a, b [3]int16) bool {
// amd64:`CMPL\t""[.+_a-z0-9]+\(SP\), [A-Z]` // amd64:`CMPL\tcommand-line-arguments[.+_a-z0-9]+\(SP\), [A-Z]`
// amd64:`CMPW\t""[.+_a-z0-9]+\(SP\), [A-Z]` // amd64:`CMPW\tcommand-line-arguments[.+_a-z0-9]+\(SP\), [A-Z]`
return a == b return a == b
} }
func CompareArray4(a, b [12]int8) bool { func CompareArray4(a, b [12]int8) bool {
// amd64:`CMPQ\t""[.+_a-z0-9]+\(SP\), [A-Z]` // amd64:`CMPQ\tcommand-line-arguments[.+_a-z0-9]+\(SP\), [A-Z]`
// amd64:`CMPL\t""[.+_a-z0-9]+\(SP\), [A-Z]` // amd64:`CMPL\tcommand-line-arguments[.+_a-z0-9]+\(SP\), [A-Z]`
return a == b return a == b
} }
func CompareArray5(a, b [15]byte) bool { func CompareArray5(a, b [15]byte) bool {
// amd64:`CMPQ\t""[.+_a-z0-9]+\(SP\), [A-Z]` // amd64:`CMPQ\tcommand-line-arguments[.+_a-z0-9]+\(SP\), [A-Z]`
return a == b return a == b
} }

View File

@ -335,7 +335,7 @@ func load_op_no_merge(p, q *int) {
// Make sure offsets are folded into loads and stores. // Make sure offsets are folded into loads and stores.
func offsets_fold(_, a [20]byte) (b [20]byte) { func offsets_fold(_, a [20]byte) (b [20]byte) {
// arm64:`MOVD\t""\.a\+[0-9]+\(FP\), R[0-9]+`,`MOVD\tR[0-9]+, ""\.b\+[0-9]+\(FP\)` // arm64:`MOVD\tcommand-line-arguments\.a\+[0-9]+\(FP\), R[0-9]+`,`MOVD\tR[0-9]+, command-line-arguments\.b\+[0-9]+\(FP\)`
b = a b = a
return return
} }

View File

@ -13,23 +13,23 @@ var x32 [2]uint32
var x64 [2]uint64 var x64 [2]uint64
func compMem1() int { func compMem1() int {
// amd64:`CMPB\t"".x\+1\(SB\), [$]0` // amd64:`CMPB\tcommand-line-arguments.x\+1\(SB\), [$]0`
if x[1] { if x[1] {
return 1 return 1
} }
// amd64:`CMPB\t"".x8\+1\(SB\), [$]7` // amd64:`CMPB\tcommand-line-arguments.x8\+1\(SB\), [$]7`
if x8[1] == 7 { if x8[1] == 7 {
return 1 return 1
} }
// amd64:`CMPW\t"".x16\+2\(SB\), [$]7` // amd64:`CMPW\tcommand-line-arguments.x16\+2\(SB\), [$]7`
if x16[1] == 7 { if x16[1] == 7 {
return 1 return 1
} }
// amd64:`CMPL\t"".x32\+4\(SB\), [$]7` // amd64:`CMPL\tcommand-line-arguments.x32\+4\(SB\), [$]7`
if x32[1] == 7 { if x32[1] == 7 {
return 1 return 1
} }
// amd64:`CMPQ\t"".x64\+8\(SB\), [$]7` // amd64:`CMPQ\tcommand-line-arguments.x64\+8\(SB\), [$]7`
if x64[1] == 7 { if x64[1] == 7 {
return 1 return 1
} }

View File

@ -10,7 +10,7 @@ func f() {
ch1 := make(chan int) ch1 := make(chan int)
ch2 := make(chan int) ch2 := make(chan int)
for { for {
// amd64:-`MOVQ\t[$]0, ""..autotmp_3` // amd64:-`MOVQ\t[$]0, command-line-arguments..autotmp_3`
select { select {
case <-ch1: case <-ch1:
case <-ch2: case <-ch2:

View File

@ -12,12 +12,12 @@ package codegen
func zeroSize() { func zeroSize() {
c := make(chan struct{}) c := make(chan struct{})
// amd64:`MOVQ\t\$0, ""\.s\+56\(SP\)` // amd64:`MOVQ\t\$0, command-line-arguments\.s\+56\(SP\)`
var s *int var s *int
// force s to be a stack object, also use some (fixed) stack space // force s to be a stack object, also use some (fixed) stack space
g(&s, 1, 2, 3, 4, 5) g(&s, 1, 2, 3, 4, 5)
// amd64:`LEAQ\t""\..*\+55\(SP\)` // amd64:`LEAQ\tcommand-line-arguments\..*\+55\(SP\)`
c <- struct{}{} c <- struct{}{}
} }

View File

@ -2,5 +2,5 @@
0 0
0 0
0 0
main.T.X
issue20014.dir/a.T.X issue20014.dir/a.T.X
main.T.X

View File

@ -32,10 +32,10 @@ func main() {
// 6g/8g print the offset as dec, but 5g/9g print the offset as hex. // 6g/8g print the offset as dec, but 5g/9g print the offset as hex.
patterns := []string{ patterns := []string{
`rel 0\+\d t=1 \"\"\.x\+8\r?\n`, // y = &x.b `rel 0\+\d t=1 p\.x\+8\r?\n`, // y = &x.b
`rel 0\+\d t=1 \"\"\.x\+(28|1c)\r?\n`, // z = &x.d.q `rel 0\+\d t=1 p\.x\+(28|1c)\r?\n`, // z = &x.d.q
`rel 0\+\d t=1 \"\"\.b\+5\r?\n`, // c = &b[5] `rel 0\+\d t=1 p\.b\+5\r?\n`, // c = &b[5]
`rel 0\+\d t=1 \"\"\.x\+(88|58)\r?\n`, // w = &x.f[3].r `rel 0\+\d t=1 p\.x\+(88|58)\r?\n`, // w = &x.f[3].r
} }
for _, p := range patterns { for _, p := range patterns {
if ok, err := regexp.Match(p, out); !ok || err != nil { if ok, err := regexp.Match(p, out); !ok || err != nil {