mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.regabi] cmd/compile: introduce cmd/compile/internal/base [generated]
Move Flag, Debug, Ctxt, Exit, and error messages to
new package cmd/compile/internal/base.
These are the core functionality that everything in gc uses
and which otherwise prevent splitting any other code
out of gc into different packages.
A minor milestone: the compiler source code
no longer contains the string "yy".
[git-generate]
cd src/cmd/compile/internal/gc
rf '
mv atExit AtExit
mv Ctxt atExitFuncs AtExit Exit base.go
mv lineno Pos
mv linestr FmtPos
mv flusherrors FlushErrors
mv yyerror Errorf
mv yyerrorl ErrorfAt
mv yyerrorv ErrorfVers
mv noder.yyerrorpos noder.errorAt
mv Warnl WarnfAt
mv errorexit ErrorExit
mv base.go debug.go flag.go print.go cmd/compile/internal/base
'
: # update comments
sed -i '' 's/yyerrorl/ErrorfAt/g; s/yyerror/Errorf/g' *.go
: # bootstrap.go is not built by default so invisible to rf
sed -i '' 's/Fatalf/base.Fatalf/' bootstrap.go
goimports -w bootstrap.go
: # update cmd/dist to add internal/base
cd ../../../dist
sed -i '' '/internal.amd64/a\
"cmd/compile/internal/base",
' buildtool.go
gofmt -w buildtool.go
Change-Id: I59903c7084222d6eaee38823fd222159ba24a31a
Reviewed-on: https://go-review.googlesource.com/c/go/+/272250
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
eb3086e5a8
commit
26b66fd60b
67 changed files with 1626 additions and 1542 deletions
|
|
@ -5,6 +5,7 @@
|
||||||
package amd64
|
package amd64
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/gc"
|
"cmd/compile/internal/gc"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
"cmd/internal/obj/x86"
|
"cmd/internal/obj/x86"
|
||||||
|
|
@ -64,7 +65,7 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, state *uint32) *obj.Pr
|
||||||
if cnt%int64(gc.Widthreg) != 0 {
|
if cnt%int64(gc.Widthreg) != 0 {
|
||||||
// should only happen with nacl
|
// should only happen with nacl
|
||||||
if cnt%int64(gc.Widthptr) != 0 {
|
if cnt%int64(gc.Widthptr) != 0 {
|
||||||
gc.Fatalf("zerorange count not a multiple of widthptr %d", cnt)
|
base.Fatalf("zerorange count not a multiple of widthptr %d", cnt)
|
||||||
}
|
}
|
||||||
if *state&ax == 0 {
|
if *state&ax == 0 {
|
||||||
p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0)
|
p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0)
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/gc"
|
"cmd/compile/internal/gc"
|
||||||
"cmd/compile/internal/logopt"
|
"cmd/compile/internal/logopt"
|
||||||
"cmd/compile/internal/ssa"
|
"cmd/compile/internal/ssa"
|
||||||
|
|
@ -975,7 +976,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
r := v.Reg()
|
r := v.Reg()
|
||||||
// See the comments in cmd/internal/obj/x86/obj6.go
|
// See the comments in cmd/internal/obj/x86/obj6.go
|
||||||
// near CanUse1InsnTLS for a detailed explanation of these instructions.
|
// near CanUse1InsnTLS for a detailed explanation of these instructions.
|
||||||
if x86.CanUse1InsnTLS(gc.Ctxt) {
|
if x86.CanUse1InsnTLS(base.Ctxt) {
|
||||||
// MOVQ (TLS), r
|
// MOVQ (TLS), r
|
||||||
p := s.Prog(x86.AMOVQ)
|
p := s.Prog(x86.AMOVQ)
|
||||||
p.From.Type = obj.TYPE_MEM
|
p.From.Type = obj.TYPE_MEM
|
||||||
|
|
@ -1017,7 +1018,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
}
|
}
|
||||||
p := s.Prog(mov)
|
p := s.Prog(mov)
|
||||||
p.From.Type = obj.TYPE_ADDR
|
p.From.Type = obj.TYPE_ADDR
|
||||||
p.From.Offset = -gc.Ctxt.FixedFrameSize() // 0 on amd64, just to be consistent with other architectures
|
p.From.Offset = -base.Ctxt.FixedFrameSize() // 0 on amd64, just to be consistent with other architectures
|
||||||
p.From.Name = obj.NAME_PARAM
|
p.From.Name = obj.NAME_PARAM
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = v.Reg()
|
p.To.Reg = v.Reg()
|
||||||
|
|
@ -1164,8 +1165,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
if logopt.Enabled() {
|
if logopt.Enabled() {
|
||||||
logopt.LogOpt(v.Pos, "nilcheck", "genssa", v.Block.Func.Name)
|
logopt.LogOpt(v.Pos, "nilcheck", "genssa", v.Block.Func.Name)
|
||||||
}
|
}
|
||||||
if gc.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
|
if base.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
|
||||||
gc.Warnl(v.Pos, "generated nil check")
|
base.WarnfAt(v.Pos, "generated nil check")
|
||||||
}
|
}
|
||||||
case ssa.OpAMD64MOVBatomicload, ssa.OpAMD64MOVLatomicload, ssa.OpAMD64MOVQatomicload:
|
case ssa.OpAMD64MOVBatomicload, ssa.OpAMD64MOVLatomicload, ssa.OpAMD64MOVQatomicload:
|
||||||
p := s.Prog(v.Op.Asm())
|
p := s.Prog(v.Op.Asm())
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"math"
|
"math"
|
||||||
"math/bits"
|
"math/bits"
|
||||||
|
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/gc"
|
"cmd/compile/internal/gc"
|
||||||
"cmd/compile/internal/logopt"
|
"cmd/compile/internal/logopt"
|
||||||
"cmd/compile/internal/ssa"
|
"cmd/compile/internal/ssa"
|
||||||
|
|
@ -741,8 +742,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
if logopt.Enabled() {
|
if logopt.Enabled() {
|
||||||
logopt.LogOpt(v.Pos, "nilcheck", "genssa", v.Block.Func.Name)
|
logopt.LogOpt(v.Pos, "nilcheck", "genssa", v.Block.Func.Name)
|
||||||
}
|
}
|
||||||
if gc.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
|
if base.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
|
||||||
gc.Warnl(v.Pos, "generated nil check")
|
base.WarnfAt(v.Pos, "generated nil check")
|
||||||
}
|
}
|
||||||
case ssa.OpARMLoweredZero:
|
case ssa.OpARMLoweredZero:
|
||||||
// MOVW.P Rarg2, 4(R1)
|
// MOVW.P Rarg2, 4(R1)
|
||||||
|
|
@ -849,7 +850,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
// caller's SP is FixedFrameSize below the address of the first arg
|
// caller's SP is FixedFrameSize below the address of the first arg
|
||||||
p := s.Prog(arm.AMOVW)
|
p := s.Prog(arm.AMOVW)
|
||||||
p.From.Type = obj.TYPE_ADDR
|
p.From.Type = obj.TYPE_ADDR
|
||||||
p.From.Offset = -gc.Ctxt.FixedFrameSize()
|
p.From.Offset = -base.Ctxt.FixedFrameSize()
|
||||||
p.From.Name = obj.NAME_PARAM
|
p.From.Name = obj.NAME_PARAM
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = v.Reg()
|
p.To.Reg = v.Reg()
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ package arm64
|
||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/gc"
|
"cmd/compile/internal/gc"
|
||||||
"cmd/compile/internal/logopt"
|
"cmd/compile/internal/logopt"
|
||||||
"cmd/compile/internal/ssa"
|
"cmd/compile/internal/ssa"
|
||||||
|
|
@ -1038,8 +1039,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
if logopt.Enabled() {
|
if logopt.Enabled() {
|
||||||
logopt.LogOpt(v.Pos, "nilcheck", "genssa", v.Block.Func.Name)
|
logopt.LogOpt(v.Pos, "nilcheck", "genssa", v.Block.Func.Name)
|
||||||
}
|
}
|
||||||
if gc.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Line==1 in generated wrappers
|
if base.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Line==1 in generated wrappers
|
||||||
gc.Warnl(v.Pos, "generated nil check")
|
base.WarnfAt(v.Pos, "generated nil check")
|
||||||
}
|
}
|
||||||
case ssa.OpARM64Equal,
|
case ssa.OpARM64Equal,
|
||||||
ssa.OpARM64NotEqual,
|
ssa.OpARM64NotEqual,
|
||||||
|
|
@ -1068,7 +1069,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
// caller's SP is FixedFrameSize below the address of the first arg
|
// caller's SP is FixedFrameSize below the address of the first arg
|
||||||
p := s.Prog(arm64.AMOVD)
|
p := s.Prog(arm64.AMOVD)
|
||||||
p.From.Type = obj.TYPE_ADDR
|
p.From.Type = obj.TYPE_ADDR
|
||||||
p.From.Offset = -gc.Ctxt.FixedFrameSize()
|
p.From.Offset = -base.Ctxt.FixedFrameSize()
|
||||||
p.From.Name = obj.NAME_PARAM
|
p.From.Name = obj.NAME_PARAM
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = v.Reg()
|
p.To.Reg = v.Reg()
|
||||||
|
|
|
||||||
28
src/cmd/compile/internal/base/base.go
Normal file
28
src/cmd/compile/internal/base/base.go
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
// Copyright 2009 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 base
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"cmd/internal/obj"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Ctxt *obj.Link
|
||||||
|
|
||||||
|
var atExitFuncs []func()
|
||||||
|
|
||||||
|
func AtExit(f func()) {
|
||||||
|
atExitFuncs = append(atExitFuncs, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Exit(code int) {
|
||||||
|
for i := len(atExitFuncs) - 1; i >= 0; i-- {
|
||||||
|
f := atExitFuncs[i]
|
||||||
|
atExitFuncs = atExitFuncs[:i]
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
os.Exit(code)
|
||||||
|
}
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
// Debug arguments, set by -d flag.
|
// Debug arguments, set by -d flag.
|
||||||
|
|
||||||
package gc
|
package base
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package gc
|
package base
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
@ -13,7 +13,6 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
|
|
@ -2,16 +2,17 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package gc
|
package base
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"cmd/internal/objabi"
|
|
||||||
"cmd/internal/src"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"cmd/internal/objabi"
|
||||||
|
"cmd/internal/src"
|
||||||
)
|
)
|
||||||
|
|
||||||
// An errorMsg is a queued error message, waiting to be printed.
|
// An errorMsg is a queued error message, waiting to be printed.
|
||||||
|
|
@ -22,7 +23,7 @@ type errorMsg struct {
|
||||||
|
|
||||||
// Pos is the current source position being processed,
|
// Pos is the current source position being processed,
|
||||||
// printed by Errorf, ErrorfLang, Fatalf, and Warnf.
|
// printed by Errorf, ErrorfLang, Fatalf, and Warnf.
|
||||||
var lineno src.XPos
|
var Pos src.XPos
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errorMsgs []errorMsg
|
errorMsgs []errorMsg
|
||||||
|
|
@ -46,7 +47,7 @@ func addErrorMsg(pos src.XPos, format string, args ...interface{}) {
|
||||||
// Only add the position if know the position.
|
// Only add the position if know the position.
|
||||||
// See issue golang.org/issue/11361.
|
// See issue golang.org/issue/11361.
|
||||||
if pos.IsKnown() {
|
if pos.IsKnown() {
|
||||||
msg = fmt.Sprintf("%v: %s", linestr(pos), msg)
|
msg = fmt.Sprintf("%v: %s", FmtPos(pos), msg)
|
||||||
}
|
}
|
||||||
errorMsgs = append(errorMsgs, errorMsg{
|
errorMsgs = append(errorMsgs, errorMsg{
|
||||||
pos: pos,
|
pos: pos,
|
||||||
|
|
@ -55,7 +56,7 @@ func addErrorMsg(pos src.XPos, format string, args ...interface{}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FmtPos formats pos as a file:line string.
|
// FmtPos formats pos as a file:line string.
|
||||||
func linestr(pos src.XPos) string {
|
func FmtPos(pos src.XPos) string {
|
||||||
if Ctxt == nil {
|
if Ctxt == nil {
|
||||||
return "???"
|
return "???"
|
||||||
}
|
}
|
||||||
|
|
@ -71,7 +72,7 @@ func (x byPos) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
||||||
|
|
||||||
// FlushErrors sorts errors seen so far by line number, prints them to stdout,
|
// FlushErrors sorts errors seen so far by line number, prints them to stdout,
|
||||||
// and empties the errors array.
|
// and empties the errors array.
|
||||||
func flusherrors() {
|
func FlushErrors() {
|
||||||
Ctxt.Bso.Flush()
|
Ctxt.Bso.Flush()
|
||||||
if len(errorMsgs) == 0 {
|
if len(errorMsgs) == 0 {
|
||||||
return
|
return
|
||||||
|
|
@ -101,12 +102,12 @@ func sameline(a, b src.XPos) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Errorf reports a formatted error at the current line.
|
// Errorf reports a formatted error at the current line.
|
||||||
func yyerror(format string, args ...interface{}) {
|
func Errorf(format string, args ...interface{}) {
|
||||||
yyerrorl(lineno, format, args...)
|
ErrorfAt(Pos, format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ErrorfAt reports a formatted error message at pos.
|
// ErrorfAt reports a formatted error message at pos.
|
||||||
func yyerrorl(pos src.XPos, format string, args ...interface{}) {
|
func ErrorfAt(pos src.XPos, format string, args ...interface{}) {
|
||||||
msg := fmt.Sprintf(format, args...)
|
msg := fmt.Sprintf(format, args...)
|
||||||
|
|
||||||
if strings.HasPrefix(msg, "syntax error") {
|
if strings.HasPrefix(msg, "syntax error") {
|
||||||
|
|
@ -134,15 +135,15 @@ func yyerrorl(pos src.XPos, format string, args ...interface{}) {
|
||||||
|
|
||||||
hcrash()
|
hcrash()
|
||||||
if numErrors >= 10 && Flag.LowerE == 0 {
|
if numErrors >= 10 && Flag.LowerE == 0 {
|
||||||
flusherrors()
|
FlushErrors()
|
||||||
fmt.Printf("%v: too many errors\n", linestr(pos))
|
fmt.Printf("%v: too many errors\n", FmtPos(pos))
|
||||||
errorexit()
|
ErrorExit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ErrorfVers reports that a language feature (format, args) requires a later version of Go.
|
// ErrorfVers reports that a language feature (format, args) requires a later version of Go.
|
||||||
func yyerrorv(lang string, format string, args ...interface{}) {
|
func ErrorfVers(lang string, format string, args ...interface{}) {
|
||||||
yyerror("%s requires %s or later (-lang was set to %s; check go.mod)", fmt.Sprintf(format, args...), lang, Flag.Lang)
|
Errorf("%s requires %s or later (-lang was set to %s; check go.mod)", fmt.Sprintf(format, args...), lang, Flag.Lang)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateErrorDot is a clumsy hack that rewrites the last error,
|
// UpdateErrorDot is a clumsy hack that rewrites the last error,
|
||||||
|
|
@ -163,17 +164,17 @@ func UpdateErrorDot(line string, name, expr string) {
|
||||||
// so this should be used only when the user has opted in
|
// so this should be used only when the user has opted in
|
||||||
// to additional output by setting a particular flag.
|
// to additional output by setting a particular flag.
|
||||||
func Warn(format string, args ...interface{}) {
|
func Warn(format string, args ...interface{}) {
|
||||||
Warnl(lineno, format, args...)
|
WarnfAt(Pos, format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WarnfAt reports a formatted warning at pos.
|
// WarnfAt reports a formatted warning at pos.
|
||||||
// In general the Go compiler does NOT generate warnings,
|
// In general the Go compiler does NOT generate warnings,
|
||||||
// so this should be used only when the user has opted in
|
// so this should be used only when the user has opted in
|
||||||
// to additional output by setting a particular flag.
|
// to additional output by setting a particular flag.
|
||||||
func Warnl(pos src.XPos, format string, args ...interface{}) {
|
func WarnfAt(pos src.XPos, format string, args ...interface{}) {
|
||||||
addErrorMsg(pos, format, args...)
|
addErrorMsg(pos, format, args...)
|
||||||
if Flag.LowerM != 0 {
|
if Flag.LowerM != 0 {
|
||||||
flusherrors()
|
FlushErrors()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -190,7 +191,7 @@ func Warnl(pos src.XPos, format string, args ...interface{}) {
|
||||||
//
|
//
|
||||||
// If -h has been specified, Fatalf panics to force the usual runtime info dump.
|
// If -h has been specified, Fatalf panics to force the usual runtime info dump.
|
||||||
func Fatalf(format string, args ...interface{}) {
|
func Fatalf(format string, args ...interface{}) {
|
||||||
FatalfAt(lineno, format, args...)
|
FatalfAt(Pos, format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FatalfAt reports a fatal error - an internal problem - at pos and exits.
|
// FatalfAt reports a fatal error - an internal problem - at pos and exits.
|
||||||
|
|
@ -206,10 +207,10 @@ func Fatalf(format string, args ...interface{}) {
|
||||||
//
|
//
|
||||||
// If -h has been specified, FatalfAt panics to force the usual runtime info dump.
|
// If -h has been specified, FatalfAt panics to force the usual runtime info dump.
|
||||||
func FatalfAt(pos src.XPos, format string, args ...interface{}) {
|
func FatalfAt(pos src.XPos, format string, args ...interface{}) {
|
||||||
flusherrors()
|
FlushErrors()
|
||||||
|
|
||||||
if Debug.Panic != 0 || numErrors == 0 {
|
if Debug.Panic != 0 || numErrors == 0 {
|
||||||
fmt.Printf("%v: internal compiler error: ", linestr(pos))
|
fmt.Printf("%v: internal compiler error: ", FmtPos(pos))
|
||||||
fmt.Printf(format, args...)
|
fmt.Printf(format, args...)
|
||||||
fmt.Printf("\n")
|
fmt.Printf("\n")
|
||||||
|
|
||||||
|
|
@ -227,13 +228,13 @@ func FatalfAt(pos src.XPos, format string, args ...interface{}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
hcrash()
|
hcrash()
|
||||||
errorexit()
|
ErrorExit()
|
||||||
}
|
}
|
||||||
|
|
||||||
// hcrash crashes the compiler when -h is set, to find out where a message is generated.
|
// hcrash crashes the compiler when -h is set, to find out where a message is generated.
|
||||||
func hcrash() {
|
func hcrash() {
|
||||||
if Flag.LowerH != 0 {
|
if Flag.LowerH != 0 {
|
||||||
flusherrors()
|
FlushErrors()
|
||||||
if Flag.LowerO != "" {
|
if Flag.LowerO != "" {
|
||||||
os.Remove(Flag.LowerO)
|
os.Remove(Flag.LowerO)
|
||||||
}
|
}
|
||||||
|
|
@ -243,8 +244,8 @@ func hcrash() {
|
||||||
|
|
||||||
// ErrorExit handles an error-status exit.
|
// ErrorExit handles an error-status exit.
|
||||||
// It flushes any pending errors, removes the output file, and exits.
|
// It flushes any pending errors, removes the output file, and exits.
|
||||||
func errorexit() {
|
func ErrorExit() {
|
||||||
flusherrors()
|
FlushErrors()
|
||||||
if Flag.LowerO != "" {
|
if Flag.LowerO != "" {
|
||||||
os.Remove(Flag.LowerO)
|
os.Remove(Flag.LowerO)
|
||||||
}
|
}
|
||||||
|
|
@ -254,6 +255,6 @@ func errorexit() {
|
||||||
// ExitIfErrors calls ErrorExit if any errors have been reported.
|
// ExitIfErrors calls ErrorExit if any errors have been reported.
|
||||||
func ExitIfErrors() {
|
func ExitIfErrors() {
|
||||||
if Errors() > 0 {
|
if Errors() > 0 {
|
||||||
errorexit()
|
ErrorExit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
@ -203,7 +204,7 @@ func algtype1(t *types.Type) (AlgKind, *types.Type) {
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
Fatalf("algtype1: unexpected type %v", t)
|
base.Fatalf("algtype1: unexpected type %v", t)
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -214,7 +215,7 @@ func genhash(t *types.Type) *obj.LSym {
|
||||||
switch algtype(t) {
|
switch algtype(t) {
|
||||||
default:
|
default:
|
||||||
// genhash is only called for types that have equality
|
// genhash is only called for types that have equality
|
||||||
Fatalf("genhash %v", t)
|
base.Fatalf("genhash %v", t)
|
||||||
case AMEM0:
|
case AMEM0:
|
||||||
return sysClosure("memhash0")
|
return sysClosure("memhash0")
|
||||||
case AMEM8:
|
case AMEM8:
|
||||||
|
|
@ -282,11 +283,11 @@ func genhash(t *types.Type) *obj.LSym {
|
||||||
}
|
}
|
||||||
|
|
||||||
sym := typesymprefix(".hash", t)
|
sym := typesymprefix(".hash", t)
|
||||||
if Flag.LowerR != 0 {
|
if base.Flag.LowerR != 0 {
|
||||||
fmt.Printf("genhash %v %v %v\n", closure, sym, t)
|
fmt.Printf("genhash %v %v %v\n", closure, sym, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
lineno = autogeneratedPos // less confusing than end of input
|
base.Pos = autogeneratedPos // less confusing than end of input
|
||||||
dclcontext = PEXTERN
|
dclcontext = PEXTERN
|
||||||
|
|
||||||
// func sym(p *T, h uintptr) uintptr
|
// func sym(p *T, h uintptr) uintptr
|
||||||
|
|
@ -374,7 +375,7 @@ func genhash(t *types.Type) *obj.LSym {
|
||||||
r.List.Append(nh)
|
r.List.Append(nh)
|
||||||
fn.Nbody.Append(r)
|
fn.Nbody.Append(r)
|
||||||
|
|
||||||
if Flag.LowerR != 0 {
|
if base.Flag.LowerR != 0 {
|
||||||
dumplist("genhash body", fn.Nbody)
|
dumplist("genhash body", fn.Nbody)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -387,7 +388,7 @@ func genhash(t *types.Type) *obj.LSym {
|
||||||
typecheckslice(fn.Nbody.Slice(), ctxStmt)
|
typecheckslice(fn.Nbody.Slice(), ctxStmt)
|
||||||
Curfn = nil
|
Curfn = nil
|
||||||
|
|
||||||
if Debug.DclStack != 0 {
|
if base.Debug.DclStack != 0 {
|
||||||
testdclstack()
|
testdclstack()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -407,7 +408,7 @@ func hashfor(t *types.Type) *Node {
|
||||||
|
|
||||||
switch a, _ := algtype1(t); a {
|
switch a, _ := algtype1(t); a {
|
||||||
case AMEM:
|
case AMEM:
|
||||||
Fatalf("hashfor with AMEM type")
|
base.Fatalf("hashfor with AMEM type")
|
||||||
case AINTER:
|
case AINTER:
|
||||||
sym = Runtimepkg.Lookup("interhash")
|
sym = Runtimepkg.Lookup("interhash")
|
||||||
case ANILINTER:
|
case ANILINTER:
|
||||||
|
|
@ -509,13 +510,13 @@ func geneq(t *types.Type) *obj.LSym {
|
||||||
return closure
|
return closure
|
||||||
}
|
}
|
||||||
sym := typesymprefix(".eq", t)
|
sym := typesymprefix(".eq", t)
|
||||||
if Flag.LowerR != 0 {
|
if base.Flag.LowerR != 0 {
|
||||||
fmt.Printf("geneq %v\n", t)
|
fmt.Printf("geneq %v\n", t)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Autogenerate code for equality of structs and arrays.
|
// Autogenerate code for equality of structs and arrays.
|
||||||
|
|
||||||
lineno = autogeneratedPos // less confusing than end of input
|
base.Pos = autogeneratedPos // less confusing than end of input
|
||||||
dclcontext = PEXTERN
|
dclcontext = PEXTERN
|
||||||
|
|
||||||
// func sym(p, q *T) bool
|
// func sym(p, q *T) bool
|
||||||
|
|
@ -539,7 +540,7 @@ func geneq(t *types.Type) *obj.LSym {
|
||||||
// so t must be either an array or a struct.
|
// so t must be either an array or a struct.
|
||||||
switch t.Etype {
|
switch t.Etype {
|
||||||
default:
|
default:
|
||||||
Fatalf("geneq %v", t)
|
base.Fatalf("geneq %v", t)
|
||||||
|
|
||||||
case TARRAY:
|
case TARRAY:
|
||||||
nelem := t.NumElem()
|
nelem := t.NumElem()
|
||||||
|
|
@ -753,7 +754,7 @@ func geneq(t *types.Type) *obj.LSym {
|
||||||
// We should really do a generic CL that shares epilogues across
|
// We should really do a generic CL that shares epilogues across
|
||||||
// the board. See #24936.
|
// the board. See #24936.
|
||||||
|
|
||||||
if Flag.LowerR != 0 {
|
if base.Flag.LowerR != 0 {
|
||||||
dumplist("geneq body", fn.Nbody)
|
dumplist("geneq body", fn.Nbody)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -766,7 +767,7 @@ func geneq(t *types.Type) *obj.LSym {
|
||||||
typecheckslice(fn.Nbody.Slice(), ctxStmt)
|
typecheckslice(fn.Nbody.Slice(), ctxStmt)
|
||||||
Curfn = nil
|
Curfn = nil
|
||||||
|
|
||||||
if Debug.DclStack != 0 {
|
if base.Debug.DclStack != 0 {
|
||||||
testdclstack()
|
testdclstack()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -859,7 +860,7 @@ func eqstring(s, t *Node) (eqlen, eqmem *Node) {
|
||||||
// eqtab must be evaluated before eqdata, and shortcircuiting is required.
|
// eqtab must be evaluated before eqdata, and shortcircuiting is required.
|
||||||
func eqinterface(s, t *Node) (eqtab, eqdata *Node) {
|
func eqinterface(s, t *Node) (eqtab, eqdata *Node) {
|
||||||
if !types.Identical(s.Type, t.Type) {
|
if !types.Identical(s.Type, t.Type) {
|
||||||
Fatalf("eqinterface %v %v", s.Type, t.Type)
|
base.Fatalf("eqinterface %v %v", s.Type, t.Type)
|
||||||
}
|
}
|
||||||
// func ifaceeq(tab *uintptr, x, y unsafe.Pointer) (ret bool)
|
// func ifaceeq(tab *uintptr, x, y unsafe.Pointer) (ret bool)
|
||||||
// func efaceeq(typ *uintptr, x, y unsafe.Pointer) (ret bool)
|
// func efaceeq(typ *uintptr, x, y unsafe.Pointer) (ret bool)
|
||||||
|
|
@ -949,7 +950,7 @@ func memrun(t *types.Type, start int) (size int64, next int) {
|
||||||
// by padding.
|
// by padding.
|
||||||
func ispaddedfield(t *types.Type, i int) bool {
|
func ispaddedfield(t *types.Type, i int) bool {
|
||||||
if !t.IsStruct() {
|
if !t.IsStruct() {
|
||||||
Fatalf("ispaddedfield called non-struct %v", t)
|
base.Fatalf("ispaddedfield called non-struct %v", t)
|
||||||
}
|
}
|
||||||
end := t.Width
|
end := t.Width
|
||||||
if i+1 < t.NumFields() {
|
if i+1 < t.NumFields() {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
@ -21,7 +22,7 @@ var defercalc int
|
||||||
|
|
||||||
func Rnd(o int64, r int64) int64 {
|
func Rnd(o int64, r int64) int64 {
|
||||||
if r < 1 || r > 8 || r&(r-1) != 0 {
|
if r < 1 || r > 8 || r&(r-1) != 0 {
|
||||||
Fatalf("rnd %d", r)
|
base.Fatalf("rnd %d", r)
|
||||||
}
|
}
|
||||||
return (o + r - 1) &^ (r - 1)
|
return (o + r - 1) &^ (r - 1)
|
||||||
}
|
}
|
||||||
|
|
@ -39,7 +40,7 @@ func expandiface(t *types.Type) {
|
||||||
case langSupported(1, 14, t.Pkg()) && !explicit && types.Identical(m.Type, prev.Type):
|
case langSupported(1, 14, t.Pkg()) && !explicit && types.Identical(m.Type, prev.Type):
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
yyerrorl(m.Pos, "duplicate method %s", m.Sym.Name)
|
base.ErrorfAt(m.Pos, "duplicate method %s", m.Sym.Name)
|
||||||
}
|
}
|
||||||
methods = append(methods, m)
|
methods = append(methods, m)
|
||||||
}
|
}
|
||||||
|
|
@ -59,7 +60,7 @@ func expandiface(t *types.Type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !m.Type.IsInterface() {
|
if !m.Type.IsInterface() {
|
||||||
yyerrorl(m.Pos, "interface contains embedded non-interface %v", m.Type)
|
base.ErrorfAt(m.Pos, "interface contains embedded non-interface %v", m.Type)
|
||||||
m.SetBroke(true)
|
m.SetBroke(true)
|
||||||
t.SetBroke(true)
|
t.SetBroke(true)
|
||||||
// Add to fields so that error messages
|
// Add to fields so that error messages
|
||||||
|
|
@ -83,7 +84,7 @@ func expandiface(t *types.Type) {
|
||||||
sort.Sort(methcmp(methods))
|
sort.Sort(methcmp(methods))
|
||||||
|
|
||||||
if int64(len(methods)) >= thearch.MAXWIDTH/int64(Widthptr) {
|
if int64(len(methods)) >= thearch.MAXWIDTH/int64(Widthptr) {
|
||||||
yyerrorl(typePos(t), "interface too large")
|
base.ErrorfAt(typePos(t), "interface too large")
|
||||||
}
|
}
|
||||||
for i, m := range methods {
|
for i, m := range methods {
|
||||||
m.Offset = int64(i) * int64(Widthptr)
|
m.Offset = int64(i) * int64(Widthptr)
|
||||||
|
|
@ -134,7 +135,7 @@ func widstruct(errtype *types.Type, t *types.Type, o int64, flag int) int64 {
|
||||||
|
|
||||||
w := f.Type.Width
|
w := f.Type.Width
|
||||||
if w < 0 {
|
if w < 0 {
|
||||||
Fatalf("invalid width %d", f.Type.Width)
|
base.Fatalf("invalid width %d", f.Type.Width)
|
||||||
}
|
}
|
||||||
if w == 0 {
|
if w == 0 {
|
||||||
lastzero = o
|
lastzero = o
|
||||||
|
|
@ -147,7 +148,7 @@ func widstruct(errtype *types.Type, t *types.Type, o int64, flag int) int64 {
|
||||||
maxwidth = 1<<31 - 1
|
maxwidth = 1<<31 - 1
|
||||||
}
|
}
|
||||||
if o >= maxwidth {
|
if o >= maxwidth {
|
||||||
yyerrorl(typePos(errtype), "type %L too large", errtype)
|
base.ErrorfAt(typePos(errtype), "type %L too large", errtype)
|
||||||
o = 8 // small but nonzero
|
o = 8 // small but nonzero
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -235,7 +236,7 @@ func reportTypeLoop(t *types.Type) {
|
||||||
|
|
||||||
var l []*types.Type
|
var l []*types.Type
|
||||||
if !findTypeLoop(t, &l) {
|
if !findTypeLoop(t, &l) {
|
||||||
Fatalf("failed to find type loop for: %v", t)
|
base.Fatalf("failed to find type loop for: %v", t)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rotate loop so that the earliest type declaration is first.
|
// Rotate loop so that the earliest type declaration is first.
|
||||||
|
|
@ -250,11 +251,11 @@ func reportTypeLoop(t *types.Type) {
|
||||||
var msg bytes.Buffer
|
var msg bytes.Buffer
|
||||||
fmt.Fprintf(&msg, "invalid recursive type %v\n", l[0])
|
fmt.Fprintf(&msg, "invalid recursive type %v\n", l[0])
|
||||||
for _, t := range l {
|
for _, t := range l {
|
||||||
fmt.Fprintf(&msg, "\t%v: %v refers to\n", linestr(typePos(t)), t)
|
fmt.Fprintf(&msg, "\t%v: %v refers to\n", base.FmtPos(typePos(t)), t)
|
||||||
t.SetBroke(true)
|
t.SetBroke(true)
|
||||||
}
|
}
|
||||||
fmt.Fprintf(&msg, "\t%v: %v", linestr(typePos(l[0])), l[0])
|
fmt.Fprintf(&msg, "\t%v: %v", base.FmtPos(typePos(l[0])), l[0])
|
||||||
yyerrorl(typePos(l[0]), msg.String())
|
base.ErrorfAt(typePos(l[0]), msg.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// dowidth calculates and stores the size and alignment for t.
|
// dowidth calculates and stores the size and alignment for t.
|
||||||
|
|
@ -268,7 +269,7 @@ func dowidth(t *types.Type) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if Widthptr == 0 {
|
if Widthptr == 0 {
|
||||||
Fatalf("dowidth without betypeinit")
|
base.Fatalf("dowidth without betypeinit")
|
||||||
}
|
}
|
||||||
|
|
||||||
if t == nil {
|
if t == nil {
|
||||||
|
|
@ -292,7 +293,7 @@ func dowidth(t *types.Type) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
t.SetBroke(true)
|
t.SetBroke(true)
|
||||||
Fatalf("width not calculated: %v", t)
|
base.Fatalf("width not calculated: %v", t)
|
||||||
}
|
}
|
||||||
|
|
||||||
// break infinite recursion if the broken recursive type
|
// break infinite recursion if the broken recursive type
|
||||||
|
|
@ -304,9 +305,9 @@ func dowidth(t *types.Type) {
|
||||||
// defer checkwidth calls until after we're done
|
// defer checkwidth calls until after we're done
|
||||||
defercheckwidth()
|
defercheckwidth()
|
||||||
|
|
||||||
lno := lineno
|
lno := base.Pos
|
||||||
if asNode(t.Nod) != nil {
|
if asNode(t.Nod) != nil {
|
||||||
lineno = asNode(t.Nod).Pos
|
base.Pos = asNode(t.Nod).Pos
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Width = -2
|
t.Width = -2
|
||||||
|
|
@ -327,7 +328,7 @@ func dowidth(t *types.Type) {
|
||||||
var w int64
|
var w int64
|
||||||
switch et {
|
switch et {
|
||||||
default:
|
default:
|
||||||
Fatalf("dowidth: unknown type: %v", t)
|
base.Fatalf("dowidth: unknown type: %v", t)
|
||||||
|
|
||||||
// compiler-specific stuff
|
// compiler-specific stuff
|
||||||
case TINT8, TUINT8, TBOOL:
|
case TINT8, TUINT8, TBOOL:
|
||||||
|
|
@ -378,7 +379,7 @@ func dowidth(t *types.Type) {
|
||||||
t1 := t.ChanArgs()
|
t1 := t.ChanArgs()
|
||||||
dowidth(t1) // just in case
|
dowidth(t1) // just in case
|
||||||
if t1.Elem().Width >= 1<<16 {
|
if t1.Elem().Width >= 1<<16 {
|
||||||
yyerrorl(typePos(t1), "channel element type too large (>64kB)")
|
base.ErrorfAt(typePos(t1), "channel element type too large (>64kB)")
|
||||||
}
|
}
|
||||||
w = 1 // anything will do
|
w = 1 // anything will do
|
||||||
|
|
||||||
|
|
@ -393,11 +394,11 @@ func dowidth(t *types.Type) {
|
||||||
|
|
||||||
case TANY:
|
case TANY:
|
||||||
// not a real type; should be replaced before use.
|
// not a real type; should be replaced before use.
|
||||||
Fatalf("dowidth any")
|
base.Fatalf("dowidth any")
|
||||||
|
|
||||||
case TSTRING:
|
case TSTRING:
|
||||||
if sizeofString == 0 {
|
if sizeofString == 0 {
|
||||||
Fatalf("early dowidth string")
|
base.Fatalf("early dowidth string")
|
||||||
}
|
}
|
||||||
w = sizeofString
|
w = sizeofString
|
||||||
t.Align = uint8(Widthptr)
|
t.Align = uint8(Widthptr)
|
||||||
|
|
@ -411,7 +412,7 @@ func dowidth(t *types.Type) {
|
||||||
if t.Elem().Width != 0 {
|
if t.Elem().Width != 0 {
|
||||||
cap := (uint64(thearch.MAXWIDTH) - 1) / uint64(t.Elem().Width)
|
cap := (uint64(thearch.MAXWIDTH) - 1) / uint64(t.Elem().Width)
|
||||||
if uint64(t.NumElem()) > cap {
|
if uint64(t.NumElem()) > cap {
|
||||||
yyerrorl(typePos(t), "type %L larger than address space", t)
|
base.ErrorfAt(typePos(t), "type %L larger than address space", t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w = t.NumElem() * t.Elem().Width
|
w = t.NumElem() * t.Elem().Width
|
||||||
|
|
@ -427,7 +428,7 @@ func dowidth(t *types.Type) {
|
||||||
|
|
||||||
case TSTRUCT:
|
case TSTRUCT:
|
||||||
if t.IsFuncArgStruct() {
|
if t.IsFuncArgStruct() {
|
||||||
Fatalf("dowidth fn struct %v", t)
|
base.Fatalf("dowidth fn struct %v", t)
|
||||||
}
|
}
|
||||||
w = widstruct(t, t, 0, 1)
|
w = widstruct(t, t, 0, 1)
|
||||||
|
|
||||||
|
|
@ -447,24 +448,24 @@ func dowidth(t *types.Type) {
|
||||||
w = widstruct(t1, t1.Results(), w, Widthreg)
|
w = widstruct(t1, t1.Results(), w, Widthreg)
|
||||||
t1.Extra.(*types.Func).Argwid = w
|
t1.Extra.(*types.Func).Argwid = w
|
||||||
if w%int64(Widthreg) != 0 {
|
if w%int64(Widthreg) != 0 {
|
||||||
Warn("bad type %v %d\n", t1, w)
|
base.Warn("bad type %v %d\n", t1, w)
|
||||||
}
|
}
|
||||||
t.Align = 1
|
t.Align = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if Widthptr == 4 && w != int64(int32(w)) {
|
if Widthptr == 4 && w != int64(int32(w)) {
|
||||||
yyerrorl(typePos(t), "type %v too large", t)
|
base.ErrorfAt(typePos(t), "type %v too large", t)
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Width = w
|
t.Width = w
|
||||||
if t.Align == 0 {
|
if t.Align == 0 {
|
||||||
if w == 0 || w > 8 || w&(w-1) != 0 {
|
if w == 0 || w > 8 || w&(w-1) != 0 {
|
||||||
Fatalf("invalid alignment for %v", t)
|
base.Fatalf("invalid alignment for %v", t)
|
||||||
}
|
}
|
||||||
t.Align = uint8(w)
|
t.Align = uint8(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
lineno = lno
|
base.Pos = lno
|
||||||
|
|
||||||
resumecheckwidth()
|
resumecheckwidth()
|
||||||
}
|
}
|
||||||
|
|
@ -495,7 +496,7 @@ func checkwidth(t *types.Type) {
|
||||||
// function arg structs should not be checked
|
// function arg structs should not be checked
|
||||||
// outside of the enclosing function.
|
// outside of the enclosing function.
|
||||||
if t.IsFuncArgStruct() {
|
if t.IsFuncArgStruct() {
|
||||||
Fatalf("checkwidth %v", t)
|
base.Fatalf("checkwidth %v", t)
|
||||||
}
|
}
|
||||||
|
|
||||||
if defercalc == 0 {
|
if defercalc == 0 {
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,11 @@
|
||||||
|
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import "runtime"
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
func startMutexProfiling() {
|
func startMutexProfiling() {
|
||||||
Fatalf("mutex profiling unavailable in version %v", runtime.Version())
|
base.Fatalf("mutex profiling unavailable in version %v", runtime.Version())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/bits"
|
"math/bits"
|
||||||
|
|
||||||
|
"cmd/compile/internal/base"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -35,7 +37,7 @@ func bvbulkalloc(nbit int32, count int32) bulkBvec {
|
||||||
nword := (nbit + wordBits - 1) / wordBits
|
nword := (nbit + wordBits - 1) / wordBits
|
||||||
size := int64(nword) * int64(count)
|
size := int64(nword) * int64(count)
|
||||||
if int64(int32(size*4)) != size*4 {
|
if int64(int32(size*4)) != size*4 {
|
||||||
Fatalf("bvbulkalloc too big: nbit=%d count=%d nword=%d size=%d", nbit, count, nword, size)
|
base.Fatalf("bvbulkalloc too big: nbit=%d count=%d nword=%d size=%d", nbit, count, nword, size)
|
||||||
}
|
}
|
||||||
return bulkBvec{
|
return bulkBvec{
|
||||||
words: make([]uint32, size),
|
words: make([]uint32, size),
|
||||||
|
|
@ -52,7 +54,7 @@ func (b *bulkBvec) next() bvec {
|
||||||
|
|
||||||
func (bv1 bvec) Eq(bv2 bvec) bool {
|
func (bv1 bvec) Eq(bv2 bvec) bool {
|
||||||
if bv1.n != bv2.n {
|
if bv1.n != bv2.n {
|
||||||
Fatalf("bvequal: lengths %d and %d are not equal", bv1.n, bv2.n)
|
base.Fatalf("bvequal: lengths %d and %d are not equal", bv1.n, bv2.n)
|
||||||
}
|
}
|
||||||
for i, x := range bv1.b {
|
for i, x := range bv1.b {
|
||||||
if x != bv2.b[i] {
|
if x != bv2.b[i] {
|
||||||
|
|
@ -68,7 +70,7 @@ func (dst bvec) Copy(src bvec) {
|
||||||
|
|
||||||
func (bv bvec) Get(i int32) bool {
|
func (bv bvec) Get(i int32) bool {
|
||||||
if i < 0 || i >= bv.n {
|
if i < 0 || i >= bv.n {
|
||||||
Fatalf("bvget: index %d is out of bounds with length %d\n", i, bv.n)
|
base.Fatalf("bvget: index %d is out of bounds with length %d\n", i, bv.n)
|
||||||
}
|
}
|
||||||
mask := uint32(1 << uint(i%wordBits))
|
mask := uint32(1 << uint(i%wordBits))
|
||||||
return bv.b[i>>wordShift]&mask != 0
|
return bv.b[i>>wordShift]&mask != 0
|
||||||
|
|
@ -76,7 +78,7 @@ func (bv bvec) Get(i int32) bool {
|
||||||
|
|
||||||
func (bv bvec) Set(i int32) {
|
func (bv bvec) Set(i int32) {
|
||||||
if i < 0 || i >= bv.n {
|
if i < 0 || i >= bv.n {
|
||||||
Fatalf("bvset: index %d is out of bounds with length %d\n", i, bv.n)
|
base.Fatalf("bvset: index %d is out of bounds with length %d\n", i, bv.n)
|
||||||
}
|
}
|
||||||
mask := uint32(1 << uint(i%wordBits))
|
mask := uint32(1 << uint(i%wordBits))
|
||||||
bv.b[i/wordBits] |= mask
|
bv.b[i/wordBits] |= mask
|
||||||
|
|
@ -84,7 +86,7 @@ func (bv bvec) Set(i int32) {
|
||||||
|
|
||||||
func (bv bvec) Unset(i int32) {
|
func (bv bvec) Unset(i int32) {
|
||||||
if i < 0 || i >= bv.n {
|
if i < 0 || i >= bv.n {
|
||||||
Fatalf("bvunset: index %d is out of bounds with length %d\n", i, bv.n)
|
base.Fatalf("bvunset: index %d is out of bounds with length %d\n", i, bv.n)
|
||||||
}
|
}
|
||||||
mask := uint32(1 << uint(i%wordBits))
|
mask := uint32(1 << uint(i%wordBits))
|
||||||
bv.b[i/wordBits] &^= mask
|
bv.b[i/wordBits] &^= mask
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/syntax"
|
"cmd/compile/internal/syntax"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/src"
|
"cmd/internal/src"
|
||||||
|
|
@ -101,7 +102,7 @@ func typecheckclosure(clo *Node, top int) {
|
||||||
if !n.Name.Captured() {
|
if !n.Name.Captured() {
|
||||||
n.Name.SetCaptured(true)
|
n.Name.SetCaptured(true)
|
||||||
if n.Name.Decldepth == 0 {
|
if n.Name.Decldepth == 0 {
|
||||||
Fatalf("typecheckclosure: var %S does not have decldepth assigned", n)
|
base.Fatalf("typecheckclosure: var %S does not have decldepth assigned", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore assignments to the variable in straightline code
|
// Ignore assignments to the variable in straightline code
|
||||||
|
|
@ -171,8 +172,8 @@ var capturevarscomplete bool
|
||||||
// We use value capturing for values <= 128 bytes that are never reassigned
|
// We use value capturing for values <= 128 bytes that are never reassigned
|
||||||
// after capturing (effectively constant).
|
// after capturing (effectively constant).
|
||||||
func capturevars(dcl *Node) {
|
func capturevars(dcl *Node) {
|
||||||
lno := lineno
|
lno := base.Pos
|
||||||
lineno = dcl.Pos
|
base.Pos = dcl.Pos
|
||||||
fn := dcl.Func
|
fn := dcl.Func
|
||||||
cvars := fn.ClosureVars.Slice()
|
cvars := fn.ClosureVars.Slice()
|
||||||
out := cvars[:0]
|
out := cvars[:0]
|
||||||
|
|
@ -203,7 +204,7 @@ func capturevars(dcl *Node) {
|
||||||
outer = nod(OADDR, outer, nil)
|
outer = nod(OADDR, outer, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
if Flag.LowerM > 1 {
|
if base.Flag.LowerM > 1 {
|
||||||
var name *types.Sym
|
var name *types.Sym
|
||||||
if v.Name.Curfn != nil && v.Name.Curfn.Func.Nname != nil {
|
if v.Name.Curfn != nil && v.Name.Curfn.Func.Nname != nil {
|
||||||
name = v.Name.Curfn.Func.Nname.Sym
|
name = v.Name.Curfn.Func.Nname.Sym
|
||||||
|
|
@ -212,7 +213,7 @@ func capturevars(dcl *Node) {
|
||||||
if v.Name.Byval() {
|
if v.Name.Byval() {
|
||||||
how = "value"
|
how = "value"
|
||||||
}
|
}
|
||||||
Warnl(v.Pos, "%v capturing by %s: %v (addr=%v assign=%v width=%d)", name, how, v.Sym, outermost.Name.Addrtaken(), outermost.Name.Assigned(), int32(v.Type.Width))
|
base.WarnfAt(v.Pos, "%v capturing by %s: %v (addr=%v assign=%v width=%d)", name, how, v.Sym, outermost.Name.Addrtaken(), outermost.Name.Assigned(), int32(v.Type.Width))
|
||||||
}
|
}
|
||||||
|
|
||||||
outer = typecheck(outer, ctxExpr)
|
outer = typecheck(outer, ctxExpr)
|
||||||
|
|
@ -220,14 +221,14 @@ func capturevars(dcl *Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn.ClosureVars.Set(out)
|
fn.ClosureVars.Set(out)
|
||||||
lineno = lno
|
base.Pos = lno
|
||||||
}
|
}
|
||||||
|
|
||||||
// transformclosure is called in a separate phase after escape analysis.
|
// transformclosure is called in a separate phase after escape analysis.
|
||||||
// It transform closure bodies to properly reference captured variables.
|
// It transform closure bodies to properly reference captured variables.
|
||||||
func transformclosure(dcl *Node) {
|
func transformclosure(dcl *Node) {
|
||||||
lno := lineno
|
lno := base.Pos
|
||||||
lineno = dcl.Pos
|
base.Pos = dcl.Pos
|
||||||
fn := dcl.Func
|
fn := dcl.Func
|
||||||
|
|
||||||
if fn.ClosureCalled {
|
if fn.ClosureCalled {
|
||||||
|
|
@ -325,7 +326,7 @@ func transformclosure(dcl *Node) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lineno = lno
|
base.Pos = lno
|
||||||
}
|
}
|
||||||
|
|
||||||
// hasemptycvars reports whether closure clo has an
|
// hasemptycvars reports whether closure clo has an
|
||||||
|
|
@ -337,15 +338,15 @@ func hasemptycvars(clo *Node) bool {
|
||||||
// closuredebugruntimecheck applies boilerplate checks for debug flags
|
// closuredebugruntimecheck applies boilerplate checks for debug flags
|
||||||
// and compiling runtime
|
// and compiling runtime
|
||||||
func closuredebugruntimecheck(clo *Node) {
|
func closuredebugruntimecheck(clo *Node) {
|
||||||
if Debug.Closure > 0 {
|
if base.Debug.Closure > 0 {
|
||||||
if clo.Esc == EscHeap {
|
if clo.Esc == EscHeap {
|
||||||
Warnl(clo.Pos, "heap closure, captured vars = %v", clo.Func.ClosureVars)
|
base.WarnfAt(clo.Pos, "heap closure, captured vars = %v", clo.Func.ClosureVars)
|
||||||
} else {
|
} else {
|
||||||
Warnl(clo.Pos, "stack closure, captured vars = %v", clo.Func.ClosureVars)
|
base.WarnfAt(clo.Pos, "stack closure, captured vars = %v", clo.Func.ClosureVars)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if Flag.CompilingRuntime && clo.Esc == EscHeap {
|
if base.Flag.CompilingRuntime && clo.Esc == EscHeap {
|
||||||
yyerrorl(clo.Pos, "heap-allocated closure, not allowed in runtime")
|
base.ErrorfAt(clo.Pos, "heap-allocated closure, not allowed in runtime")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -386,8 +387,8 @@ func walkclosure(clo *Node, init *Nodes) *Node {
|
||||||
|
|
||||||
// If no closure vars, don't bother wrapping.
|
// If no closure vars, don't bother wrapping.
|
||||||
if hasemptycvars(clo) {
|
if hasemptycvars(clo) {
|
||||||
if Debug.Closure > 0 {
|
if base.Debug.Closure > 0 {
|
||||||
Warnl(clo.Pos, "closure converted to global")
|
base.WarnfAt(clo.Pos, "closure converted to global")
|
||||||
}
|
}
|
||||||
return fn.Nname
|
return fn.Nname
|
||||||
}
|
}
|
||||||
|
|
@ -423,7 +424,7 @@ func typecheckpartialcall(dot *Node, sym *types.Sym) {
|
||||||
break
|
break
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Fatalf("invalid typecheckpartialcall")
|
base.Fatalf("invalid typecheckpartialcall")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create top-level function.
|
// Create top-level function.
|
||||||
|
|
@ -448,13 +449,13 @@ func makepartialcall(dot *Node, t0 *types.Type, meth *types.Sym) *Node {
|
||||||
sym.SetUniq(true)
|
sym.SetUniq(true)
|
||||||
|
|
||||||
savecurfn := Curfn
|
savecurfn := Curfn
|
||||||
saveLineNo := lineno
|
saveLineNo := base.Pos
|
||||||
Curfn = nil
|
Curfn = nil
|
||||||
|
|
||||||
// Set line number equal to the line number where the method is declared.
|
// Set line number equal to the line number where the method is declared.
|
||||||
var m *types.Field
|
var m *types.Field
|
||||||
if lookdot0(meth, rcvrtype, &m, false) == 1 && m.Pos.IsKnown() {
|
if lookdot0(meth, rcvrtype, &m, false) == 1 && m.Pos.IsKnown() {
|
||||||
lineno = m.Pos
|
base.Pos = m.Pos
|
||||||
}
|
}
|
||||||
// Note: !m.Pos.IsKnown() happens for method expressions where
|
// Note: !m.Pos.IsKnown() happens for method expressions where
|
||||||
// the method is implicitly declared. The Error method of the
|
// the method is implicitly declared. The Error method of the
|
||||||
|
|
@ -512,7 +513,7 @@ func makepartialcall(dot *Node, t0 *types.Type, meth *types.Sym) *Node {
|
||||||
sym.Def = asTypesNode(dcl)
|
sym.Def = asTypesNode(dcl)
|
||||||
xtop = append(xtop, dcl)
|
xtop = append(xtop, dcl)
|
||||||
Curfn = savecurfn
|
Curfn = savecurfn
|
||||||
lineno = saveLineNo
|
base.Pos = saveLineNo
|
||||||
|
|
||||||
return dcl
|
return dcl
|
||||||
}
|
}
|
||||||
|
|
@ -579,14 +580,14 @@ func walkpartialcall(n *Node, init *Nodes) *Node {
|
||||||
// referenced by method value n.
|
// referenced by method value n.
|
||||||
func callpartMethod(n *Node) *types.Field {
|
func callpartMethod(n *Node) *types.Field {
|
||||||
if n.Op != OCALLPART {
|
if n.Op != OCALLPART {
|
||||||
Fatalf("expected OCALLPART, got %v", n)
|
base.Fatalf("expected OCALLPART, got %v", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(mdempsky): Optimize this. If necessary,
|
// TODO(mdempsky): Optimize this. If necessary,
|
||||||
// makepartialcall could save m for us somewhere.
|
// makepartialcall could save m for us somewhere.
|
||||||
var m *types.Field
|
var m *types.Field
|
||||||
if lookdot0(n.Right.Sym, n.Left.Type, &m, false) != 1 {
|
if lookdot0(n.Right.Sym, n.Left.Type, &m, false) != 1 {
|
||||||
Fatalf("failed to find field for OCALLPART")
|
base.Fatalf("failed to find field for OCALLPART")
|
||||||
}
|
}
|
||||||
|
|
||||||
return m
|
return m
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/src"
|
"cmd/internal/src"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
@ -28,7 +29,7 @@ const (
|
||||||
func (n *Node) ValueInterface() interface{} {
|
func (n *Node) ValueInterface() interface{} {
|
||||||
switch v := n.Val(); v.Kind() {
|
switch v := n.Val(); v.Kind() {
|
||||||
default:
|
default:
|
||||||
Fatalf("unexpected constant: %v", v)
|
base.Fatalf("unexpected constant: %v", v)
|
||||||
panic("unreachable")
|
panic("unreachable")
|
||||||
case constant.Bool:
|
case constant.Bool:
|
||||||
return constant.BoolVal(v)
|
return constant.BoolVal(v)
|
||||||
|
|
@ -55,7 +56,7 @@ func int64Val(t *types.Type, v constant.Value) int64 {
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Fatalf("%v out of range for %v", v, t)
|
base.Fatalf("%v out of range for %v", v, t)
|
||||||
panic("unreachable")
|
panic("unreachable")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -63,7 +64,7 @@ func float64Val(v constant.Value) float64 {
|
||||||
if x, _ := constant.Float64Val(v); !math.IsInf(x, 0) {
|
if x, _ := constant.Float64Val(v); !math.IsInf(x, 0) {
|
||||||
return x + 0 // avoid -0 (should not be needed, but be conservative)
|
return x + 0 // avoid -0 (should not be needed, but be conservative)
|
||||||
}
|
}
|
||||||
Fatalf("bad float64 value: %v", v)
|
base.Fatalf("bad float64 value: %v", v)
|
||||||
panic("unreachable")
|
panic("unreachable")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,7 +81,7 @@ func bigFloatVal(v constant.Value) *big.Float {
|
||||||
case *big.Rat:
|
case *big.Rat:
|
||||||
f.SetRat(u)
|
f.SetRat(u)
|
||||||
default:
|
default:
|
||||||
Fatalf("unexpected: %v", u)
|
base.Fatalf("unexpected: %v", u)
|
||||||
}
|
}
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
@ -89,11 +90,11 @@ func bigFloatVal(v constant.Value) *big.Float {
|
||||||
// n must be an integer or rune constant.
|
// n must be an integer or rune constant.
|
||||||
func (n *Node) Int64Val() int64 {
|
func (n *Node) Int64Val() int64 {
|
||||||
if !Isconst(n, constant.Int) {
|
if !Isconst(n, constant.Int) {
|
||||||
Fatalf("Int64Val(%v)", n)
|
base.Fatalf("Int64Val(%v)", n)
|
||||||
}
|
}
|
||||||
x, ok := constant.Int64Val(n.Val())
|
x, ok := constant.Int64Val(n.Val())
|
||||||
if !ok {
|
if !ok {
|
||||||
Fatalf("Int64Val(%v)", n)
|
base.Fatalf("Int64Val(%v)", n)
|
||||||
}
|
}
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
|
@ -114,11 +115,11 @@ func (n *Node) CanInt64() bool {
|
||||||
// n must be an integer or rune constant.
|
// n must be an integer or rune constant.
|
||||||
func (n *Node) Uint64Val() uint64 {
|
func (n *Node) Uint64Val() uint64 {
|
||||||
if !Isconst(n, constant.Int) {
|
if !Isconst(n, constant.Int) {
|
||||||
Fatalf("Uint64Val(%v)", n)
|
base.Fatalf("Uint64Val(%v)", n)
|
||||||
}
|
}
|
||||||
x, ok := constant.Uint64Val(n.Val())
|
x, ok := constant.Uint64Val(n.Val())
|
||||||
if !ok {
|
if !ok {
|
||||||
Fatalf("Uint64Val(%v)", n)
|
base.Fatalf("Uint64Val(%v)", n)
|
||||||
}
|
}
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
|
@ -127,7 +128,7 @@ func (n *Node) Uint64Val() uint64 {
|
||||||
// n must be a boolean constant.
|
// n must be a boolean constant.
|
||||||
func (n *Node) BoolVal() bool {
|
func (n *Node) BoolVal() bool {
|
||||||
if !Isconst(n, constant.Bool) {
|
if !Isconst(n, constant.Bool) {
|
||||||
Fatalf("BoolVal(%v)", n)
|
base.Fatalf("BoolVal(%v)", n)
|
||||||
}
|
}
|
||||||
return constant.BoolVal(n.Val())
|
return constant.BoolVal(n.Val())
|
||||||
}
|
}
|
||||||
|
|
@ -136,7 +137,7 @@ func (n *Node) BoolVal() bool {
|
||||||
// n must be a string constant.
|
// n must be a string constant.
|
||||||
func (n *Node) StringVal() string {
|
func (n *Node) StringVal() string {
|
||||||
if !Isconst(n, constant.String) {
|
if !Isconst(n, constant.String) {
|
||||||
Fatalf("StringVal(%v)", n)
|
base.Fatalf("StringVal(%v)", n)
|
||||||
}
|
}
|
||||||
return constant.StringVal(n.Val())
|
return constant.StringVal(n.Val())
|
||||||
}
|
}
|
||||||
|
|
@ -150,7 +151,7 @@ func roundFloat(v constant.Value, sz int64) constant.Value {
|
||||||
f, _ := constant.Float64Val(v)
|
f, _ := constant.Float64Val(v)
|
||||||
return makeFloat64(f)
|
return makeFloat64(f)
|
||||||
}
|
}
|
||||||
Fatalf("unexpected size: %v", sz)
|
base.Fatalf("unexpected size: %v", sz)
|
||||||
panic("unreachable")
|
panic("unreachable")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -169,7 +170,7 @@ func truncfltlit(v constant.Value, t *types.Type) constant.Value {
|
||||||
|
|
||||||
// truncate Real and Imag parts of Mpcplx to 32-bit or 64-bit
|
// truncate Real and Imag parts of Mpcplx to 32-bit or 64-bit
|
||||||
// precision, according to type; return truncated value. In case of
|
// precision, according to type; return truncated value. In case of
|
||||||
// overflow, calls yyerror but does not truncate the input value.
|
// overflow, calls Errorf but does not truncate the input value.
|
||||||
func trunccmplxlit(v constant.Value, t *types.Type) constant.Value {
|
func trunccmplxlit(v constant.Value, t *types.Type) constant.Value {
|
||||||
if t.IsUntyped() || overflow(v, t) {
|
if t.IsUntyped() || overflow(v, t) {
|
||||||
// If there was overflow, simply continuing would set the
|
// If there was overflow, simply continuing would set the
|
||||||
|
|
@ -199,10 +200,10 @@ func defaultlit(n *Node, t *types.Type) *Node { return convlit1(n, t, false, nil
|
||||||
// message.
|
// message.
|
||||||
func convlit1(n *Node, t *types.Type, explicit bool, context func() string) *Node {
|
func convlit1(n *Node, t *types.Type, explicit bool, context func() string) *Node {
|
||||||
if explicit && t == nil {
|
if explicit && t == nil {
|
||||||
Fatalf("explicit conversion missing type")
|
base.Fatalf("explicit conversion missing type")
|
||||||
}
|
}
|
||||||
if t != nil && t.IsUntyped() {
|
if t != nil && t.IsUntyped() {
|
||||||
Fatalf("bad conversion to untyped: %v", t)
|
base.Fatalf("bad conversion to untyped: %v", t)
|
||||||
}
|
}
|
||||||
|
|
||||||
if n == nil || n.Type == nil {
|
if n == nil || n.Type == nil {
|
||||||
|
|
@ -223,10 +224,10 @@ func convlit1(n *Node, t *types.Type, explicit bool, context func() string) *Nod
|
||||||
// Nil is technically not a constant, so handle it specially.
|
// Nil is technically not a constant, so handle it specially.
|
||||||
if n.Type.Etype == TNIL {
|
if n.Type.Etype == TNIL {
|
||||||
if n.Op != ONIL {
|
if n.Op != ONIL {
|
||||||
Fatalf("unexpected op: %v (%v)", n, n.Op)
|
base.Fatalf("unexpected op: %v (%v)", n, n.Op)
|
||||||
}
|
}
|
||||||
if t == nil {
|
if t == nil {
|
||||||
yyerror("use of untyped nil")
|
base.Errorf("use of untyped nil")
|
||||||
n.SetDiag(true)
|
n.SetDiag(true)
|
||||||
n.Type = nil
|
n.Type = nil
|
||||||
return n
|
return n
|
||||||
|
|
@ -247,7 +248,7 @@ func convlit1(n *Node, t *types.Type, explicit bool, context func() string) *Nod
|
||||||
|
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
default:
|
default:
|
||||||
Fatalf("unexpected untyped expression: %v", n)
|
base.Fatalf("unexpected untyped expression: %v", n)
|
||||||
|
|
||||||
case OLITERAL:
|
case OLITERAL:
|
||||||
v := convertVal(n.Val(), t, explicit)
|
v := convertVal(n.Val(), t, explicit)
|
||||||
|
|
@ -287,7 +288,7 @@ func convlit1(n *Node, t *types.Type, explicit bool, context func() string) *Nod
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
if !types.Identical(n.Left.Type, n.Right.Type) {
|
if !types.Identical(n.Left.Type, n.Right.Type) {
|
||||||
yyerror("invalid operation: %v (mismatched types %v and %v)", n, n.Left.Type, n.Right.Type)
|
base.Errorf("invalid operation: %v (mismatched types %v and %v)", n, n.Left.Type, n.Right.Type)
|
||||||
n.Type = nil
|
n.Type = nil
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
@ -306,7 +307,7 @@ func convlit1(n *Node, t *types.Type, explicit bool, context func() string) *Nod
|
||||||
n.Left = convlit1(n.Left, t, explicit, nil)
|
n.Left = convlit1(n.Left, t, explicit, nil)
|
||||||
n.Type = n.Left.Type
|
n.Type = n.Left.Type
|
||||||
if n.Type != nil && !n.Type.IsInteger() {
|
if n.Type != nil && !n.Type.IsInteger() {
|
||||||
yyerror("invalid operation: %v (shift of type %v)", n, n.Type)
|
base.Errorf("invalid operation: %v (shift of type %v)", n, n.Type)
|
||||||
n.Type = nil
|
n.Type = nil
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
|
|
@ -315,11 +316,11 @@ func convlit1(n *Node, t *types.Type, explicit bool, context func() string) *Nod
|
||||||
if !n.Diag() {
|
if !n.Diag() {
|
||||||
if !t.Broke() {
|
if !t.Broke() {
|
||||||
if explicit {
|
if explicit {
|
||||||
yyerror("cannot convert %L to type %v", n, t)
|
base.Errorf("cannot convert %L to type %v", n, t)
|
||||||
} else if context != nil {
|
} else if context != nil {
|
||||||
yyerror("cannot use %L as type %v in %s", n, t, context())
|
base.Errorf("cannot use %L as type %v in %s", n, t, context())
|
||||||
} else {
|
} else {
|
||||||
yyerror("cannot use %L as type %v", n, t)
|
base.Errorf("cannot use %L as type %v", n, t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
n.SetDiag(true)
|
n.SetDiag(true)
|
||||||
|
|
@ -395,7 +396,7 @@ func tocplx(v constant.Value) constant.Value {
|
||||||
func toflt(v constant.Value) constant.Value {
|
func toflt(v constant.Value) constant.Value {
|
||||||
if v.Kind() == constant.Complex {
|
if v.Kind() == constant.Complex {
|
||||||
if constant.Sign(constant.Imag(v)) != 0 {
|
if constant.Sign(constant.Imag(v)) != 0 {
|
||||||
yyerror("constant %v truncated to real", v)
|
base.Errorf("constant %v truncated to real", v)
|
||||||
}
|
}
|
||||||
v = constant.Real(v)
|
v = constant.Real(v)
|
||||||
}
|
}
|
||||||
|
|
@ -406,7 +407,7 @@ func toflt(v constant.Value) constant.Value {
|
||||||
func toint(v constant.Value) constant.Value {
|
func toint(v constant.Value) constant.Value {
|
||||||
if v.Kind() == constant.Complex {
|
if v.Kind() == constant.Complex {
|
||||||
if constant.Sign(constant.Imag(v)) != 0 {
|
if constant.Sign(constant.Imag(v)) != 0 {
|
||||||
yyerror("constant %v truncated to integer", v)
|
base.Errorf("constant %v truncated to integer", v)
|
||||||
}
|
}
|
||||||
v = constant.Real(v)
|
v = constant.Real(v)
|
||||||
}
|
}
|
||||||
|
|
@ -426,14 +427,14 @@ func toint(v constant.Value) constant.Value {
|
||||||
// (See issue #11371).
|
// (See issue #11371).
|
||||||
f := bigFloatVal(v)
|
f := bigFloatVal(v)
|
||||||
if f.MantExp(nil) > 2*Mpprec {
|
if f.MantExp(nil) > 2*Mpprec {
|
||||||
yyerror("integer too large")
|
base.Errorf("integer too large")
|
||||||
} else {
|
} else {
|
||||||
var t big.Float
|
var t big.Float
|
||||||
t.Parse(fmt.Sprint(v), 0)
|
t.Parse(fmt.Sprint(v), 0)
|
||||||
if t.IsInt() {
|
if t.IsInt() {
|
||||||
yyerror("constant truncated to integer")
|
base.Errorf("constant truncated to integer")
|
||||||
} else {
|
} else {
|
||||||
yyerror("constant %v truncated to integer", v)
|
base.Errorf("constant %v truncated to integer", v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -470,7 +471,7 @@ func doesoverflow(v constant.Value, t *types.Type) bool {
|
||||||
ft := floatForComplex(t)
|
ft := floatForComplex(t)
|
||||||
return doesoverflow(constant.Real(v), ft) || doesoverflow(constant.Imag(v), ft)
|
return doesoverflow(constant.Real(v), ft) || doesoverflow(constant.Imag(v), ft)
|
||||||
}
|
}
|
||||||
Fatalf("doesoverflow: %v, %v", v, t)
|
base.Fatalf("doesoverflow: %v, %v", v, t)
|
||||||
panic("unreachable")
|
panic("unreachable")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -483,11 +484,11 @@ func overflow(v constant.Value, t *types.Type) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if v.Kind() == constant.Int && constant.BitLen(v) > Mpprec {
|
if v.Kind() == constant.Int && constant.BitLen(v) > Mpprec {
|
||||||
yyerror("integer too large")
|
base.Errorf("integer too large")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if doesoverflow(v, t) {
|
if doesoverflow(v, t) {
|
||||||
yyerror("constant %v overflows %v", vconv(v, 0), t)
|
base.Errorf("constant %v overflows %v", vconv(v, 0), t)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|
@ -568,12 +569,12 @@ func evalConst(n *Node) *Node {
|
||||||
|
|
||||||
// check for divisor underflow in complex division (see issue 20227)
|
// check for divisor underflow in complex division (see issue 20227)
|
||||||
if op == ODIV && n.Type.IsComplex() && constant.Sign(square(constant.Real(rval))) == 0 && constant.Sign(square(constant.Imag(rval))) == 0 {
|
if op == ODIV && n.Type.IsComplex() && constant.Sign(square(constant.Real(rval))) == 0 && constant.Sign(square(constant.Imag(rval))) == 0 {
|
||||||
yyerror("complex division by zero")
|
base.Errorf("complex division by zero")
|
||||||
n.Type = nil
|
n.Type = nil
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
if (op == ODIV || op == OMOD) && constant.Sign(rval) == 0 {
|
if (op == ODIV || op == OMOD) && constant.Sign(rval) == 0 {
|
||||||
yyerror("division by zero")
|
base.Errorf("division by zero")
|
||||||
n.Type = nil
|
n.Type = nil
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
@ -596,7 +597,7 @@ func evalConst(n *Node) *Node {
|
||||||
const shiftBound = 1023 - 1 + 52
|
const shiftBound = 1023 - 1 + 52
|
||||||
s, ok := constant.Uint64Val(nr.Val())
|
s, ok := constant.Uint64Val(nr.Val())
|
||||||
if !ok || s > shiftBound {
|
if !ok || s > shiftBound {
|
||||||
yyerror("invalid shift count %v", nr)
|
base.Errorf("invalid shift count %v", nr)
|
||||||
n.Type = nil
|
n.Type = nil
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
@ -702,7 +703,7 @@ func makeInt(i *big.Int) constant.Value {
|
||||||
|
|
||||||
func makeFloat64(f float64) constant.Value {
|
func makeFloat64(f float64) constant.Value {
|
||||||
if math.IsInf(f, 0) {
|
if math.IsInf(f, 0) {
|
||||||
Fatalf("infinity is not a valid constant")
|
base.Fatalf("infinity is not a valid constant")
|
||||||
}
|
}
|
||||||
v := constant.MakeFloat64(f)
|
v := constant.MakeFloat64(f)
|
||||||
v = constant.ToFloat(v) // workaround #42641 (MakeFloat64(0).Kind() returns Int, not Float)
|
v = constant.ToFloat(v) // workaround #42641 (MakeFloat64(0).Kind() returns Int, not Float)
|
||||||
|
|
@ -732,7 +733,7 @@ var overflowNames = [...]string{
|
||||||
func origConst(n *Node, v constant.Value) *Node {
|
func origConst(n *Node, v constant.Value) *Node {
|
||||||
lno := setlineno(n)
|
lno := setlineno(n)
|
||||||
v = convertVal(v, n.Type, false)
|
v = convertVal(v, n.Type, false)
|
||||||
lineno = lno
|
base.Pos = lno
|
||||||
|
|
||||||
switch v.Kind() {
|
switch v.Kind() {
|
||||||
case constant.Int:
|
case constant.Int:
|
||||||
|
|
@ -743,9 +744,9 @@ func origConst(n *Node, v constant.Value) *Node {
|
||||||
case constant.Unknown:
|
case constant.Unknown:
|
||||||
what := overflowNames[n.Op]
|
what := overflowNames[n.Op]
|
||||||
if what == "" {
|
if what == "" {
|
||||||
Fatalf("unexpected overflow: %v", n.Op)
|
base.Fatalf("unexpected overflow: %v", n.Op)
|
||||||
}
|
}
|
||||||
yyerrorl(n.Pos, "constant %v overflow", what)
|
base.ErrorfAt(n.Pos, "constant %v overflow", what)
|
||||||
n.Type = nil
|
n.Type = nil
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
@ -760,7 +761,7 @@ func origConst(n *Node, v constant.Value) *Node {
|
||||||
|
|
||||||
func assertRepresents(t *types.Type, v constant.Value) {
|
func assertRepresents(t *types.Type, v constant.Value) {
|
||||||
if !represents(t, v) {
|
if !represents(t, v) {
|
||||||
Fatalf("%v does not represent %v", t, v)
|
base.Fatalf("%v does not represent %v", t, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -780,7 +781,7 @@ func represents(t *types.Type, v constant.Value) bool {
|
||||||
return t.IsComplex()
|
return t.IsComplex()
|
||||||
}
|
}
|
||||||
|
|
||||||
Fatalf("unexpected constant kind: %v", v)
|
base.Fatalf("unexpected constant kind: %v", v)
|
||||||
panic("unreachable")
|
panic("unreachable")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -815,7 +816,7 @@ func idealType(ct constant.Kind) *types.Type {
|
||||||
case constant.Complex:
|
case constant.Complex:
|
||||||
return types.UntypedComplex
|
return types.UntypedComplex
|
||||||
}
|
}
|
||||||
Fatalf("unexpected Ctype: %v", ct)
|
base.Fatalf("unexpected Ctype: %v", ct)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -876,7 +877,7 @@ func mixUntyped(t1, t2 *types.Type) *types.Type {
|
||||||
case types.UntypedComplex:
|
case types.UntypedComplex:
|
||||||
return 3
|
return 3
|
||||||
}
|
}
|
||||||
Fatalf("bad type %v", t)
|
base.Fatalf("bad type %v", t)
|
||||||
panic("unreachable")
|
panic("unreachable")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -906,7 +907,7 @@ func defaultType(t *types.Type) *types.Type {
|
||||||
return types.Types[TCOMPLEX128]
|
return types.Types[TCOMPLEX128]
|
||||||
}
|
}
|
||||||
|
|
||||||
Fatalf("bad type %v", t)
|
base.Fatalf("bad type %v", t)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1023,7 +1024,7 @@ func (s *constSet) add(pos src.XPos, n *Node, what, where string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if n.Type.IsUntyped() {
|
if n.Type.IsUntyped() {
|
||||||
Fatalf("%v is untyped", n)
|
base.Fatalf("%v is untyped", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Consts are only duplicates if they have the same value and
|
// Consts are only duplicates if they have the same value and
|
||||||
|
|
@ -1059,9 +1060,9 @@ func (s *constSet) add(pos src.XPos, n *Node, what, where string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if prevPos, isDup := s.m[k]; isDup {
|
if prevPos, isDup := s.m[k]; isDup {
|
||||||
yyerrorl(pos, "duplicate %s %s in %s\n\tprevious %s at %v",
|
base.ErrorfAt(pos, "duplicate %s %s in %s\n\tprevious %s at %v",
|
||||||
what, nodeAndVal(n), where,
|
what, nodeAndVal(n), where,
|
||||||
what, linestr(prevPos))
|
what, base.FmtPos(prevPos))
|
||||||
} else {
|
} else {
|
||||||
s.m[k] = pos
|
s.m[k] = pos
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
"cmd/internal/src"
|
"cmd/internal/src"
|
||||||
|
|
@ -20,7 +21,7 @@ var externdcl []*Node
|
||||||
|
|
||||||
func testdclstack() {
|
func testdclstack() {
|
||||||
if !types.IsDclstackValid() {
|
if !types.IsDclstackValid() {
|
||||||
Fatalf("mark left on the dclstack")
|
base.Fatalf("mark left on the dclstack")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -31,7 +32,7 @@ func redeclare(pos src.XPos, s *types.Sym, where string) {
|
||||||
if pkg == nil {
|
if pkg == nil {
|
||||||
pkg = s.Pkg
|
pkg = s.Pkg
|
||||||
}
|
}
|
||||||
yyerrorl(pos, "%v redeclared %s\n"+
|
base.ErrorfAt(pos, "%v redeclared %s\n"+
|
||||||
"\tprevious declaration during import %q", s, where, pkg.Path)
|
"\tprevious declaration during import %q", s, where, pkg.Path)
|
||||||
} else {
|
} else {
|
||||||
prevPos := s.Lastlineno
|
prevPos := s.Lastlineno
|
||||||
|
|
@ -44,8 +45,8 @@ func redeclare(pos src.XPos, s *types.Sym, where string) {
|
||||||
pos, prevPos = prevPos, pos
|
pos, prevPos = prevPos, pos
|
||||||
}
|
}
|
||||||
|
|
||||||
yyerrorl(pos, "%v redeclared %s\n"+
|
base.ErrorfAt(pos, "%v redeclared %s\n"+
|
||||||
"\tprevious declaration at %v", s, where, linestr(prevPos))
|
"\tprevious declaration at %v", s, where, base.FmtPos(prevPos))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,22 +72,22 @@ func declare(n *Node, ctxt Class) {
|
||||||
|
|
||||||
// kludgy: typecheckok means we're past parsing. Eg genwrapper may declare out of package names later.
|
// kludgy: typecheckok means we're past parsing. Eg genwrapper may declare out of package names later.
|
||||||
if !inimport && !typecheckok && s.Pkg != localpkg {
|
if !inimport && !typecheckok && s.Pkg != localpkg {
|
||||||
yyerrorl(n.Pos, "cannot declare name %v", s)
|
base.ErrorfAt(n.Pos, "cannot declare name %v", s)
|
||||||
}
|
}
|
||||||
|
|
||||||
gen := 0
|
gen := 0
|
||||||
if ctxt == PEXTERN {
|
if ctxt == PEXTERN {
|
||||||
if s.Name == "init" {
|
if s.Name == "init" {
|
||||||
yyerrorl(n.Pos, "cannot declare init - must be func")
|
base.ErrorfAt(n.Pos, "cannot declare init - must be func")
|
||||||
}
|
}
|
||||||
if s.Name == "main" && s.Pkg.Name == "main" {
|
if s.Name == "main" && s.Pkg.Name == "main" {
|
||||||
yyerrorl(n.Pos, "cannot declare main - must be func")
|
base.ErrorfAt(n.Pos, "cannot declare main - must be func")
|
||||||
}
|
}
|
||||||
externdcl = append(externdcl, n)
|
externdcl = append(externdcl, n)
|
||||||
} else {
|
} else {
|
||||||
if Curfn == nil && ctxt == PAUTO {
|
if Curfn == nil && ctxt == PAUTO {
|
||||||
lineno = n.Pos
|
base.Pos = n.Pos
|
||||||
Fatalf("automatic outside function")
|
base.Fatalf("automatic outside function")
|
||||||
}
|
}
|
||||||
if Curfn != nil && ctxt != PFUNC {
|
if Curfn != nil && ctxt != PFUNC {
|
||||||
Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
|
Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
|
||||||
|
|
@ -115,7 +116,7 @@ func declare(n *Node, ctxt Class) {
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Block = types.Block
|
s.Block = types.Block
|
||||||
s.Lastlineno = lineno
|
s.Lastlineno = base.Pos
|
||||||
s.Def = asTypesNode(n)
|
s.Def = asTypesNode(n)
|
||||||
n.Name.Vargen = int32(gen)
|
n.Name.Vargen = int32(gen)
|
||||||
n.SetClass(ctxt)
|
n.SetClass(ctxt)
|
||||||
|
|
@ -128,7 +129,7 @@ func declare(n *Node, ctxt Class) {
|
||||||
|
|
||||||
func addvar(n *Node, t *types.Type, ctxt Class) {
|
func addvar(n *Node, t *types.Type, ctxt Class) {
|
||||||
if n == nil || n.Sym == nil || (n.Op != ONAME && n.Op != ONONAME) || t == nil {
|
if n == nil || n.Sym == nil || (n.Op != ONAME && n.Op != ONONAME) || t == nil {
|
||||||
Fatalf("addvar: n=%v t=%v nil", n, t)
|
base.Fatalf("addvar: n=%v t=%v nil", n, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Op = ONAME
|
n.Op = ONAME
|
||||||
|
|
@ -165,7 +166,7 @@ func variter(vl []*Node, t *Node, el []*Node) []*Node {
|
||||||
var e *Node
|
var e *Node
|
||||||
if doexpr {
|
if doexpr {
|
||||||
if len(el) == 0 {
|
if len(el) == 0 {
|
||||||
yyerror("assignment mismatch: %d variables but %d values", len(vl), nel)
|
base.Errorf("assignment mismatch: %d variables but %d values", len(vl), nel)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
e = el[0]
|
e = el[0]
|
||||||
|
|
@ -189,7 +190,7 @@ func variter(vl []*Node, t *Node, el []*Node) []*Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(el) != 0 {
|
if len(el) != 0 {
|
||||||
yyerror("assignment mismatch: %d variables but %d values", len(vl), nel)
|
base.Errorf("assignment mismatch: %d variables but %d values", len(vl), nel)
|
||||||
}
|
}
|
||||||
return init
|
return init
|
||||||
}
|
}
|
||||||
|
|
@ -197,7 +198,7 @@ func variter(vl []*Node, t *Node, el []*Node) []*Node {
|
||||||
// newnoname returns a new ONONAME Node associated with symbol s.
|
// newnoname returns a new ONONAME Node associated with symbol s.
|
||||||
func newnoname(s *types.Sym) *Node {
|
func newnoname(s *types.Sym) *Node {
|
||||||
if s == nil {
|
if s == nil {
|
||||||
Fatalf("newnoname nil")
|
base.Fatalf("newnoname nil")
|
||||||
}
|
}
|
||||||
n := nod(ONONAME, nil, nil)
|
n := nod(ONONAME, nil, nil)
|
||||||
n.Sym = s
|
n.Sym = s
|
||||||
|
|
@ -208,7 +209,7 @@ func newnoname(s *types.Sym) *Node {
|
||||||
// newfuncnamel generates a new name node for a function or method.
|
// newfuncnamel generates a new name node for a function or method.
|
||||||
func newfuncnamel(pos src.XPos, s *types.Sym, fn *Func) *Node {
|
func newfuncnamel(pos src.XPos, s *types.Sym, fn *Func) *Node {
|
||||||
if fn.Nname != nil {
|
if fn.Nname != nil {
|
||||||
Fatalf("newfuncnamel - already have name")
|
base.Fatalf("newfuncnamel - already have name")
|
||||||
}
|
}
|
||||||
n := newnamel(pos, s)
|
n := newnamel(pos, s)
|
||||||
n.Func = fn
|
n.Func = fn
|
||||||
|
|
@ -304,7 +305,7 @@ func importName(sym *types.Sym) *Node {
|
||||||
n := oldname(sym)
|
n := oldname(sym)
|
||||||
if !types.IsExported(sym.Name) && sym.Pkg != localpkg {
|
if !types.IsExported(sym.Name) && sym.Pkg != localpkg {
|
||||||
n.SetDiag(true)
|
n.SetDiag(true)
|
||||||
yyerror("cannot refer to unexported name %s.%s", sym.Pkg.Name, sym.Name)
|
base.Errorf("cannot refer to unexported name %s.%s", sym.Pkg.Name, sym.Name)
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
@ -336,13 +337,13 @@ func colasdefn(left []*Node, defn *Node) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !colasname(n) {
|
if !colasname(n) {
|
||||||
yyerrorl(defn.Pos, "non-name %v on left side of :=", n)
|
base.ErrorfAt(defn.Pos, "non-name %v on left side of :=", n)
|
||||||
nerr++
|
nerr++
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if !n.Sym.Uniq() {
|
if !n.Sym.Uniq() {
|
||||||
yyerrorl(defn.Pos, "%v repeated on left side of :=", n.Sym)
|
base.ErrorfAt(defn.Pos, "%v repeated on left side of :=", n.Sym)
|
||||||
n.SetDiag(true)
|
n.SetDiag(true)
|
||||||
nerr++
|
nerr++
|
||||||
continue
|
continue
|
||||||
|
|
@ -362,7 +363,7 @@ func colasdefn(left []*Node, defn *Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if nnew == 0 && nerr == 0 {
|
if nnew == 0 && nerr == 0 {
|
||||||
yyerrorl(defn.Pos, "no new variables on left side of :=")
|
base.ErrorfAt(defn.Pos, "no new variables on left side of :=")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -370,11 +371,11 @@ func colasdefn(left []*Node, defn *Node) {
|
||||||
// interface field declaration.
|
// interface field declaration.
|
||||||
func ifacedcl(n *Node) {
|
func ifacedcl(n *Node) {
|
||||||
if n.Op != ODCLFIELD || n.Left == nil {
|
if n.Op != ODCLFIELD || n.Left == nil {
|
||||||
Fatalf("ifacedcl")
|
base.Fatalf("ifacedcl")
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Sym.IsBlank() {
|
if n.Sym.IsBlank() {
|
||||||
yyerror("methods must have a unique non-blank name")
|
base.Errorf("methods must have a unique non-blank name")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -399,7 +400,7 @@ func funchdr(n *Node) {
|
||||||
|
|
||||||
func funcargs(nt *Node) {
|
func funcargs(nt *Node) {
|
||||||
if nt.Op != OTFUNC {
|
if nt.Op != OTFUNC {
|
||||||
Fatalf("funcargs %v", nt.Op)
|
base.Fatalf("funcargs %v", nt.Op)
|
||||||
}
|
}
|
||||||
|
|
||||||
// re-start the variable generation number
|
// re-start the variable generation number
|
||||||
|
|
@ -449,7 +450,7 @@ func funcargs(nt *Node) {
|
||||||
|
|
||||||
func funcarg(n *Node, ctxt Class) {
|
func funcarg(n *Node, ctxt Class) {
|
||||||
if n.Op != ODCLFIELD {
|
if n.Op != ODCLFIELD {
|
||||||
Fatalf("funcarg %v", n.Op)
|
base.Fatalf("funcarg %v", n.Op)
|
||||||
}
|
}
|
||||||
if n.Sym == nil {
|
if n.Sym == nil {
|
||||||
return
|
return
|
||||||
|
|
@ -469,7 +470,7 @@ func funcarg(n *Node, ctxt Class) {
|
||||||
// used functype directly to parse the function's type.
|
// used functype directly to parse the function's type.
|
||||||
func funcargs2(t *types.Type) {
|
func funcargs2(t *types.Type) {
|
||||||
if t.Etype != TFUNC {
|
if t.Etype != TFUNC {
|
||||||
Fatalf("funcargs2 %v", t)
|
base.Fatalf("funcargs2 %v", t)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, f := range t.Recvs().Fields().Slice() {
|
for _, f := range t.Recvs().Fields().Slice() {
|
||||||
|
|
@ -522,23 +523,23 @@ func checkembeddedtype(t *types.Type) {
|
||||||
if t.Sym == nil && t.IsPtr() {
|
if t.Sym == nil && t.IsPtr() {
|
||||||
t = t.Elem()
|
t = t.Elem()
|
||||||
if t.IsInterface() {
|
if t.IsInterface() {
|
||||||
yyerror("embedded type cannot be a pointer to interface")
|
base.Errorf("embedded type cannot be a pointer to interface")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.IsPtr() || t.IsUnsafePtr() {
|
if t.IsPtr() || t.IsUnsafePtr() {
|
||||||
yyerror("embedded type cannot be a pointer")
|
base.Errorf("embedded type cannot be a pointer")
|
||||||
} else if t.Etype == TFORW && !t.ForwardType().Embedlineno.IsKnown() {
|
} else if t.Etype == TFORW && !t.ForwardType().Embedlineno.IsKnown() {
|
||||||
t.ForwardType().Embedlineno = lineno
|
t.ForwardType().Embedlineno = base.Pos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func structfield(n *Node) *types.Field {
|
func structfield(n *Node) *types.Field {
|
||||||
lno := lineno
|
lno := base.Pos
|
||||||
lineno = n.Pos
|
base.Pos = n.Pos
|
||||||
|
|
||||||
if n.Op != ODCLFIELD {
|
if n.Op != ODCLFIELD {
|
||||||
Fatalf("structfield: oops %v\n", n)
|
base.Fatalf("structfield: oops %v\n", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Left != nil {
|
if n.Left != nil {
|
||||||
|
|
@ -556,7 +557,7 @@ func structfield(n *Node) *types.Field {
|
||||||
f.Note = constant.StringVal(n.Val())
|
f.Note = constant.StringVal(n.Val())
|
||||||
}
|
}
|
||||||
|
|
||||||
lineno = lno
|
base.Pos = lno
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -570,7 +571,7 @@ func checkdupfields(what string, fss ...[]*types.Field) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if seen[f.Sym] {
|
if seen[f.Sym] {
|
||||||
yyerrorl(f.Pos, "duplicate %s %s", what, f.Sym.Name)
|
base.ErrorfAt(f.Pos, "duplicate %s %s", what, f.Sym.Name)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
seen[f.Sym] = true
|
seen[f.Sym] = true
|
||||||
|
|
@ -631,15 +632,15 @@ func tofunargsfield(fields []*types.Field, funarg types.Funarg) *types.Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
func interfacefield(n *Node) *types.Field {
|
func interfacefield(n *Node) *types.Field {
|
||||||
lno := lineno
|
lno := base.Pos
|
||||||
lineno = n.Pos
|
base.Pos = n.Pos
|
||||||
|
|
||||||
if n.Op != ODCLFIELD {
|
if n.Op != ODCLFIELD {
|
||||||
Fatalf("interfacefield: oops %v\n", n)
|
base.Fatalf("interfacefield: oops %v\n", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.HasVal() {
|
if n.HasVal() {
|
||||||
yyerror("interface method cannot have annotation")
|
base.Errorf("interface method cannot have annotation")
|
||||||
}
|
}
|
||||||
|
|
||||||
// MethodSpec = MethodName Signature | InterfaceTypeName .
|
// MethodSpec = MethodName Signature | InterfaceTypeName .
|
||||||
|
|
@ -655,7 +656,7 @@ func interfacefield(n *Node) *types.Field {
|
||||||
|
|
||||||
f := types.NewField(n.Pos, n.Sym, n.Type)
|
f := types.NewField(n.Pos, n.Sym, n.Type)
|
||||||
|
|
||||||
lineno = lno
|
base.Pos = lno
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -774,13 +775,13 @@ func methodSym(recv *types.Type, msym *types.Sym) *types.Sym {
|
||||||
// start with a letter, number, or period.
|
// start with a letter, number, or period.
|
||||||
func methodSymSuffix(recv *types.Type, msym *types.Sym, suffix string) *types.Sym {
|
func methodSymSuffix(recv *types.Type, msym *types.Sym, suffix string) *types.Sym {
|
||||||
if msym.IsBlank() {
|
if msym.IsBlank() {
|
||||||
Fatalf("blank method name")
|
base.Fatalf("blank method name")
|
||||||
}
|
}
|
||||||
|
|
||||||
rsym := recv.Sym
|
rsym := recv.Sym
|
||||||
if recv.IsPtr() {
|
if recv.IsPtr() {
|
||||||
if rsym != nil {
|
if rsym != nil {
|
||||||
Fatalf("declared pointer receiver type: %v", recv)
|
base.Fatalf("declared pointer receiver type: %v", recv)
|
||||||
}
|
}
|
||||||
rsym = recv.Elem().Sym
|
rsym = recv.Elem().Sym
|
||||||
}
|
}
|
||||||
|
|
@ -824,13 +825,13 @@ func methodSymSuffix(recv *types.Type, msym *types.Sym, suffix string) *types.Sy
|
||||||
// Returns a pointer to the existing or added Field; or nil if there's an error.
|
// Returns a pointer to the existing or added Field; or nil if there's an error.
|
||||||
func addmethod(n *Node, msym *types.Sym, t *types.Type, local, nointerface bool) *types.Field {
|
func addmethod(n *Node, msym *types.Sym, t *types.Type, local, nointerface bool) *types.Field {
|
||||||
if msym == nil {
|
if msym == nil {
|
||||||
Fatalf("no method symbol")
|
base.Fatalf("no method symbol")
|
||||||
}
|
}
|
||||||
|
|
||||||
// get parent type sym
|
// get parent type sym
|
||||||
rf := t.Recv() // ptr to this structure
|
rf := t.Recv() // ptr to this structure
|
||||||
if rf == nil {
|
if rf == nil {
|
||||||
yyerror("missing receiver")
|
base.Errorf("missing receiver")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -840,7 +841,7 @@ func addmethod(n *Node, msym *types.Sym, t *types.Type, local, nointerface bool)
|
||||||
t := pa
|
t := pa
|
||||||
if t != nil && t.IsPtr() {
|
if t != nil && t.IsPtr() {
|
||||||
if t.Sym != nil {
|
if t.Sym != nil {
|
||||||
yyerror("invalid receiver type %v (%v is a pointer type)", pa, t)
|
base.Errorf("invalid receiver type %v (%v is a pointer type)", pa, t)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
t = t.Elem()
|
t = t.Elem()
|
||||||
|
|
@ -850,21 +851,21 @@ func addmethod(n *Node, msym *types.Sym, t *types.Type, local, nointerface bool)
|
||||||
case t == nil || t.Broke():
|
case t == nil || t.Broke():
|
||||||
// rely on typecheck having complained before
|
// rely on typecheck having complained before
|
||||||
case t.Sym == nil:
|
case t.Sym == nil:
|
||||||
yyerror("invalid receiver type %v (%v is not a defined type)", pa, t)
|
base.Errorf("invalid receiver type %v (%v is not a defined type)", pa, t)
|
||||||
case t.IsPtr():
|
case t.IsPtr():
|
||||||
yyerror("invalid receiver type %v (%v is a pointer type)", pa, t)
|
base.Errorf("invalid receiver type %v (%v is a pointer type)", pa, t)
|
||||||
case t.IsInterface():
|
case t.IsInterface():
|
||||||
yyerror("invalid receiver type %v (%v is an interface type)", pa, t)
|
base.Errorf("invalid receiver type %v (%v is an interface type)", pa, t)
|
||||||
default:
|
default:
|
||||||
// Should have picked off all the reasons above,
|
// Should have picked off all the reasons above,
|
||||||
// but just in case, fall back to generic error.
|
// but just in case, fall back to generic error.
|
||||||
yyerror("invalid receiver type %v (%L / %L)", pa, pa, t)
|
base.Errorf("invalid receiver type %v (%L / %L)", pa, pa, t)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if local && mt.Sym.Pkg != localpkg {
|
if local && mt.Sym.Pkg != localpkg {
|
||||||
yyerror("cannot define new methods on non-local type %v", mt)
|
base.Errorf("cannot define new methods on non-local type %v", mt)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -875,7 +876,7 @@ func addmethod(n *Node, msym *types.Sym, t *types.Type, local, nointerface bool)
|
||||||
if mt.IsStruct() {
|
if mt.IsStruct() {
|
||||||
for _, f := range mt.Fields().Slice() {
|
for _, f := range mt.Fields().Slice() {
|
||||||
if f.Sym == msym {
|
if f.Sym == msym {
|
||||||
yyerror("type %v has both field and method named %v", mt, msym)
|
base.Errorf("type %v has both field and method named %v", mt, msym)
|
||||||
f.SetBroke(true)
|
f.SetBroke(true)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -889,12 +890,12 @@ func addmethod(n *Node, msym *types.Sym, t *types.Type, local, nointerface bool)
|
||||||
// types.Identical only checks that incoming and result parameters match,
|
// types.Identical only checks that incoming and result parameters match,
|
||||||
// so explicitly check that the receiver parameters match too.
|
// so explicitly check that the receiver parameters match too.
|
||||||
if !types.Identical(t, f.Type) || !types.Identical(t.Recv().Type, f.Type.Recv().Type) {
|
if !types.Identical(t, f.Type) || !types.Identical(t.Recv().Type, f.Type.Recv().Type) {
|
||||||
yyerror("method redeclared: %v.%v\n\t%v\n\t%v", mt, msym, f.Type, t)
|
base.Errorf("method redeclared: %v.%v\n\t%v\n\t%v", mt, msym, f.Type, t)
|
||||||
}
|
}
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
f := types.NewField(lineno, msym, t)
|
f := types.NewField(base.Pos, msym, t)
|
||||||
f.Nname = asTypesNode(n.Func.Nname)
|
f.Nname = asTypesNode(n.Func.Nname)
|
||||||
f.SetNointerface(nointerface)
|
f.SetNointerface(nointerface)
|
||||||
|
|
||||||
|
|
@ -923,7 +924,7 @@ func funcsym(s *types.Sym) *types.Sym {
|
||||||
// When dynamically linking, the necessary function
|
// When dynamically linking, the necessary function
|
||||||
// symbols will be created explicitly with makefuncsym.
|
// symbols will be created explicitly with makefuncsym.
|
||||||
// See the makefuncsym comment for details.
|
// See the makefuncsym comment for details.
|
||||||
if !Ctxt.Flag_dynlink && !existed {
|
if !base.Ctxt.Flag_dynlink && !existed {
|
||||||
funcsyms = append(funcsyms, s)
|
funcsyms = append(funcsyms, s)
|
||||||
}
|
}
|
||||||
funcsymsmu.Unlock()
|
funcsymsmu.Unlock()
|
||||||
|
|
@ -940,13 +941,13 @@ func funcsym(s *types.Sym) *types.Sym {
|
||||||
// So instead, when dynamic linking, we only create
|
// So instead, when dynamic linking, we only create
|
||||||
// the s·f stubs in s's package.
|
// the s·f stubs in s's package.
|
||||||
func makefuncsym(s *types.Sym) {
|
func makefuncsym(s *types.Sym) {
|
||||||
if !Ctxt.Flag_dynlink {
|
if !base.Ctxt.Flag_dynlink {
|
||||||
Fatalf("makefuncsym dynlink")
|
base.Fatalf("makefuncsym dynlink")
|
||||||
}
|
}
|
||||||
if s.IsBlank() {
|
if s.IsBlank() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if Flag.CompilingRuntime && (s.Name == "getg" || s.Name == "getclosureptr" || s.Name == "getcallerpc" || s.Name == "getcallersp") {
|
if base.Flag.CompilingRuntime && (s.Name == "getg" || s.Name == "getclosureptr" || s.Name == "getcallerpc" || s.Name == "getcallersp") {
|
||||||
// runtime.getg(), getclosureptr(), getcallerpc(), and
|
// runtime.getg(), getclosureptr(), getcallerpc(), and
|
||||||
// getcallersp() are not real functions and so do not
|
// getcallersp() are not real functions and so do not
|
||||||
// get funcsyms.
|
// get funcsyms.
|
||||||
|
|
@ -960,7 +961,7 @@ func makefuncsym(s *types.Sym) {
|
||||||
// setNodeNameFunc marks a node as a function.
|
// setNodeNameFunc marks a node as a function.
|
||||||
func setNodeNameFunc(n *Node) {
|
func setNodeNameFunc(n *Node) {
|
||||||
if n.Op != ONAME || n.Class() != Pxxx {
|
if n.Op != ONAME || n.Class() != Pxxx {
|
||||||
Fatalf("expected ONAME/Pxxx node, got %v", n)
|
base.Fatalf("expected ONAME/Pxxx node, got %v", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
n.SetClass(PFUNC)
|
n.SetClass(PFUNC)
|
||||||
|
|
@ -969,11 +970,11 @@ func setNodeNameFunc(n *Node) {
|
||||||
|
|
||||||
func dclfunc(sym *types.Sym, tfn *Node) *Node {
|
func dclfunc(sym *types.Sym, tfn *Node) *Node {
|
||||||
if tfn.Op != OTFUNC {
|
if tfn.Op != OTFUNC {
|
||||||
Fatalf("expected OTFUNC node, got %v", tfn)
|
base.Fatalf("expected OTFUNC node, got %v", tfn)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := nod(ODCLFUNC, nil, nil)
|
fn := nod(ODCLFUNC, nil, nil)
|
||||||
fn.Func.Nname = newfuncnamel(lineno, sym, fn.Func)
|
fn.Func.Nname = newfuncnamel(base.Pos, sym, fn.Func)
|
||||||
fn.Func.Nname.Name.Defn = fn
|
fn.Func.Nname.Name.Defn = fn
|
||||||
fn.Func.Nname.Name.Param.Ntype = tfn
|
fn.Func.Nname.Name.Param.Ntype = tfn
|
||||||
setNodeNameFunc(fn.Func.Nname)
|
setNodeNameFunc(fn.Func.Nname)
|
||||||
|
|
@ -1045,10 +1046,10 @@ func (c *nowritebarrierrecChecker) findExtraCalls(n *Node) bool {
|
||||||
case OCLOSURE:
|
case OCLOSURE:
|
||||||
callee = arg.Func.Decl
|
callee = arg.Func.Decl
|
||||||
default:
|
default:
|
||||||
Fatalf("expected ONAME or OCLOSURE node, got %+v", arg)
|
base.Fatalf("expected ONAME or OCLOSURE node, got %+v", arg)
|
||||||
}
|
}
|
||||||
if callee.Op != ODCLFUNC {
|
if callee.Op != ODCLFUNC {
|
||||||
Fatalf("expected ODCLFUNC node, got %+v", callee)
|
base.Fatalf("expected ODCLFUNC node, got %+v", callee)
|
||||||
}
|
}
|
||||||
c.extraCalls[c.curfn] = append(c.extraCalls[c.curfn], nowritebarrierrecCall{callee, n.Pos})
|
c.extraCalls[c.curfn] = append(c.extraCalls[c.curfn], nowritebarrierrecCall{callee, n.Pos})
|
||||||
return true
|
return true
|
||||||
|
|
@ -1064,7 +1065,7 @@ func (c *nowritebarrierrecChecker) findExtraCalls(n *Node) bool {
|
||||||
// This can be called concurrently for different from Nodes.
|
// This can be called concurrently for different from Nodes.
|
||||||
func (c *nowritebarrierrecChecker) recordCall(from *Node, to *obj.LSym, pos src.XPos) {
|
func (c *nowritebarrierrecChecker) recordCall(from *Node, to *obj.LSym, pos src.XPos) {
|
||||||
if from.Op != ODCLFUNC {
|
if from.Op != ODCLFUNC {
|
||||||
Fatalf("expected ODCLFUNC, got %v", from)
|
base.Fatalf("expected ODCLFUNC, got %v", from)
|
||||||
}
|
}
|
||||||
// We record this information on the *Func so this is
|
// We record this information on the *Func so this is
|
||||||
// concurrent-safe.
|
// concurrent-safe.
|
||||||
|
|
@ -1105,7 +1106,7 @@ func (c *nowritebarrierrecChecker) check() {
|
||||||
}
|
}
|
||||||
// Check go:nowritebarrier functions.
|
// Check go:nowritebarrier functions.
|
||||||
if n.Func.Pragma&Nowritebarrier != 0 && n.Func.WBPos.IsKnown() {
|
if n.Func.Pragma&Nowritebarrier != 0 && n.Func.WBPos.IsKnown() {
|
||||||
yyerrorl(n.Func.WBPos, "write barrier prohibited")
|
base.ErrorfAt(n.Func.WBPos, "write barrier prohibited")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1133,10 +1134,10 @@ func (c *nowritebarrierrecChecker) check() {
|
||||||
var err bytes.Buffer
|
var err bytes.Buffer
|
||||||
call := funcs[fn]
|
call := funcs[fn]
|
||||||
for call.target != nil {
|
for call.target != nil {
|
||||||
fmt.Fprintf(&err, "\n\t%v: called by %v", linestr(call.lineno), call.target.Func.Nname)
|
fmt.Fprintf(&err, "\n\t%v: called by %v", base.FmtPos(call.lineno), call.target.Func.Nname)
|
||||||
call = funcs[call.target]
|
call = funcs[call.target]
|
||||||
}
|
}
|
||||||
yyerrorl(fn.Func.WBPos, "write barrier prohibited by caller; %v%s", fn.Func.Nname, err.String())
|
base.ErrorfAt(fn.Func.WBPos, "write barrier prohibited by caller; %v%s", fn.Func.Nname, err.String())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/src"
|
"cmd/internal/src"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
@ -146,7 +147,7 @@ func (p *dumper) dump(x reflect.Value, depth int) {
|
||||||
x = reflect.ValueOf(v.Slice())
|
x = reflect.ValueOf(v.Slice())
|
||||||
|
|
||||||
case src.XPos:
|
case src.XPos:
|
||||||
p.printf("%s", linestr(v))
|
p.printf("%s", base.FmtPos(v))
|
||||||
return
|
return
|
||||||
|
|
||||||
case *types.Node:
|
case *types.Node:
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/internal/dwarf"
|
"cmd/internal/dwarf"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
"cmd/internal/src"
|
"cmd/internal/src"
|
||||||
|
|
@ -26,8 +27,8 @@ type varPos struct {
|
||||||
func assembleInlines(fnsym *obj.LSym, dwVars []*dwarf.Var) dwarf.InlCalls {
|
func assembleInlines(fnsym *obj.LSym, dwVars []*dwarf.Var) dwarf.InlCalls {
|
||||||
var inlcalls dwarf.InlCalls
|
var inlcalls dwarf.InlCalls
|
||||||
|
|
||||||
if Debug.DwarfInl != 0 {
|
if base.Debug.DwarfInl != 0 {
|
||||||
Ctxt.Logf("assembling DWARF inlined routine info for %v\n", fnsym.Name)
|
base.Ctxt.Logf("assembling DWARF inlined routine info for %v\n", fnsym.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// This maps inline index (from Ctxt.InlTree) to index in inlcalls.Calls
|
// This maps inline index (from Ctxt.InlTree) to index in inlcalls.Calls
|
||||||
|
|
@ -106,7 +107,7 @@ func assembleInlines(fnsym *obj.LSym, dwVars []*dwarf.Var) dwarf.InlCalls {
|
||||||
}
|
}
|
||||||
m = makePreinlineDclMap(fnsym)
|
m = makePreinlineDclMap(fnsym)
|
||||||
} else {
|
} else {
|
||||||
ifnlsym := Ctxt.InlTree.InlinedFunction(int(ii - 1))
|
ifnlsym := base.Ctxt.InlTree.InlinedFunction(int(ii - 1))
|
||||||
m = makePreinlineDclMap(ifnlsym)
|
m = makePreinlineDclMap(ifnlsym)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -181,7 +182,7 @@ func assembleInlines(fnsym *obj.LSym, dwVars []*dwarf.Var) dwarf.InlCalls {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debugging
|
// Debugging
|
||||||
if Debug.DwarfInl != 0 {
|
if base.Debug.DwarfInl != 0 {
|
||||||
dumpInlCalls(inlcalls)
|
dumpInlCalls(inlcalls)
|
||||||
dumpInlVars(dwVars)
|
dumpInlVars(dwVars)
|
||||||
}
|
}
|
||||||
|
|
@ -205,15 +206,15 @@ func assembleInlines(fnsym *obj.LSym, dwVars []*dwarf.Var) dwarf.InlCalls {
|
||||||
// abstract function DIE for an inlined routine imported from a
|
// abstract function DIE for an inlined routine imported from a
|
||||||
// previously compiled package.
|
// previously compiled package.
|
||||||
func genAbstractFunc(fn *obj.LSym) {
|
func genAbstractFunc(fn *obj.LSym) {
|
||||||
ifn := Ctxt.DwFixups.GetPrecursorFunc(fn)
|
ifn := base.Ctxt.DwFixups.GetPrecursorFunc(fn)
|
||||||
if ifn == nil {
|
if ifn == nil {
|
||||||
Ctxt.Diag("failed to locate precursor fn for %v", fn)
|
base.Ctxt.Diag("failed to locate precursor fn for %v", fn)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if Debug.DwarfInl != 0 {
|
if base.Debug.DwarfInl != 0 {
|
||||||
Ctxt.Logf("DwarfAbstractFunc(%v)\n", fn.Name)
|
base.Ctxt.Logf("DwarfAbstractFunc(%v)\n", fn.Name)
|
||||||
}
|
}
|
||||||
Ctxt.DwarfAbstractFunc(ifn, fn, Ctxt.Pkgpath)
|
base.Ctxt.DwarfAbstractFunc(ifn, fn, base.Ctxt.Pkgpath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Undo any versioning performed when a name was written
|
// Undo any versioning performed when a name was written
|
||||||
|
|
@ -235,7 +236,7 @@ func makePreinlineDclMap(fnsym *obj.LSym) map[varPos]int {
|
||||||
dcl := preInliningDcls(fnsym)
|
dcl := preInliningDcls(fnsym)
|
||||||
m := make(map[varPos]int)
|
m := make(map[varPos]int)
|
||||||
for i, n := range dcl {
|
for i, n := range dcl {
|
||||||
pos := Ctxt.InnermostPos(n.Pos)
|
pos := base.Ctxt.InnermostPos(n.Pos)
|
||||||
vp := varPos{
|
vp := varPos{
|
||||||
DeclName: unversion(n.Sym.Name),
|
DeclName: unversion(n.Sym.Name),
|
||||||
DeclFile: pos.RelFilename(),
|
DeclFile: pos.RelFilename(),
|
||||||
|
|
@ -243,7 +244,7 @@ func makePreinlineDclMap(fnsym *obj.LSym) map[varPos]int {
|
||||||
DeclCol: pos.Col(),
|
DeclCol: pos.Col(),
|
||||||
}
|
}
|
||||||
if _, found := m[vp]; found {
|
if _, found := m[vp]; found {
|
||||||
Fatalf("child dcl collision on symbol %s within %v\n", n.Sym.Name, fnsym.Name)
|
base.Fatalf("child dcl collision on symbol %s within %v\n", n.Sym.Name, fnsym.Name)
|
||||||
}
|
}
|
||||||
m[vp] = i
|
m[vp] = i
|
||||||
}
|
}
|
||||||
|
|
@ -260,17 +261,17 @@ func insertInlCall(dwcalls *dwarf.InlCalls, inlIdx int, imap map[int]int) int {
|
||||||
// is one. We do this first so that parents appear before their
|
// is one. We do this first so that parents appear before their
|
||||||
// children in the resulting table.
|
// children in the resulting table.
|
||||||
parCallIdx := -1
|
parCallIdx := -1
|
||||||
parInlIdx := Ctxt.InlTree.Parent(inlIdx)
|
parInlIdx := base.Ctxt.InlTree.Parent(inlIdx)
|
||||||
if parInlIdx >= 0 {
|
if parInlIdx >= 0 {
|
||||||
parCallIdx = insertInlCall(dwcalls, parInlIdx, imap)
|
parCallIdx = insertInlCall(dwcalls, parInlIdx, imap)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create new entry for this inline
|
// Create new entry for this inline
|
||||||
inlinedFn := Ctxt.InlTree.InlinedFunction(inlIdx)
|
inlinedFn := base.Ctxt.InlTree.InlinedFunction(inlIdx)
|
||||||
callXPos := Ctxt.InlTree.CallPos(inlIdx)
|
callXPos := base.Ctxt.InlTree.CallPos(inlIdx)
|
||||||
absFnSym := Ctxt.DwFixups.AbsFuncDwarfSym(inlinedFn)
|
absFnSym := base.Ctxt.DwFixups.AbsFuncDwarfSym(inlinedFn)
|
||||||
pb := Ctxt.PosTable.Pos(callXPos).Base()
|
pb := base.Ctxt.PosTable.Pos(callXPos).Base()
|
||||||
callFileSym := Ctxt.Lookup(pb.SymFilename())
|
callFileSym := base.Ctxt.Lookup(pb.SymFilename())
|
||||||
ic := dwarf.InlCall{
|
ic := dwarf.InlCall{
|
||||||
InlIndex: inlIdx,
|
InlIndex: inlIdx,
|
||||||
CallFile: callFileSym,
|
CallFile: callFileSym,
|
||||||
|
|
@ -298,7 +299,7 @@ func insertInlCall(dwcalls *dwarf.InlCalls, inlIdx int, imap map[int]int) int {
|
||||||
// the index for a node from the inlined body of D will refer to the
|
// the index for a node from the inlined body of D will refer to the
|
||||||
// call to D from C. Whew.
|
// call to D from C. Whew.
|
||||||
func posInlIndex(xpos src.XPos) int {
|
func posInlIndex(xpos src.XPos) int {
|
||||||
pos := Ctxt.PosTable.Pos(xpos)
|
pos := base.Ctxt.PosTable.Pos(xpos)
|
||||||
if b := pos.Base(); b != nil {
|
if b := pos.Base(); b != nil {
|
||||||
ii := b.InliningIndex()
|
ii := b.InliningIndex()
|
||||||
if ii >= 0 {
|
if ii >= 0 {
|
||||||
|
|
@ -324,7 +325,7 @@ func addRange(calls []dwarf.InlCall, start, end int64, ii int, imap map[int]int)
|
||||||
// Append range to correct inlined call
|
// Append range to correct inlined call
|
||||||
callIdx, found := imap[ii]
|
callIdx, found := imap[ii]
|
||||||
if !found {
|
if !found {
|
||||||
Fatalf("can't find inlIndex %d in imap for prog at %d\n", ii, start)
|
base.Fatalf("can't find inlIndex %d in imap for prog at %d\n", ii, start)
|
||||||
}
|
}
|
||||||
call := &calls[callIdx]
|
call := &calls[callIdx]
|
||||||
call.Ranges = append(call.Ranges, dwarf.Range{Start: start, End: end})
|
call.Ranges = append(call.Ranges, dwarf.Range{Start: start, End: end})
|
||||||
|
|
@ -332,23 +333,23 @@ func addRange(calls []dwarf.InlCall, start, end int64, ii int, imap map[int]int)
|
||||||
|
|
||||||
func dumpInlCall(inlcalls dwarf.InlCalls, idx, ilevel int) {
|
func dumpInlCall(inlcalls dwarf.InlCalls, idx, ilevel int) {
|
||||||
for i := 0; i < ilevel; i++ {
|
for i := 0; i < ilevel; i++ {
|
||||||
Ctxt.Logf(" ")
|
base.Ctxt.Logf(" ")
|
||||||
}
|
}
|
||||||
ic := inlcalls.Calls[idx]
|
ic := inlcalls.Calls[idx]
|
||||||
callee := Ctxt.InlTree.InlinedFunction(ic.InlIndex)
|
callee := base.Ctxt.InlTree.InlinedFunction(ic.InlIndex)
|
||||||
Ctxt.Logf(" %d: II:%d (%s) V: (", idx, ic.InlIndex, callee.Name)
|
base.Ctxt.Logf(" %d: II:%d (%s) V: (", idx, ic.InlIndex, callee.Name)
|
||||||
for _, f := range ic.InlVars {
|
for _, f := range ic.InlVars {
|
||||||
Ctxt.Logf(" %v", f.Name)
|
base.Ctxt.Logf(" %v", f.Name)
|
||||||
}
|
}
|
||||||
Ctxt.Logf(" ) C: (")
|
base.Ctxt.Logf(" ) C: (")
|
||||||
for _, k := range ic.Children {
|
for _, k := range ic.Children {
|
||||||
Ctxt.Logf(" %v", k)
|
base.Ctxt.Logf(" %v", k)
|
||||||
}
|
}
|
||||||
Ctxt.Logf(" ) R:")
|
base.Ctxt.Logf(" ) R:")
|
||||||
for _, r := range ic.Ranges {
|
for _, r := range ic.Ranges {
|
||||||
Ctxt.Logf(" [%d,%d)", r.Start, r.End)
|
base.Ctxt.Logf(" [%d,%d)", r.Start, r.End)
|
||||||
}
|
}
|
||||||
Ctxt.Logf("\n")
|
base.Ctxt.Logf("\n")
|
||||||
for _, k := range ic.Children {
|
for _, k := range ic.Children {
|
||||||
dumpInlCall(inlcalls, k, ilevel+1)
|
dumpInlCall(inlcalls, k, ilevel+1)
|
||||||
}
|
}
|
||||||
|
|
@ -373,7 +374,7 @@ func dumpInlVars(dwvars []*dwarf.Var) {
|
||||||
if dwv.IsInAbstract {
|
if dwv.IsInAbstract {
|
||||||
ia = 1
|
ia = 1
|
||||||
}
|
}
|
||||||
Ctxt.Logf("V%d: %s CI:%d II:%d IA:%d %s\n", i, dwv.Name, dwv.ChildIndex, dwv.InlIndex-1, ia, typ)
|
base.Ctxt.Logf("V%d: %s CI:%d II:%d IA:%d %s\n", i, dwv.Name, dwv.ChildIndex, dwv.InlIndex-1, ia, typ)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -410,7 +411,7 @@ func checkInlCall(funcName string, inlCalls dwarf.InlCalls, funcSize int64, idx,
|
||||||
|
|
||||||
// Callee
|
// Callee
|
||||||
ic := inlCalls.Calls[idx]
|
ic := inlCalls.Calls[idx]
|
||||||
callee := Ctxt.InlTree.InlinedFunction(ic.InlIndex).Name
|
callee := base.Ctxt.InlTree.InlinedFunction(ic.InlIndex).Name
|
||||||
calleeRanges := ic.Ranges
|
calleeRanges := ic.Ranges
|
||||||
|
|
||||||
// Caller
|
// Caller
|
||||||
|
|
@ -418,14 +419,14 @@ func checkInlCall(funcName string, inlCalls dwarf.InlCalls, funcSize int64, idx,
|
||||||
parentRanges := []dwarf.Range{dwarf.Range{Start: int64(0), End: funcSize}}
|
parentRanges := []dwarf.Range{dwarf.Range{Start: int64(0), End: funcSize}}
|
||||||
if parentIdx != -1 {
|
if parentIdx != -1 {
|
||||||
pic := inlCalls.Calls[parentIdx]
|
pic := inlCalls.Calls[parentIdx]
|
||||||
caller = Ctxt.InlTree.InlinedFunction(pic.InlIndex).Name
|
caller = base.Ctxt.InlTree.InlinedFunction(pic.InlIndex).Name
|
||||||
parentRanges = pic.Ranges
|
parentRanges = pic.Ranges
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callee ranges contained in caller ranges?
|
// Callee ranges contained in caller ranges?
|
||||||
c, m := rangesContainsAll(parentRanges, calleeRanges)
|
c, m := rangesContainsAll(parentRanges, calleeRanges)
|
||||||
if !c {
|
if !c {
|
||||||
Fatalf("** malformed inlined routine range in %s: caller %s callee %s II=%d %s\n", funcName, caller, callee, idx, m)
|
base.Fatalf("** malformed inlined routine range in %s: caller %s callee %s II=%d %s\n", funcName, caller, callee, idx, m)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now visit kids
|
// Now visit kids
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/syntax"
|
"cmd/compile/internal/syntax"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
|
|
@ -43,30 +44,30 @@ func varEmbed(p *noder, names []*Node, typ *Node, exprs []*Node, embeds []Pragma
|
||||||
|
|
||||||
pos := embeds[0].Pos
|
pos := embeds[0].Pos
|
||||||
if !haveEmbed {
|
if !haveEmbed {
|
||||||
p.yyerrorpos(pos, "invalid go:embed: missing import \"embed\"")
|
p.errorAt(pos, "invalid go:embed: missing import \"embed\"")
|
||||||
return exprs
|
return exprs
|
||||||
}
|
}
|
||||||
if Flag.Cfg.Embed.Patterns == nil {
|
if base.Flag.Cfg.Embed.Patterns == nil {
|
||||||
p.yyerrorpos(pos, "invalid go:embed: build system did not supply embed configuration")
|
p.errorAt(pos, "invalid go:embed: build system did not supply embed configuration")
|
||||||
return exprs
|
return exprs
|
||||||
}
|
}
|
||||||
if len(names) > 1 {
|
if len(names) > 1 {
|
||||||
p.yyerrorpos(pos, "go:embed cannot apply to multiple vars")
|
p.errorAt(pos, "go:embed cannot apply to multiple vars")
|
||||||
return exprs
|
return exprs
|
||||||
}
|
}
|
||||||
if len(exprs) > 0 {
|
if len(exprs) > 0 {
|
||||||
p.yyerrorpos(pos, "go:embed cannot apply to var with initializer")
|
p.errorAt(pos, "go:embed cannot apply to var with initializer")
|
||||||
return exprs
|
return exprs
|
||||||
}
|
}
|
||||||
if typ == nil {
|
if typ == nil {
|
||||||
// Should not happen, since len(exprs) == 0 now.
|
// Should not happen, since len(exprs) == 0 now.
|
||||||
p.yyerrorpos(pos, "go:embed cannot apply to var without type")
|
p.errorAt(pos, "go:embed cannot apply to var without type")
|
||||||
return exprs
|
return exprs
|
||||||
}
|
}
|
||||||
|
|
||||||
kind := embedKindApprox(typ)
|
kind := embedKindApprox(typ)
|
||||||
if kind == embedUnknown {
|
if kind == embedUnknown {
|
||||||
p.yyerrorpos(pos, "go:embed cannot apply to var of type %v", typ)
|
p.errorAt(pos, "go:embed cannot apply to var of type %v", typ)
|
||||||
return exprs
|
return exprs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -75,13 +76,13 @@ func varEmbed(p *noder, names []*Node, typ *Node, exprs []*Node, embeds []Pragma
|
||||||
var list []string
|
var list []string
|
||||||
for _, e := range embeds {
|
for _, e := range embeds {
|
||||||
for _, pattern := range e.Patterns {
|
for _, pattern := range e.Patterns {
|
||||||
files, ok := Flag.Cfg.Embed.Patterns[pattern]
|
files, ok := base.Flag.Cfg.Embed.Patterns[pattern]
|
||||||
if !ok {
|
if !ok {
|
||||||
p.yyerrorpos(e.Pos, "invalid go:embed: build system did not map pattern: %s", pattern)
|
p.errorAt(e.Pos, "invalid go:embed: build system did not map pattern: %s", pattern)
|
||||||
}
|
}
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
if Flag.Cfg.Embed.Files[file] == "" {
|
if base.Flag.Cfg.Embed.Files[file] == "" {
|
||||||
p.yyerrorpos(e.Pos, "invalid go:embed: build system did not map file: %s", file)
|
p.errorAt(e.Pos, "invalid go:embed: build system did not map file: %s", file)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !have[file] {
|
if !have[file] {
|
||||||
|
|
@ -103,7 +104,7 @@ func varEmbed(p *noder, names []*Node, typ *Node, exprs []*Node, embeds []Pragma
|
||||||
|
|
||||||
if kind == embedString || kind == embedBytes {
|
if kind == embedString || kind == embedBytes {
|
||||||
if len(list) > 1 {
|
if len(list) > 1 {
|
||||||
p.yyerrorpos(pos, "invalid go:embed: multiple files for type %v", typ)
|
p.errorAt(pos, "invalid go:embed: multiple files for type %v", typ)
|
||||||
return exprs
|
return exprs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -129,7 +130,7 @@ func varEmbed(p *noder, names []*Node, typ *Node, exprs []*Node, embeds []Pragma
|
||||||
// can't tell whether "string" and "byte" really mean "string" and "byte".
|
// can't tell whether "string" and "byte" really mean "string" and "byte".
|
||||||
// The result must be confirmed later, after type checking, using embedKind.
|
// The result must be confirmed later, after type checking, using embedKind.
|
||||||
func embedKindApprox(typ *Node) int {
|
func embedKindApprox(typ *Node) int {
|
||||||
if typ.Sym != nil && typ.Sym.Name == "FS" && (typ.Sym.Pkg.Path == "embed" || (typ.Sym.Pkg == localpkg && Ctxt.Pkgpath == "embed")) {
|
if typ.Sym != nil && typ.Sym.Name == "FS" && (typ.Sym.Pkg.Path == "embed" || (typ.Sym.Pkg == localpkg && base.Ctxt.Pkgpath == "embed")) {
|
||||||
return embedFiles
|
return embedFiles
|
||||||
}
|
}
|
||||||
// These are not guaranteed to match only string and []byte -
|
// These are not guaranteed to match only string and []byte -
|
||||||
|
|
@ -147,7 +148,7 @@ func embedKindApprox(typ *Node) int {
|
||||||
|
|
||||||
// embedKind determines the kind of embedding variable.
|
// embedKind determines the kind of embedding variable.
|
||||||
func embedKind(typ *types.Type) int {
|
func embedKind(typ *types.Type) int {
|
||||||
if typ.Sym != nil && typ.Sym.Name == "FS" && (typ.Sym.Pkg.Path == "embed" || (typ.Sym.Pkg == localpkg && Ctxt.Pkgpath == "embed")) {
|
if typ.Sym != nil && typ.Sym.Name == "FS" && (typ.Sym.Pkg.Path == "embed" || (typ.Sym.Pkg == localpkg && base.Ctxt.Pkgpath == "embed")) {
|
||||||
return embedFiles
|
return embedFiles
|
||||||
}
|
}
|
||||||
if typ == types.Types[TSTRING] {
|
if typ == types.Types[TSTRING] {
|
||||||
|
|
@ -194,13 +195,13 @@ func initEmbed(v *Node) {
|
||||||
files := v.Name.Param.EmbedFiles()
|
files := v.Name.Param.EmbedFiles()
|
||||||
switch kind := embedKind(v.Type); kind {
|
switch kind := embedKind(v.Type); kind {
|
||||||
case embedUnknown:
|
case embedUnknown:
|
||||||
yyerrorl(v.Pos, "go:embed cannot apply to var of type %v", v.Type)
|
base.ErrorfAt(v.Pos, "go:embed cannot apply to var of type %v", v.Type)
|
||||||
|
|
||||||
case embedString, embedBytes:
|
case embedString, embedBytes:
|
||||||
file := files[0]
|
file := files[0]
|
||||||
fsym, size, err := fileStringSym(v.Pos, Flag.Cfg.Embed.Files[file], kind == embedString, nil)
|
fsym, size, err := fileStringSym(v.Pos, base.Flag.Cfg.Embed.Files[file], kind == embedString, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
yyerrorl(v.Pos, "embed %s: %v", file, err)
|
base.ErrorfAt(v.Pos, "embed %s: %v", file, err)
|
||||||
}
|
}
|
||||||
sym := v.Sym.Linksym()
|
sym := v.Sym.Linksym()
|
||||||
off := 0
|
off := 0
|
||||||
|
|
@ -211,7 +212,7 @@ func initEmbed(v *Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case embedFiles:
|
case embedFiles:
|
||||||
slicedata := Ctxt.Lookup(`"".` + v.Sym.Name + `.files`)
|
slicedata := base.Ctxt.Lookup(`"".` + v.Sym.Name + `.files`)
|
||||||
off := 0
|
off := 0
|
||||||
// []files pointed at by Files
|
// []files pointed at by Files
|
||||||
off = dsymptr(slicedata, off, slicedata, 3*Widthptr) // []file, pointing just past slice
|
off = dsymptr(slicedata, off, slicedata, 3*Widthptr) // []file, pointing just past slice
|
||||||
|
|
@ -234,13 +235,13 @@ func initEmbed(v *Node) {
|
||||||
off = duintptr(slicedata, off, 0)
|
off = duintptr(slicedata, off, 0)
|
||||||
off += hashSize
|
off += hashSize
|
||||||
} else {
|
} else {
|
||||||
fsym, size, err := fileStringSym(v.Pos, Flag.Cfg.Embed.Files[file], true, hash)
|
fsym, size, err := fileStringSym(v.Pos, base.Flag.Cfg.Embed.Files[file], true, hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
yyerrorl(v.Pos, "embed %s: %v", file, err)
|
base.ErrorfAt(v.Pos, "embed %s: %v", file, err)
|
||||||
}
|
}
|
||||||
off = dsymptr(slicedata, off, fsym, 0) // data string
|
off = dsymptr(slicedata, off, fsym, 0) // data string
|
||||||
off = duintptr(slicedata, off, uint64(size))
|
off = duintptr(slicedata, off, uint64(size))
|
||||||
off = int(slicedata.WriteBytes(Ctxt, int64(off), hash))
|
off = int(slicedata.WriteBytes(base.Ctxt, int64(off), hash))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ggloblsym(slicedata, int32(off), obj.RODATA|obj.LOCAL)
|
ggloblsym(slicedata, int32(off), obj.RODATA|obj.LOCAL)
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
@ -263,11 +264,11 @@ func addrescapes(n *Node) {
|
||||||
Curfn = Curfn.Func.Decl
|
Curfn = Curfn.Func.Decl
|
||||||
panic("can't happen")
|
panic("can't happen")
|
||||||
}
|
}
|
||||||
ln := lineno
|
ln := base.Pos
|
||||||
lineno = Curfn.Pos
|
base.Pos = Curfn.Pos
|
||||||
moveToHeap(n)
|
moveToHeap(n)
|
||||||
Curfn = oldfn
|
Curfn = oldfn
|
||||||
lineno = ln
|
base.Pos = ln
|
||||||
|
|
||||||
// ODOTPTR has already been introduced,
|
// ODOTPTR has already been introduced,
|
||||||
// so these are the non-pointer ODOT and OINDEX.
|
// so these are the non-pointer ODOT and OINDEX.
|
||||||
|
|
@ -283,15 +284,15 @@ func addrescapes(n *Node) {
|
||||||
|
|
||||||
// moveToHeap records the parameter or local variable n as moved to the heap.
|
// moveToHeap records the parameter or local variable n as moved to the heap.
|
||||||
func moveToHeap(n *Node) {
|
func moveToHeap(n *Node) {
|
||||||
if Flag.LowerR != 0 {
|
if base.Flag.LowerR != 0 {
|
||||||
Dump("MOVE", n)
|
Dump("MOVE", n)
|
||||||
}
|
}
|
||||||
if Flag.CompilingRuntime {
|
if base.Flag.CompilingRuntime {
|
||||||
yyerror("%v escapes to heap, not allowed in runtime", n)
|
base.Errorf("%v escapes to heap, not allowed in runtime", n)
|
||||||
}
|
}
|
||||||
if n.Class() == PAUTOHEAP {
|
if n.Class() == PAUTOHEAP {
|
||||||
Dump("n", n)
|
Dump("n", n)
|
||||||
Fatalf("double move to heap")
|
base.Fatalf("double move to heap")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate a local stack variable to hold the pointer to the heap copy.
|
// Allocate a local stack variable to hold the pointer to the heap copy.
|
||||||
|
|
@ -311,7 +312,7 @@ func moveToHeap(n *Node) {
|
||||||
// the function.
|
// the function.
|
||||||
if n.Class() == PPARAM || n.Class() == PPARAMOUT {
|
if n.Class() == PPARAM || n.Class() == PPARAMOUT {
|
||||||
if n.Xoffset == BADWIDTH {
|
if n.Xoffset == BADWIDTH {
|
||||||
Fatalf("addrescapes before param assignment")
|
base.Fatalf("addrescapes before param assignment")
|
||||||
}
|
}
|
||||||
|
|
||||||
// We rewrite n below to be a heap variable (indirection of heapaddr).
|
// We rewrite n below to be a heap variable (indirection of heapaddr).
|
||||||
|
|
@ -350,7 +351,7 @@ func moveToHeap(n *Node) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !found {
|
if !found {
|
||||||
Fatalf("cannot find %v in local variable list", n)
|
base.Fatalf("cannot find %v in local variable list", n)
|
||||||
}
|
}
|
||||||
Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
|
Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
|
||||||
}
|
}
|
||||||
|
|
@ -360,8 +361,8 @@ func moveToHeap(n *Node) {
|
||||||
n.Xoffset = 0
|
n.Xoffset = 0
|
||||||
n.Name.Param.Heapaddr = heapaddr
|
n.Name.Param.Heapaddr = heapaddr
|
||||||
n.Esc = EscHeap
|
n.Esc = EscHeap
|
||||||
if Flag.LowerM != 0 {
|
if base.Flag.LowerM != 0 {
|
||||||
Warnl(n.Pos, "moved to heap: %v", n)
|
base.WarnfAt(n.Pos, "moved to heap: %v", n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -390,8 +391,8 @@ func (e *Escape) paramTag(fn *Node, narg int, f *types.Field) string {
|
||||||
// but we are reusing the ability to annotate an individual function
|
// but we are reusing the ability to annotate an individual function
|
||||||
// argument and pass those annotations along to importing code.
|
// argument and pass those annotations along to importing code.
|
||||||
if f.Type.IsUintptr() {
|
if f.Type.IsUintptr() {
|
||||||
if Flag.LowerM != 0 {
|
if base.Flag.LowerM != 0 {
|
||||||
Warnl(f.Pos, "assuming %v is unsafe uintptr", name())
|
base.WarnfAt(f.Pos, "assuming %v is unsafe uintptr", name())
|
||||||
}
|
}
|
||||||
return unsafeUintptrTag
|
return unsafeUintptrTag
|
||||||
}
|
}
|
||||||
|
|
@ -405,12 +406,12 @@ func (e *Escape) paramTag(fn *Node, narg int, f *types.Field) string {
|
||||||
// External functions are assumed unsafe, unless
|
// External functions are assumed unsafe, unless
|
||||||
// //go:noescape is given before the declaration.
|
// //go:noescape is given before the declaration.
|
||||||
if fn.Func.Pragma&Noescape != 0 {
|
if fn.Func.Pragma&Noescape != 0 {
|
||||||
if Flag.LowerM != 0 && f.Sym != nil {
|
if base.Flag.LowerM != 0 && f.Sym != nil {
|
||||||
Warnl(f.Pos, "%v does not escape", name())
|
base.WarnfAt(f.Pos, "%v does not escape", name())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if Flag.LowerM != 0 && f.Sym != nil {
|
if base.Flag.LowerM != 0 && f.Sym != nil {
|
||||||
Warnl(f.Pos, "leaking param: %v", name())
|
base.WarnfAt(f.Pos, "leaking param: %v", name())
|
||||||
}
|
}
|
||||||
esc.AddHeap(0)
|
esc.AddHeap(0)
|
||||||
}
|
}
|
||||||
|
|
@ -420,15 +421,15 @@ func (e *Escape) paramTag(fn *Node, narg int, f *types.Field) string {
|
||||||
|
|
||||||
if fn.Func.Pragma&UintptrEscapes != 0 {
|
if fn.Func.Pragma&UintptrEscapes != 0 {
|
||||||
if f.Type.IsUintptr() {
|
if f.Type.IsUintptr() {
|
||||||
if Flag.LowerM != 0 {
|
if base.Flag.LowerM != 0 {
|
||||||
Warnl(f.Pos, "marking %v as escaping uintptr", name())
|
base.WarnfAt(f.Pos, "marking %v as escaping uintptr", name())
|
||||||
}
|
}
|
||||||
return uintptrEscapesTag
|
return uintptrEscapesTag
|
||||||
}
|
}
|
||||||
if f.IsDDD() && f.Type.Elem().IsUintptr() {
|
if f.IsDDD() && f.Type.Elem().IsUintptr() {
|
||||||
// final argument is ...uintptr.
|
// final argument is ...uintptr.
|
||||||
if Flag.LowerM != 0 {
|
if base.Flag.LowerM != 0 {
|
||||||
Warnl(f.Pos, "marking %v as escaping ...uintptr", name())
|
base.WarnfAt(f.Pos, "marking %v as escaping ...uintptr", name())
|
||||||
}
|
}
|
||||||
return uintptrEscapesTag
|
return uintptrEscapesTag
|
||||||
}
|
}
|
||||||
|
|
@ -449,22 +450,22 @@ func (e *Escape) paramTag(fn *Node, narg int, f *types.Field) string {
|
||||||
esc := loc.paramEsc
|
esc := loc.paramEsc
|
||||||
esc.Optimize()
|
esc.Optimize()
|
||||||
|
|
||||||
if Flag.LowerM != 0 && !loc.escapes {
|
if base.Flag.LowerM != 0 && !loc.escapes {
|
||||||
if esc.Empty() {
|
if esc.Empty() {
|
||||||
Warnl(f.Pos, "%v does not escape", name())
|
base.WarnfAt(f.Pos, "%v does not escape", name())
|
||||||
}
|
}
|
||||||
if x := esc.Heap(); x >= 0 {
|
if x := esc.Heap(); x >= 0 {
|
||||||
if x == 0 {
|
if x == 0 {
|
||||||
Warnl(f.Pos, "leaking param: %v", name())
|
base.WarnfAt(f.Pos, "leaking param: %v", name())
|
||||||
} else {
|
} else {
|
||||||
// TODO(mdempsky): Mention level=x like below?
|
// TODO(mdempsky): Mention level=x like below?
|
||||||
Warnl(f.Pos, "leaking param content: %v", name())
|
base.WarnfAt(f.Pos, "leaking param content: %v", name())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i := 0; i < numEscResults; i++ {
|
for i := 0; i < numEscResults; i++ {
|
||||||
if x := esc.Result(i); x >= 0 {
|
if x := esc.Result(i); x >= 0 {
|
||||||
res := fn.Type.Results().Field(i).Sym
|
res := fn.Type.Results().Field(i).Sym
|
||||||
Warnl(f.Pos, "leaking param: %v to result %v level=%d", name(), res, x)
|
base.WarnfAt(f.Pos, "leaking param: %v to result %v level=%d", name(), res, x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/logopt"
|
"cmd/compile/internal/logopt"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/src"
|
"cmd/internal/src"
|
||||||
|
|
@ -180,7 +181,7 @@ func escFmt(n *Node, short bool) string {
|
||||||
func escapeFuncs(fns []*Node, recursive bool) {
|
func escapeFuncs(fns []*Node, recursive bool) {
|
||||||
for _, fn := range fns {
|
for _, fn := range fns {
|
||||||
if fn.Op != ODCLFUNC {
|
if fn.Op != ODCLFUNC {
|
||||||
Fatalf("unexpected node: %v", fn)
|
base.Fatalf("unexpected node: %v", fn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -202,10 +203,10 @@ func escapeFuncs(fns []*Node, recursive bool) {
|
||||||
|
|
||||||
func (e *Escape) initFunc(fn *Node) {
|
func (e *Escape) initFunc(fn *Node) {
|
||||||
if fn.Op != ODCLFUNC || fn.Esc != EscFuncUnknown {
|
if fn.Op != ODCLFUNC || fn.Esc != EscFuncUnknown {
|
||||||
Fatalf("unexpected node: %v", fn)
|
base.Fatalf("unexpected node: %v", fn)
|
||||||
}
|
}
|
||||||
fn.Esc = EscFuncPlanned
|
fn.Esc = EscFuncPlanned
|
||||||
if Flag.LowerM > 3 {
|
if base.Flag.LowerM > 3 {
|
||||||
Dump("escAnalyze", fn)
|
Dump("escAnalyze", fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -279,18 +280,18 @@ func (e *Escape) stmt(n *Node) {
|
||||||
|
|
||||||
lno := setlineno(n)
|
lno := setlineno(n)
|
||||||
defer func() {
|
defer func() {
|
||||||
lineno = lno
|
base.Pos = lno
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if Flag.LowerM > 2 {
|
if base.Flag.LowerM > 2 {
|
||||||
fmt.Printf("%v:[%d] %v stmt: %v\n", linestr(lineno), e.loopDepth, funcSym(e.curfn), n)
|
fmt.Printf("%v:[%d] %v stmt: %v\n", base.FmtPos(base.Pos), e.loopDepth, funcSym(e.curfn), n)
|
||||||
}
|
}
|
||||||
|
|
||||||
e.stmts(n.Ninit)
|
e.stmts(n.Ninit)
|
||||||
|
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
default:
|
default:
|
||||||
Fatalf("unexpected stmt: %v", n)
|
base.Fatalf("unexpected stmt: %v", n)
|
||||||
|
|
||||||
case ODCLCONST, ODCLTYPE, OEMPTY, OFALL, OINLMARK:
|
case ODCLCONST, ODCLTYPE, OEMPTY, OFALL, OINLMARK:
|
||||||
// nop
|
// nop
|
||||||
|
|
@ -310,16 +311,16 @@ func (e *Escape) stmt(n *Node) {
|
||||||
case OLABEL:
|
case OLABEL:
|
||||||
switch asNode(n.Sym.Label) {
|
switch asNode(n.Sym.Label) {
|
||||||
case nonlooping:
|
case nonlooping:
|
||||||
if Flag.LowerM > 2 {
|
if base.Flag.LowerM > 2 {
|
||||||
fmt.Printf("%v:%v non-looping label\n", linestr(lineno), n)
|
fmt.Printf("%v:%v non-looping label\n", base.FmtPos(base.Pos), n)
|
||||||
}
|
}
|
||||||
case looping:
|
case looping:
|
||||||
if Flag.LowerM > 2 {
|
if base.Flag.LowerM > 2 {
|
||||||
fmt.Printf("%v: %v looping label\n", linestr(lineno), n)
|
fmt.Printf("%v: %v looping label\n", base.FmtPos(base.Pos), n)
|
||||||
}
|
}
|
||||||
e.loopDepth++
|
e.loopDepth++
|
||||||
default:
|
default:
|
||||||
Fatalf("label missing tag")
|
base.Fatalf("label missing tag")
|
||||||
}
|
}
|
||||||
n.Sym.Label = nil
|
n.Sym.Label = nil
|
||||||
|
|
||||||
|
|
@ -460,7 +461,7 @@ func (e *Escape) exprSkipInit(k EscHole, n *Node) {
|
||||||
|
|
||||||
lno := setlineno(n)
|
lno := setlineno(n)
|
||||||
defer func() {
|
defer func() {
|
||||||
lineno = lno
|
base.Pos = lno
|
||||||
}()
|
}()
|
||||||
|
|
||||||
uintptrEscapesHack := k.uintptrEscapesHack
|
uintptrEscapesHack := k.uintptrEscapesHack
|
||||||
|
|
@ -474,7 +475,7 @@ func (e *Escape) exprSkipInit(k EscHole, n *Node) {
|
||||||
|
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
default:
|
default:
|
||||||
Fatalf("unexpected expr: %v", n)
|
base.Fatalf("unexpected expr: %v", n)
|
||||||
|
|
||||||
case OLITERAL, ONIL, OGETG, OCLOSUREVAR, OTYPE, OMETHEXPR:
|
case OLITERAL, ONIL, OGETG, OCLOSUREVAR, OTYPE, OMETHEXPR:
|
||||||
// nop
|
// nop
|
||||||
|
|
@ -653,7 +654,7 @@ func (e *Escape) exprSkipInit(k EscHole, n *Node) {
|
||||||
// for conversions from an unsafe.Pointer.
|
// for conversions from an unsafe.Pointer.
|
||||||
func (e *Escape) unsafeValue(k EscHole, n *Node) {
|
func (e *Escape) unsafeValue(k EscHole, n *Node) {
|
||||||
if n.Type.Etype != TUINTPTR {
|
if n.Type.Etype != TUINTPTR {
|
||||||
Fatalf("unexpected type %v for %v", n.Type, n)
|
base.Fatalf("unexpected type %v for %v", n.Type, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
e.stmts(n.Ninit)
|
e.stmts(n.Ninit)
|
||||||
|
|
@ -711,7 +712,7 @@ func (e *Escape) addr(n *Node) EscHole {
|
||||||
|
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
default:
|
default:
|
||||||
Fatalf("unexpected addr: %v", n)
|
base.Fatalf("unexpected addr: %v", n)
|
||||||
case ONAME:
|
case ONAME:
|
||||||
if n.Class() == PEXTERN {
|
if n.Class() == PEXTERN {
|
||||||
break
|
break
|
||||||
|
|
@ -752,8 +753,8 @@ func (e *Escape) addrs(l Nodes) []EscHole {
|
||||||
func (e *Escape) assign(dst, src *Node, why string, where *Node) {
|
func (e *Escape) assign(dst, src *Node, why string, where *Node) {
|
||||||
// Filter out some no-op assignments for escape analysis.
|
// Filter out some no-op assignments for escape analysis.
|
||||||
ignore := dst != nil && src != nil && isSelfAssign(dst, src)
|
ignore := dst != nil && src != nil && isSelfAssign(dst, src)
|
||||||
if ignore && Flag.LowerM != 0 {
|
if ignore && base.Flag.LowerM != 0 {
|
||||||
Warnl(where.Pos, "%v ignoring self-assignment in %S", funcSym(e.curfn), where)
|
base.WarnfAt(where.Pos, "%v ignoring self-assignment in %S", funcSym(e.curfn), where)
|
||||||
}
|
}
|
||||||
|
|
||||||
k := e.addr(dst)
|
k := e.addr(dst)
|
||||||
|
|
@ -797,7 +798,7 @@ func (e *Escape) call(ks []EscHole, call, where *Node) {
|
||||||
|
|
||||||
switch call.Op {
|
switch call.Op {
|
||||||
default:
|
default:
|
||||||
Fatalf("unexpected call op: %v", call.Op)
|
base.Fatalf("unexpected call op: %v", call.Op)
|
||||||
|
|
||||||
case OCALLFUNC, OCALLMETH, OCALLINTER:
|
case OCALLFUNC, OCALLMETH, OCALLINTER:
|
||||||
fixVariadicCall(call)
|
fixVariadicCall(call)
|
||||||
|
|
@ -936,7 +937,7 @@ func (e *Escape) tagHole(ks []EscHole, fn *Node, param *types.Field) EscHole {
|
||||||
func (e *Escape) inMutualBatch(fn *Node) bool {
|
func (e *Escape) inMutualBatch(fn *Node) bool {
|
||||||
if fn.Name.Defn != nil && fn.Name.Defn.Esc < EscFuncTagged {
|
if fn.Name.Defn != nil && fn.Name.Defn.Esc < EscFuncTagged {
|
||||||
if fn.Name.Defn.Esc == EscFuncUnknown {
|
if fn.Name.Defn.Esc == EscFuncUnknown {
|
||||||
Fatalf("graph inconsistency")
|
base.Fatalf("graph inconsistency")
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
@ -964,9 +965,9 @@ type EscNote struct {
|
||||||
|
|
||||||
func (k EscHole) note(where *Node, why string) EscHole {
|
func (k EscHole) note(where *Node, why string) EscHole {
|
||||||
if where == nil || why == "" {
|
if where == nil || why == "" {
|
||||||
Fatalf("note: missing where/why")
|
base.Fatalf("note: missing where/why")
|
||||||
}
|
}
|
||||||
if Flag.LowerM >= 2 || logopt.Enabled() {
|
if base.Flag.LowerM >= 2 || logopt.Enabled() {
|
||||||
k.notes = &EscNote{
|
k.notes = &EscNote{
|
||||||
next: k.notes,
|
next: k.notes,
|
||||||
where: where,
|
where: where,
|
||||||
|
|
@ -979,7 +980,7 @@ func (k EscHole) note(where *Node, why string) EscHole {
|
||||||
func (k EscHole) shift(delta int) EscHole {
|
func (k EscHole) shift(delta int) EscHole {
|
||||||
k.derefs += delta
|
k.derefs += delta
|
||||||
if k.derefs < -1 {
|
if k.derefs < -1 {
|
||||||
Fatalf("derefs underflow: %v", k.derefs)
|
base.Fatalf("derefs underflow: %v", k.derefs)
|
||||||
}
|
}
|
||||||
return k
|
return k
|
||||||
}
|
}
|
||||||
|
|
@ -1016,7 +1017,7 @@ func (e *Escape) teeHole(ks ...EscHole) EscHole {
|
||||||
// *ltmp" and "l2 = ltmp" and return "ltmp = &_"
|
// *ltmp" and "l2 = ltmp" and return "ltmp = &_"
|
||||||
// instead.
|
// instead.
|
||||||
if k.derefs < 0 {
|
if k.derefs < 0 {
|
||||||
Fatalf("teeHole: negative derefs")
|
base.Fatalf("teeHole: negative derefs")
|
||||||
}
|
}
|
||||||
|
|
||||||
e.flow(k, loc)
|
e.flow(k, loc)
|
||||||
|
|
@ -1054,7 +1055,7 @@ func canonicalNode(n *Node) *Node {
|
||||||
if n != nil && n.Op == ONAME && n.Name.IsClosureVar() {
|
if n != nil && n.Op == ONAME && n.Name.IsClosureVar() {
|
||||||
n = n.Name.Defn
|
n = n.Name.Defn
|
||||||
if n.Name.IsClosureVar() {
|
if n.Name.IsClosureVar() {
|
||||||
Fatalf("still closure var")
|
base.Fatalf("still closure var")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1063,10 +1064,10 @@ func canonicalNode(n *Node) *Node {
|
||||||
|
|
||||||
func (e *Escape) newLoc(n *Node, transient bool) *EscLocation {
|
func (e *Escape) newLoc(n *Node, transient bool) *EscLocation {
|
||||||
if e.curfn == nil {
|
if e.curfn == nil {
|
||||||
Fatalf("e.curfn isn't set")
|
base.Fatalf("e.curfn isn't set")
|
||||||
}
|
}
|
||||||
if n != nil && n.Type != nil && n.Type.NotInHeap() {
|
if n != nil && n.Type != nil && n.Type.NotInHeap() {
|
||||||
yyerrorl(n.Pos, "%v is incomplete (or unallocatable); stack allocation disallowed", n.Type)
|
base.ErrorfAt(n.Pos, "%v is incomplete (or unallocatable); stack allocation disallowed", n.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
n = canonicalNode(n)
|
n = canonicalNode(n)
|
||||||
|
|
@ -1079,11 +1080,11 @@ func (e *Escape) newLoc(n *Node, transient bool) *EscLocation {
|
||||||
e.allLocs = append(e.allLocs, loc)
|
e.allLocs = append(e.allLocs, loc)
|
||||||
if n != nil {
|
if n != nil {
|
||||||
if n.Op == ONAME && n.Name.Curfn != e.curfn {
|
if n.Op == ONAME && n.Name.Curfn != e.curfn {
|
||||||
Fatalf("curfn mismatch: %v != %v", n.Name.Curfn, e.curfn)
|
base.Fatalf("curfn mismatch: %v != %v", n.Name.Curfn, e.curfn)
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.HasOpt() {
|
if n.HasOpt() {
|
||||||
Fatalf("%v already has a location", n)
|
base.Fatalf("%v already has a location", n)
|
||||||
}
|
}
|
||||||
n.SetOpt(loc)
|
n.SetOpt(loc)
|
||||||
|
|
||||||
|
|
@ -1112,9 +1113,9 @@ func (e *Escape) flow(k EscHole, src *EscLocation) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if dst.escapes && k.derefs < 0 { // dst = &src
|
if dst.escapes && k.derefs < 0 { // dst = &src
|
||||||
if Flag.LowerM >= 2 || logopt.Enabled() {
|
if base.Flag.LowerM >= 2 || logopt.Enabled() {
|
||||||
pos := linestr(src.n.Pos)
|
pos := base.FmtPos(src.n.Pos)
|
||||||
if Flag.LowerM >= 2 {
|
if base.Flag.LowerM >= 2 {
|
||||||
fmt.Printf("%s: %v escapes to heap:\n", pos, src.n)
|
fmt.Printf("%s: %v escapes to heap:\n", pos, src.n)
|
||||||
}
|
}
|
||||||
explanation := e.explainFlow(pos, dst, src, k.derefs, k.notes, []*logopt.LoggedOpt{})
|
explanation := e.explainFlow(pos, dst, src, k.derefs, k.notes, []*logopt.LoggedOpt{})
|
||||||
|
|
@ -1214,9 +1215,9 @@ func (e *Escape) walkOne(root *EscLocation, walkgen uint32, enqueue func(*EscLoc
|
||||||
// that value flow for tagging the function
|
// that value flow for tagging the function
|
||||||
// later.
|
// later.
|
||||||
if l.isName(PPARAM) {
|
if l.isName(PPARAM) {
|
||||||
if (logopt.Enabled() || Flag.LowerM >= 2) && !l.escapes {
|
if (logopt.Enabled() || base.Flag.LowerM >= 2) && !l.escapes {
|
||||||
if Flag.LowerM >= 2 {
|
if base.Flag.LowerM >= 2 {
|
||||||
fmt.Printf("%s: parameter %v leaks to %s with derefs=%d:\n", linestr(l.n.Pos), l.n, e.explainLoc(root), derefs)
|
fmt.Printf("%s: parameter %v leaks to %s with derefs=%d:\n", base.FmtPos(l.n.Pos), l.n, e.explainLoc(root), derefs)
|
||||||
}
|
}
|
||||||
explanation := e.explainPath(root, l)
|
explanation := e.explainPath(root, l)
|
||||||
if logopt.Enabled() {
|
if logopt.Enabled() {
|
||||||
|
|
@ -1231,9 +1232,9 @@ func (e *Escape) walkOne(root *EscLocation, walkgen uint32, enqueue func(*EscLoc
|
||||||
// outlives it, then l needs to be heap
|
// outlives it, then l needs to be heap
|
||||||
// allocated.
|
// allocated.
|
||||||
if addressOf && !l.escapes {
|
if addressOf && !l.escapes {
|
||||||
if logopt.Enabled() || Flag.LowerM >= 2 {
|
if logopt.Enabled() || base.Flag.LowerM >= 2 {
|
||||||
if Flag.LowerM >= 2 {
|
if base.Flag.LowerM >= 2 {
|
||||||
fmt.Printf("%s: %v escapes to heap:\n", linestr(l.n.Pos), l.n)
|
fmt.Printf("%s: %v escapes to heap:\n", base.FmtPos(l.n.Pos), l.n)
|
||||||
}
|
}
|
||||||
explanation := e.explainPath(root, l)
|
explanation := e.explainPath(root, l)
|
||||||
if logopt.Enabled() {
|
if logopt.Enabled() {
|
||||||
|
|
@ -1265,12 +1266,12 @@ func (e *Escape) walkOne(root *EscLocation, walkgen uint32, enqueue func(*EscLoc
|
||||||
// explainPath prints an explanation of how src flows to the walk root.
|
// explainPath prints an explanation of how src flows to the walk root.
|
||||||
func (e *Escape) explainPath(root, src *EscLocation) []*logopt.LoggedOpt {
|
func (e *Escape) explainPath(root, src *EscLocation) []*logopt.LoggedOpt {
|
||||||
visited := make(map[*EscLocation]bool)
|
visited := make(map[*EscLocation]bool)
|
||||||
pos := linestr(src.n.Pos)
|
pos := base.FmtPos(src.n.Pos)
|
||||||
var explanation []*logopt.LoggedOpt
|
var explanation []*logopt.LoggedOpt
|
||||||
for {
|
for {
|
||||||
// Prevent infinite loop.
|
// Prevent infinite loop.
|
||||||
if visited[src] {
|
if visited[src] {
|
||||||
if Flag.LowerM >= 2 {
|
if base.Flag.LowerM >= 2 {
|
||||||
fmt.Printf("%s: warning: truncated explanation due to assignment cycle; see golang.org/issue/35518\n", pos)
|
fmt.Printf("%s: warning: truncated explanation due to assignment cycle; see golang.org/issue/35518\n", pos)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
|
@ -1279,7 +1280,7 @@ func (e *Escape) explainPath(root, src *EscLocation) []*logopt.LoggedOpt {
|
||||||
dst := src.dst
|
dst := src.dst
|
||||||
edge := &dst.edges[src.dstEdgeIdx]
|
edge := &dst.edges[src.dstEdgeIdx]
|
||||||
if edge.src != src {
|
if edge.src != src {
|
||||||
Fatalf("path inconsistency: %v != %v", edge.src, src)
|
base.Fatalf("path inconsistency: %v != %v", edge.src, src)
|
||||||
}
|
}
|
||||||
|
|
||||||
explanation = e.explainFlow(pos, dst, src, edge.derefs, edge.notes, explanation)
|
explanation = e.explainFlow(pos, dst, src, edge.derefs, edge.notes, explanation)
|
||||||
|
|
@ -1298,7 +1299,7 @@ func (e *Escape) explainFlow(pos string, dst, srcloc *EscLocation, derefs int, n
|
||||||
if derefs >= 0 {
|
if derefs >= 0 {
|
||||||
ops = strings.Repeat("*", derefs)
|
ops = strings.Repeat("*", derefs)
|
||||||
}
|
}
|
||||||
print := Flag.LowerM >= 2
|
print := base.Flag.LowerM >= 2
|
||||||
|
|
||||||
flow := fmt.Sprintf(" flow: %s = %s%v:", e.explainLoc(dst), ops, e.explainLoc(srcloc))
|
flow := fmt.Sprintf(" flow: %s = %s%v:", e.explainLoc(dst), ops, e.explainLoc(srcloc))
|
||||||
if print {
|
if print {
|
||||||
|
|
@ -1316,7 +1317,7 @@ func (e *Escape) explainFlow(pos string, dst, srcloc *EscLocation, derefs int, n
|
||||||
|
|
||||||
for note := notes; note != nil; note = note.next {
|
for note := notes; note != nil; note = note.next {
|
||||||
if print {
|
if print {
|
||||||
fmt.Printf("%s: from %v (%v) at %s\n", pos, note.where, note.why, linestr(note.where.Pos))
|
fmt.Printf("%s: from %v (%v) at %s\n", pos, note.where, note.why, base.FmtPos(note.where.Pos))
|
||||||
}
|
}
|
||||||
if logopt.Enabled() {
|
if logopt.Enabled() {
|
||||||
explanation = append(explanation, logopt.NewLoggedOpt(note.where.Pos, "escflow", "escape", e.curfn.funcname(),
|
explanation = append(explanation, logopt.NewLoggedOpt(note.where.Pos, "escflow", "escape", e.curfn.funcname(),
|
||||||
|
|
@ -1394,7 +1395,7 @@ func (e *Escape) outlives(l, other *EscLocation) bool {
|
||||||
// containsClosure reports whether c is a closure contained within f.
|
// containsClosure reports whether c is a closure contained within f.
|
||||||
func containsClosure(f, c *Node) bool {
|
func containsClosure(f, c *Node) bool {
|
||||||
if f.Op != ODCLFUNC || c.Op != ODCLFUNC {
|
if f.Op != ODCLFUNC || c.Op != ODCLFUNC {
|
||||||
Fatalf("bad containsClosure: %v, %v", f, c)
|
base.Fatalf("bad containsClosure: %v, %v", f, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Common case.
|
// Common case.
|
||||||
|
|
@ -1452,8 +1453,8 @@ func (e *Escape) finish(fns []*Node) {
|
||||||
|
|
||||||
if loc.escapes {
|
if loc.escapes {
|
||||||
if n.Op != ONAME {
|
if n.Op != ONAME {
|
||||||
if Flag.LowerM != 0 {
|
if base.Flag.LowerM != 0 {
|
||||||
Warnl(n.Pos, "%S escapes to heap", n)
|
base.WarnfAt(n.Pos, "%S escapes to heap", n)
|
||||||
}
|
}
|
||||||
if logopt.Enabled() {
|
if logopt.Enabled() {
|
||||||
logopt.LogOpt(n.Pos, "escape", "escape", e.curfn.funcname())
|
logopt.LogOpt(n.Pos, "escape", "escape", e.curfn.funcname())
|
||||||
|
|
@ -1462,8 +1463,8 @@ func (e *Escape) finish(fns []*Node) {
|
||||||
n.Esc = EscHeap
|
n.Esc = EscHeap
|
||||||
addrescapes(n)
|
addrescapes(n)
|
||||||
} else {
|
} else {
|
||||||
if Flag.LowerM != 0 && n.Op != ONAME {
|
if base.Flag.LowerM != 0 && n.Op != ONAME {
|
||||||
Warnl(n.Pos, "%S does not escape", n)
|
base.WarnfAt(n.Pos, "%S does not escape", n)
|
||||||
}
|
}
|
||||||
n.Esc = EscNone
|
n.Esc = EscNone
|
||||||
if loc.transient {
|
if loc.transient {
|
||||||
|
|
@ -1516,7 +1517,7 @@ func (l *EscLeaks) add(i, derefs int) {
|
||||||
func (l *EscLeaks) set(i, derefs int) {
|
func (l *EscLeaks) set(i, derefs int) {
|
||||||
v := derefs + 1
|
v := derefs + 1
|
||||||
if v < 0 {
|
if v < 0 {
|
||||||
Fatalf("invalid derefs count: %v", derefs)
|
base.Fatalf("invalid derefs count: %v", derefs)
|
||||||
}
|
}
|
||||||
if v > math.MaxUint8 {
|
if v > math.MaxUint8 {
|
||||||
v = math.MaxUint8
|
v = math.MaxUint8
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/bio"
|
"cmd/internal/bio"
|
||||||
"cmd/internal/src"
|
"cmd/internal/src"
|
||||||
|
|
@ -14,7 +15,7 @@ import (
|
||||||
|
|
||||||
func exportf(bout *bio.Writer, format string, args ...interface{}) {
|
func exportf(bout *bio.Writer, format string, args ...interface{}) {
|
||||||
fmt.Fprintf(bout, format, args...)
|
fmt.Fprintf(bout, format, args...)
|
||||||
if Debug.Export != 0 {
|
if base.Debug.Export != 0 {
|
||||||
fmt.Printf(format, args...)
|
fmt.Printf(format, args...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -28,7 +29,7 @@ func exportsym(n *Node) {
|
||||||
}
|
}
|
||||||
n.Sym.SetOnExportList(true)
|
n.Sym.SetOnExportList(true)
|
||||||
|
|
||||||
if Flag.E != 0 {
|
if base.Flag.E != 0 {
|
||||||
fmt.Printf("export symbol %v\n", n.Sym)
|
fmt.Printf("export symbol %v\n", n.Sym)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -53,7 +54,7 @@ func autoexport(n *Node, ctxt Class) {
|
||||||
if types.IsExported(n.Sym.Name) || initname(n.Sym.Name) {
|
if types.IsExported(n.Sym.Name) || initname(n.Sym.Name) {
|
||||||
exportsym(n)
|
exportsym(n)
|
||||||
}
|
}
|
||||||
if Flag.AsmHdr != "" && !n.Sym.Asm() {
|
if base.Flag.AsmHdr != "" && !n.Sym.Asm() {
|
||||||
n.Sym.SetAsm(true)
|
n.Sym.SetAsm(true)
|
||||||
asmlist = append(asmlist, n)
|
asmlist = append(asmlist, n)
|
||||||
}
|
}
|
||||||
|
|
@ -67,8 +68,8 @@ func dumpexport(bout *bio.Writer) {
|
||||||
size := bout.Offset() - off
|
size := bout.Offset() - off
|
||||||
exportf(bout, "\n$$\n")
|
exportf(bout, "\n$$\n")
|
||||||
|
|
||||||
if Debug.Export != 0 {
|
if base.Debug.Export != 0 {
|
||||||
fmt.Printf("BenchmarkExportSize:%s 1 %d bytes\n", Ctxt.Pkgpath, size)
|
fmt.Printf("BenchmarkExportSize:%s 1 %d bytes\n", base.Ctxt.Pkgpath, size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,7 +81,7 @@ func importsym(ipkg *types.Pkg, s *types.Sym, op Op) *Node {
|
||||||
// is declarations for Runtimepkg, which are populated
|
// is declarations for Runtimepkg, which are populated
|
||||||
// by loadsys instead.
|
// by loadsys instead.
|
||||||
if s.Pkg != Runtimepkg {
|
if s.Pkg != Runtimepkg {
|
||||||
Fatalf("missing ONONAME for %v\n", s)
|
base.Fatalf("missing ONONAME for %v\n", s)
|
||||||
}
|
}
|
||||||
|
|
||||||
n = dclname(s)
|
n = dclname(s)
|
||||||
|
|
@ -88,7 +89,7 @@ func importsym(ipkg *types.Pkg, s *types.Sym, op Op) *Node {
|
||||||
s.Importdef = ipkg
|
s.Importdef = ipkg
|
||||||
}
|
}
|
||||||
if n.Op != ONONAME && n.Op != op {
|
if n.Op != ONONAME && n.Op != op {
|
||||||
redeclare(lineno, s, fmt.Sprintf("during import %q", ipkg.Path))
|
redeclare(base.Pos, s, fmt.Sprintf("during import %q", ipkg.Path))
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
@ -111,7 +112,7 @@ func importtype(ipkg *types.Pkg, pos src.XPos, s *types.Sym) *types.Type {
|
||||||
|
|
||||||
t := n.Type
|
t := n.Type
|
||||||
if t == nil {
|
if t == nil {
|
||||||
Fatalf("importtype %v", s)
|
base.Fatalf("importtype %v", s)
|
||||||
}
|
}
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
@ -122,7 +123,7 @@ func importobj(ipkg *types.Pkg, pos src.XPos, s *types.Sym, op Op, ctxt Class, t
|
||||||
n := importsym(ipkg, s, op)
|
n := importsym(ipkg, s, op)
|
||||||
if n.Op != ONONAME {
|
if n.Op != ONONAME {
|
||||||
if n.Op == op && (n.Class() != ctxt || !types.Identical(n.Type, t)) {
|
if n.Op == op && (n.Class() != ctxt || !types.Identical(n.Type, t)) {
|
||||||
redeclare(lineno, s, fmt.Sprintf("during import %q", ipkg.Path))
|
redeclare(base.Pos, s, fmt.Sprintf("during import %q", ipkg.Path))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -147,7 +148,7 @@ func importconst(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type, val
|
||||||
|
|
||||||
n.SetVal(val)
|
n.SetVal(val)
|
||||||
|
|
||||||
if Flag.E != 0 {
|
if base.Flag.E != 0 {
|
||||||
fmt.Printf("import const %v %L = %v\n", s, t, val)
|
fmt.Printf("import const %v %L = %v\n", s, t, val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -162,7 +163,7 @@ func importfunc(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) {
|
||||||
|
|
||||||
n.Func = new(Func)
|
n.Func = new(Func)
|
||||||
|
|
||||||
if Flag.E != 0 {
|
if base.Flag.E != 0 {
|
||||||
fmt.Printf("import func %v%S\n", s, t)
|
fmt.Printf("import func %v%S\n", s, t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -175,7 +176,7 @@ func importvar(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if Flag.E != 0 {
|
if base.Flag.E != 0 {
|
||||||
fmt.Printf("import var %v %L\n", s, t)
|
fmt.Printf("import var %v %L\n", s, t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -188,15 +189,15 @@ func importalias(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if Flag.E != 0 {
|
if base.Flag.E != 0 {
|
||||||
fmt.Printf("import type %v = %L\n", s, t)
|
fmt.Printf("import type %v = %L\n", s, t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func dumpasmhdr() {
|
func dumpasmhdr() {
|
||||||
b, err := bio.Create(Flag.AsmHdr)
|
b, err := bio.Create(base.Flag.AsmHdr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatalf("%v", err)
|
base.Fatalf("%v", err)
|
||||||
}
|
}
|
||||||
fmt.Fprintf(b, "// generated by compile -asmhdr from package %s\n\n", localpkg.Name)
|
fmt.Fprintf(b, "// generated by compile -asmhdr from package %s\n\n", localpkg.Name)
|
||||||
for _, n := range asmlist {
|
for _, n := range asmlist {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/src"
|
"cmd/internal/src"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
@ -47,7 +48,7 @@ func fmtFlag(s fmt.State, verb rune) FmtFlag {
|
||||||
flag |= FmtSign
|
flag |= FmtSign
|
||||||
}
|
}
|
||||||
if s.Flag(' ') {
|
if s.Flag(' ') {
|
||||||
Fatalf("FmtUnsigned in format string")
|
base.Fatalf("FmtUnsigned in format string")
|
||||||
}
|
}
|
||||||
if _, ok := s.Precision(); ok {
|
if _, ok := s.Precision(); ok {
|
||||||
flag |= FmtComma
|
flag |= FmtComma
|
||||||
|
|
@ -313,7 +314,7 @@ func (m fmtMode) prepareArgs(args []interface{}) {
|
||||||
case int32, int64, string, types.EType, constant.Value:
|
case int32, int64, string, types.EType, constant.Value:
|
||||||
// OK: printing these types doesn't depend on mode
|
// OK: printing these types doesn't depend on mode
|
||||||
default:
|
default:
|
||||||
Fatalf("mode.prepareArgs type %T", arg)
|
base.Fatalf("mode.prepareArgs type %T", arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -339,14 +340,14 @@ func (n *Node) jconv(s fmt.State, flag FmtFlag) {
|
||||||
short := flag&FmtShort != 0
|
short := flag&FmtShort != 0
|
||||||
|
|
||||||
// Useful to see which nodes in an AST printout are actually identical
|
// Useful to see which nodes in an AST printout are actually identical
|
||||||
if Debug.DumpPtrs != 0 {
|
if base.Debug.DumpPtrs != 0 {
|
||||||
fmt.Fprintf(s, " p(%p)", n)
|
fmt.Fprintf(s, " p(%p)", n)
|
||||||
}
|
}
|
||||||
if !short && n.Name != nil && n.Name.Vargen != 0 {
|
if !short && n.Name != nil && n.Name.Vargen != 0 {
|
||||||
fmt.Fprintf(s, " g(%d)", n.Name.Vargen)
|
fmt.Fprintf(s, " g(%d)", n.Name.Vargen)
|
||||||
}
|
}
|
||||||
|
|
||||||
if Debug.DumpPtrs != 0 && !short && n.Name != nil && n.Name.Defn != nil {
|
if base.Debug.DumpPtrs != 0 && !short && n.Name != nil && n.Name.Defn != nil {
|
||||||
// Useful to see where Defn is set and what node it points to
|
// Useful to see where Defn is set and what node it points to
|
||||||
fmt.Fprintf(s, " defn(%p)", n.Name.Defn)
|
fmt.Fprintf(s, " defn(%p)", n.Name.Defn)
|
||||||
}
|
}
|
||||||
|
|
@ -817,7 +818,7 @@ func tconv2(b *bytes.Buffer, t *types.Type, flag FmtFlag, mode fmtMode, visited
|
||||||
case mt.Hiter:
|
case mt.Hiter:
|
||||||
b.WriteString("map.iter[")
|
b.WriteString("map.iter[")
|
||||||
default:
|
default:
|
||||||
Fatalf("unknown internal map type")
|
base.Fatalf("unknown internal map type")
|
||||||
}
|
}
|
||||||
tconv2(b, m.Key(), 0, mode, visited)
|
tconv2(b, m.Key(), 0, mode, visited)
|
||||||
b.WriteByte(']')
|
b.WriteByte(']')
|
||||||
|
|
@ -1416,7 +1417,7 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
|
||||||
|
|
||||||
case OSLICEHEADER:
|
case OSLICEHEADER:
|
||||||
if n.List.Len() != 2 {
|
if n.List.Len() != 2 {
|
||||||
Fatalf("bad OSLICEHEADER list length %d", n.List.Len())
|
base.Fatalf("bad OSLICEHEADER list length %d", n.List.Len())
|
||||||
}
|
}
|
||||||
mode.Fprintf(s, "sliceheader{%v,%v,%v}", n.Left, n.List.First(), n.List.Second())
|
mode.Fprintf(s, "sliceheader{%v,%v,%v}", n.Left, n.List.First(), n.List.Second())
|
||||||
|
|
||||||
|
|
@ -1806,7 +1807,7 @@ func (n *Node) nconv(s fmt.State, flag FmtFlag, mode fmtMode) {
|
||||||
dumpdepth--
|
dumpdepth--
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Fatalf("unhandled %%N mode: %d", mode)
|
base.Fatalf("unhandled %%N mode: %d", mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
"cmd/internal/src"
|
"cmd/internal/src"
|
||||||
|
|
@ -52,14 +53,14 @@ func autotmpname(n int) string {
|
||||||
// make a new Node off the books
|
// make a new Node off the books
|
||||||
func tempAt(pos src.XPos, curfn *Node, t *types.Type) *Node {
|
func tempAt(pos src.XPos, curfn *Node, t *types.Type) *Node {
|
||||||
if curfn == nil {
|
if curfn == nil {
|
||||||
Fatalf("no curfn for tempAt")
|
base.Fatalf("no curfn for tempAt")
|
||||||
}
|
}
|
||||||
if curfn.Op == OCLOSURE {
|
if curfn.Op == OCLOSURE {
|
||||||
Dump("tempAt", curfn)
|
Dump("tempAt", curfn)
|
||||||
Fatalf("adding tempAt to wrong closure function")
|
base.Fatalf("adding tempAt to wrong closure function")
|
||||||
}
|
}
|
||||||
if t == nil {
|
if t == nil {
|
||||||
Fatalf("tempAt called with nil type")
|
base.Fatalf("tempAt called with nil type")
|
||||||
}
|
}
|
||||||
|
|
||||||
s := &types.Sym{
|
s := &types.Sym{
|
||||||
|
|
@ -82,5 +83,5 @@ func tempAt(pos src.XPos, curfn *Node, t *types.Type) *Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
func temp(t *types.Type) *Node {
|
func temp(t *types.Type) *Node {
|
||||||
return tempAt(lineno, Curfn, t)
|
return tempAt(base.Pos, Curfn, t)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/ssa"
|
"cmd/compile/internal/ssa"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
|
|
@ -39,7 +40,7 @@ var (
|
||||||
|
|
||||||
// isRuntimePkg reports whether p is package runtime.
|
// isRuntimePkg reports whether p is package runtime.
|
||||||
func isRuntimePkg(p *types.Pkg) bool {
|
func isRuntimePkg(p *types.Pkg) bool {
|
||||||
if Flag.CompilingRuntime && p == localpkg {
|
if base.Flag.CompilingRuntime && p == localpkg {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return p.Path == "runtime"
|
return p.Path == "runtime"
|
||||||
|
|
@ -48,7 +49,7 @@ func isRuntimePkg(p *types.Pkg) bool {
|
||||||
// isReflectPkg reports whether p is package reflect.
|
// isReflectPkg reports whether p is package reflect.
|
||||||
func isReflectPkg(p *types.Pkg) bool {
|
func isReflectPkg(p *types.Pkg) bool {
|
||||||
if p == localpkg {
|
if p == localpkg {
|
||||||
return Ctxt.Pkgpath == "reflect"
|
return base.Ctxt.Pkgpath == "reflect"
|
||||||
}
|
}
|
||||||
return p.Path == "reflect"
|
return p.Path == "reflect"
|
||||||
}
|
}
|
||||||
|
|
@ -182,8 +183,6 @@ var instrumenting bool
|
||||||
// Whether we are tracking lexical scopes for DWARF.
|
// Whether we are tracking lexical scopes for DWARF.
|
||||||
var trackScopes bool
|
var trackScopes bool
|
||||||
|
|
||||||
var Ctxt *obj.Link
|
|
||||||
|
|
||||||
var nodfp *Node
|
var nodfp *Node
|
||||||
|
|
||||||
var autogeneratedPos src.XPos
|
var autogeneratedPos src.XPos
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/ssa"
|
"cmd/compile/internal/ssa"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
|
|
@ -57,8 +58,8 @@ type Progs struct {
|
||||||
// worker indicates which of the backend workers will use the Progs.
|
// worker indicates which of the backend workers will use the Progs.
|
||||||
func newProgs(fn *Node, worker int) *Progs {
|
func newProgs(fn *Node, worker int) *Progs {
|
||||||
pp := new(Progs)
|
pp := new(Progs)
|
||||||
if Ctxt.CanReuseProgs() {
|
if base.Ctxt.CanReuseProgs() {
|
||||||
sz := len(sharedProgArray) / Flag.LowerC
|
sz := len(sharedProgArray) / base.Flag.LowerC
|
||||||
pp.progcache = sharedProgArray[sz*worker : sz*(worker+1)]
|
pp.progcache = sharedProgArray[sz*worker : sz*(worker+1)]
|
||||||
}
|
}
|
||||||
pp.curfn = fn
|
pp.curfn = fn
|
||||||
|
|
@ -83,19 +84,19 @@ func (pp *Progs) NewProg() *obj.Prog {
|
||||||
} else {
|
} else {
|
||||||
p = new(obj.Prog)
|
p = new(obj.Prog)
|
||||||
}
|
}
|
||||||
p.Ctxt = Ctxt
|
p.Ctxt = base.Ctxt
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush converts from pp to machine code.
|
// Flush converts from pp to machine code.
|
||||||
func (pp *Progs) Flush() {
|
func (pp *Progs) Flush() {
|
||||||
plist := &obj.Plist{Firstpc: pp.Text, Curfn: pp.curfn}
|
plist := &obj.Plist{Firstpc: pp.Text, Curfn: pp.curfn}
|
||||||
obj.Flushplist(Ctxt, plist, pp.NewProg, Ctxt.Pkgpath)
|
obj.Flushplist(base.Ctxt, plist, pp.NewProg, base.Ctxt.Pkgpath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free clears pp and any associated resources.
|
// Free clears pp and any associated resources.
|
||||||
func (pp *Progs) Free() {
|
func (pp *Progs) Free() {
|
||||||
if Ctxt.CanReuseProgs() {
|
if base.Ctxt.CanReuseProgs() {
|
||||||
// Clear progs to enable GC and avoid abuse.
|
// Clear progs to enable GC and avoid abuse.
|
||||||
s := pp.progcache[:pp.cacheidx]
|
s := pp.progcache[:pp.cacheidx]
|
||||||
for i := range s {
|
for i := range s {
|
||||||
|
|
@ -133,8 +134,8 @@ func (pp *Progs) Prog(as obj.As) *obj.Prog {
|
||||||
pp.clearp(pp.next)
|
pp.clearp(pp.next)
|
||||||
p.Link = pp.next
|
p.Link = pp.next
|
||||||
|
|
||||||
if !pp.pos.IsKnown() && Flag.K != 0 {
|
if !pp.pos.IsKnown() && base.Flag.K != 0 {
|
||||||
Warn("prog: unknown position (line 0)")
|
base.Warn("prog: unknown position (line 0)")
|
||||||
}
|
}
|
||||||
|
|
||||||
p.As = as
|
p.As = as
|
||||||
|
|
@ -174,7 +175,7 @@ func (pp *Progs) Appendpp(p *obj.Prog, as obj.As, ftype obj.AddrType, freg int16
|
||||||
|
|
||||||
func (pp *Progs) settext(fn *Node) {
|
func (pp *Progs) settext(fn *Node) {
|
||||||
if pp.Text != nil {
|
if pp.Text != nil {
|
||||||
Fatalf("Progs.settext called twice")
|
base.Fatalf("Progs.settext called twice")
|
||||||
}
|
}
|
||||||
ptxt := pp.Prog(obj.ATEXT)
|
ptxt := pp.Prog(obj.ATEXT)
|
||||||
pp.Text = ptxt
|
pp.Text = ptxt
|
||||||
|
|
@ -193,7 +194,7 @@ func (pp *Progs) settext(fn *Node) {
|
||||||
// called for both functions with bodies and functions without bodies.
|
// called for both functions with bodies and functions without bodies.
|
||||||
func (f *Func) initLSym(hasBody bool) {
|
func (f *Func) initLSym(hasBody bool) {
|
||||||
if f.lsym != nil {
|
if f.lsym != nil {
|
||||||
Fatalf("Func.initLSym called twice")
|
base.Fatalf("Func.initLSym called twice")
|
||||||
}
|
}
|
||||||
|
|
||||||
if nam := f.Nname; !nam.isBlank() {
|
if nam := f.Nname; !nam.isBlank() {
|
||||||
|
|
@ -215,7 +216,7 @@ func (f *Func) initLSym(hasBody bool) {
|
||||||
// using the expected ABI.
|
// using the expected ABI.
|
||||||
want := obj.ABIInternal
|
want := obj.ABIInternal
|
||||||
if f.lsym.ABI() != want {
|
if f.lsym.ABI() != want {
|
||||||
Fatalf("function symbol %s has the wrong ABI %v, expected %v", f.lsym.Name, f.lsym.ABI(), want)
|
base.Fatalf("function symbol %s has the wrong ABI %v, expected %v", f.lsym.Name, f.lsym.ABI(), want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -249,7 +250,7 @@ func (f *Func) initLSym(hasBody bool) {
|
||||||
}
|
}
|
||||||
asym.SetABI(aliasABI)
|
asym.SetABI(aliasABI)
|
||||||
asym.Set(obj.AttrDuplicateOK, true)
|
asym.Set(obj.AttrDuplicateOK, true)
|
||||||
Ctxt.ABIAliases = append(Ctxt.ABIAliases, asym)
|
base.Ctxt.ABIAliases = append(base.Ctxt.ABIAliases, asym)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -278,14 +279,14 @@ func (f *Func) initLSym(hasBody bool) {
|
||||||
// Clumsy but important.
|
// Clumsy but important.
|
||||||
// See test/recover.go for test cases and src/reflect/value.go
|
// See test/recover.go for test cases and src/reflect/value.go
|
||||||
// for the actual functions being considered.
|
// for the actual functions being considered.
|
||||||
if Ctxt.Pkgpath == "reflect" {
|
if base.Ctxt.Pkgpath == "reflect" {
|
||||||
switch f.Nname.Sym.Name {
|
switch f.Nname.Sym.Name {
|
||||||
case "callReflect", "callMethod":
|
case "callReflect", "callMethod":
|
||||||
flag |= obj.WRAPPER
|
flag |= obj.WRAPPER
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ctxt.InitTextSym(f.lsym, flag)
|
base.Ctxt.InitTextSym(f.lsym, flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ggloblnod(nam *Node) {
|
func ggloblnod(nam *Node) {
|
||||||
|
|
@ -298,7 +299,7 @@ func ggloblnod(nam *Node) {
|
||||||
if nam.Type != nil && !nam.Type.HasPointers() {
|
if nam.Type != nil && !nam.Type.HasPointers() {
|
||||||
flags |= obj.NOPTR
|
flags |= obj.NOPTR
|
||||||
}
|
}
|
||||||
Ctxt.Globl(s, nam.Type.Width, flags)
|
base.Ctxt.Globl(s, nam.Type.Width, flags)
|
||||||
if nam.Name.LibfuzzerExtraCounter() {
|
if nam.Name.LibfuzzerExtraCounter() {
|
||||||
s.Type = objabi.SLIBFUZZER_EXTRA_COUNTER
|
s.Type = objabi.SLIBFUZZER_EXTRA_COUNTER
|
||||||
}
|
}
|
||||||
|
|
@ -315,7 +316,7 @@ func ggloblsym(s *obj.LSym, width int32, flags int16) {
|
||||||
s.Set(obj.AttrLocal, true)
|
s.Set(obj.AttrLocal, true)
|
||||||
flags &^= obj.LOCAL
|
flags &^= obj.LOCAL
|
||||||
}
|
}
|
||||||
Ctxt.Globl(s, int64(width), int(flags))
|
base.Ctxt.Globl(s, int64(width), int(flags))
|
||||||
}
|
}
|
||||||
|
|
||||||
func Addrconst(a *obj.Addr, v int64) {
|
func Addrconst(a *obj.Addr, v int64) {
|
||||||
|
|
@ -326,7 +327,7 @@ func Addrconst(a *obj.Addr, v int64) {
|
||||||
|
|
||||||
func Patch(p *obj.Prog, to *obj.Prog) {
|
func Patch(p *obj.Prog, to *obj.Prog) {
|
||||||
if p.To.Type != obj.TYPE_BRANCH {
|
if p.To.Type != obj.TYPE_BRANCH {
|
||||||
Fatalf("patch: not a branch")
|
base.Fatalf("patch: not a branch")
|
||||||
}
|
}
|
||||||
p.To.SetTarget(to)
|
p.To.SetTarget(to)
|
||||||
p.To.Offset = to.Pc
|
p.To.Offset = to.Pc
|
||||||
|
|
|
||||||
|
|
@ -204,6 +204,7 @@ package gc
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/goobj"
|
"cmd/internal/goobj"
|
||||||
"cmd/internal/src"
|
"cmd/internal/src"
|
||||||
|
|
@ -266,7 +267,7 @@ func iexport(out *bufio.Writer) {
|
||||||
p.typIndex[pt] = uint64(i)
|
p.typIndex[pt] = uint64(i)
|
||||||
}
|
}
|
||||||
if len(p.typIndex) > predeclReserved {
|
if len(p.typIndex) > predeclReserved {
|
||||||
Fatalf("too many predeclared types: %d > %d", len(p.typIndex), predeclReserved)
|
base.Fatalf("too many predeclared types: %d > %d", len(p.typIndex), predeclReserved)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize work queue with exported declarations.
|
// Initialize work queue with exported declarations.
|
||||||
|
|
@ -304,8 +305,8 @@ func iexport(out *bufio.Writer) {
|
||||||
|
|
||||||
// Add fingerprint (used by linker object file).
|
// Add fingerprint (used by linker object file).
|
||||||
// Attach this to the end, so tools (e.g. gcimporter) don't care.
|
// Attach this to the end, so tools (e.g. gcimporter) don't care.
|
||||||
copy(Ctxt.Fingerprint[:], h.Sum(nil)[:])
|
copy(base.Ctxt.Fingerprint[:], h.Sum(nil)[:])
|
||||||
out.Write(Ctxt.Fingerprint[:])
|
out.Write(base.Ctxt.Fingerprint[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeIndex writes out an object index. mainIndex indicates whether
|
// writeIndex writes out an object index. mainIndex indicates whether
|
||||||
|
|
@ -394,7 +395,7 @@ func (p *iexporter) stringOff(s string) uint64 {
|
||||||
// pushDecl adds n to the declaration work queue, if not already present.
|
// pushDecl adds n to the declaration work queue, if not already present.
|
||||||
func (p *iexporter) pushDecl(n *Node) {
|
func (p *iexporter) pushDecl(n *Node) {
|
||||||
if n.Sym == nil || asNode(n.Sym.Def) != n && n.Op != OTYPE {
|
if n.Sym == nil || asNode(n.Sym.Def) != n && n.Op != OTYPE {
|
||||||
Fatalf("weird Sym: %v, %v", n, n.Sym)
|
base.Fatalf("weird Sym: %v, %v", n, n.Sym)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't export predeclared declarations.
|
// Don't export predeclared declarations.
|
||||||
|
|
@ -437,7 +438,7 @@ func (p *iexporter) doDecl(n *Node) {
|
||||||
|
|
||||||
case PFUNC:
|
case PFUNC:
|
||||||
if n.IsMethod() {
|
if n.IsMethod() {
|
||||||
Fatalf("unexpected method: %v", n)
|
base.Fatalf("unexpected method: %v", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function.
|
// Function.
|
||||||
|
|
@ -447,7 +448,7 @@ func (p *iexporter) doDecl(n *Node) {
|
||||||
w.funcExt(n)
|
w.funcExt(n)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Fatalf("unexpected class: %v, %v", n, n.Class())
|
base.Fatalf("unexpected class: %v, %v", n, n.Class())
|
||||||
}
|
}
|
||||||
|
|
||||||
case OLITERAL:
|
case OLITERAL:
|
||||||
|
|
@ -503,7 +504,7 @@ func (p *iexporter) doDecl(n *Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Fatalf("unexpected node: %v", n)
|
base.Fatalf("unexpected node: %v", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.declIndex[n] = w.flush()
|
p.declIndex[n] = w.flush()
|
||||||
|
|
@ -523,7 +524,7 @@ func (p *iexporter) doInline(f *Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *exportWriter) pos(pos src.XPos) {
|
func (w *exportWriter) pos(pos src.XPos) {
|
||||||
p := Ctxt.PosTable.Pos(pos)
|
p := base.Ctxt.PosTable.Pos(pos)
|
||||||
file := p.Base().AbsFilename()
|
file := p.Base().AbsFilename()
|
||||||
line := int64(p.RelLine())
|
line := int64(p.RelLine())
|
||||||
column := int64(p.RelCol())
|
column := int64(p.RelCol())
|
||||||
|
|
@ -579,7 +580,7 @@ func (w *exportWriter) qualifiedIdent(n *Node) {
|
||||||
|
|
||||||
func (w *exportWriter) selector(s *types.Sym) {
|
func (w *exportWriter) selector(s *types.Sym) {
|
||||||
if w.currPkg == nil {
|
if w.currPkg == nil {
|
||||||
Fatalf("missing currPkg")
|
base.Fatalf("missing currPkg")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method selectors are rewritten into method symbols (of the
|
// Method selectors are rewritten into method symbols (of the
|
||||||
|
|
@ -594,7 +595,7 @@ func (w *exportWriter) selector(s *types.Sym) {
|
||||||
pkg = localpkg
|
pkg = localpkg
|
||||||
}
|
}
|
||||||
if s.Pkg != pkg {
|
if s.Pkg != pkg {
|
||||||
Fatalf("package mismatch in selector: %v in package %q, but want %q", s, s.Pkg.Path, pkg.Path)
|
base.Fatalf("package mismatch in selector: %v in package %q, but want %q", s, s.Pkg.Path, pkg.Path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -633,7 +634,7 @@ func (w *exportWriter) startType(k itag) {
|
||||||
func (w *exportWriter) doTyp(t *types.Type) {
|
func (w *exportWriter) doTyp(t *types.Type) {
|
||||||
if t.Sym != nil {
|
if t.Sym != nil {
|
||||||
if t.Sym.Pkg == builtinpkg || t.Sym.Pkg == unsafepkg {
|
if t.Sym.Pkg == builtinpkg || t.Sym.Pkg == unsafepkg {
|
||||||
Fatalf("builtin type missing from typIndex: %v", t)
|
base.Fatalf("builtin type missing from typIndex: %v", t)
|
||||||
}
|
}
|
||||||
|
|
||||||
w.startType(definedType)
|
w.startType(definedType)
|
||||||
|
|
@ -710,7 +711,7 @@ func (w *exportWriter) doTyp(t *types.Type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Fatalf("unexpected type: %v", t)
|
base.Fatalf("unexpected type: %v", t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -773,7 +774,7 @@ func constTypeOf(typ *types.Type) constant.Kind {
|
||||||
return constant.Complex
|
return constant.Complex
|
||||||
}
|
}
|
||||||
|
|
||||||
Fatalf("unexpected constant type: %v", typ)
|
base.Fatalf("unexpected constant type: %v", typ)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -851,7 +852,7 @@ func (w *exportWriter) mpint(x constant.Value, typ *types.Type) {
|
||||||
|
|
||||||
negative := constant.Sign(x) < 0
|
negative := constant.Sign(x) < 0
|
||||||
if !signed && negative {
|
if !signed && negative {
|
||||||
Fatalf("negative unsigned integer; type %v, value %v", typ, x)
|
base.Fatalf("negative unsigned integer; type %v, value %v", typ, x)
|
||||||
}
|
}
|
||||||
|
|
||||||
b := constant.Bytes(x) // little endian
|
b := constant.Bytes(x) // little endian
|
||||||
|
|
@ -860,10 +861,10 @@ func (w *exportWriter) mpint(x constant.Value, typ *types.Type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(b) > 0 && b[0] == 0 {
|
if len(b) > 0 && b[0] == 0 {
|
||||||
Fatalf("leading zeros")
|
base.Fatalf("leading zeros")
|
||||||
}
|
}
|
||||||
if uint(len(b)) > maxBytes {
|
if uint(len(b)) > maxBytes {
|
||||||
Fatalf("bad mpint length: %d > %d (type %v, value %v)", len(b), maxBytes, typ, x)
|
base.Fatalf("bad mpint length: %d > %d (type %v, value %v)", len(b), maxBytes, typ, x)
|
||||||
}
|
}
|
||||||
|
|
||||||
maxSmall := 256 - maxBytes
|
maxSmall := 256 - maxBytes
|
||||||
|
|
@ -900,7 +901,7 @@ func (w *exportWriter) mpint(x constant.Value, typ *types.Type) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if n < maxSmall || n >= 256 {
|
if n < maxSmall || n >= 256 {
|
||||||
Fatalf("encoding mistake: %d, %v, %v => %d", len(b), signed, negative, n)
|
base.Fatalf("encoding mistake: %d, %v, %v => %d", len(b), signed, negative, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
w.data.WriteByte(byte(n))
|
w.data.WriteByte(byte(n))
|
||||||
|
|
@ -916,7 +917,7 @@ func (w *exportWriter) mpint(x constant.Value, typ *types.Type) {
|
||||||
func (w *exportWriter) mpfloat(v constant.Value, typ *types.Type) {
|
func (w *exportWriter) mpfloat(v constant.Value, typ *types.Type) {
|
||||||
f := bigFloatVal(v)
|
f := bigFloatVal(v)
|
||||||
if f.IsInf() {
|
if f.IsInf() {
|
||||||
Fatalf("infinite constant")
|
base.Fatalf("infinite constant")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Break into f = mant × 2**exp, with 0.5 <= mant < 1.
|
// Break into f = mant × 2**exp, with 0.5 <= mant < 1.
|
||||||
|
|
@ -930,7 +931,7 @@ func (w *exportWriter) mpfloat(v constant.Value, typ *types.Type) {
|
||||||
|
|
||||||
manti, acc := mant.Int(nil)
|
manti, acc := mant.Int(nil)
|
||||||
if acc != big.Exact {
|
if acc != big.Exact {
|
||||||
Fatalf("mantissa scaling failed for %f (%s)", f, acc)
|
base.Fatalf("mantissa scaling failed for %f (%s)", f, acc)
|
||||||
}
|
}
|
||||||
w.mpint(makeInt(manti), typ)
|
w.mpint(makeInt(manti), typ)
|
||||||
if manti.Sign() != 0 {
|
if manti.Sign() != 0 {
|
||||||
|
|
@ -1158,7 +1159,7 @@ func (w *exportWriter) stmt(n *Node) {
|
||||||
w.string(n.Sym.Name)
|
w.string(n.Sym.Name)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Fatalf("exporter: CANNOT EXPORT: %v\nPlease notify gri@\n", n.Op)
|
base.Fatalf("exporter: CANNOT EXPORT: %v\nPlease notify gri@\n", n.Op)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1169,7 +1170,7 @@ func (w *exportWriter) caseList(sw *Node) {
|
||||||
w.uint64(uint64(len(cases)))
|
w.uint64(uint64(len(cases)))
|
||||||
for _, cas := range cases {
|
for _, cas := range cases {
|
||||||
if cas.Op != OCASE {
|
if cas.Op != OCASE {
|
||||||
Fatalf("expected OCASE, got %v", cas)
|
base.Fatalf("expected OCASE, got %v", cas)
|
||||||
}
|
}
|
||||||
w.pos(cas.Pos)
|
w.pos(cas.Pos)
|
||||||
w.stmtList(cas.List)
|
w.stmtList(cas.List)
|
||||||
|
|
@ -1207,7 +1208,7 @@ func (w *exportWriter) expr(n *Node) {
|
||||||
// (somewhat closely following the structure of exprfmt in fmt.go)
|
// (somewhat closely following the structure of exprfmt in fmt.go)
|
||||||
case ONIL:
|
case ONIL:
|
||||||
if !n.Type.HasNil() {
|
if !n.Type.HasNil() {
|
||||||
Fatalf("unexpected type for nil: %v", n.Type)
|
base.Fatalf("unexpected type for nil: %v", n.Type)
|
||||||
}
|
}
|
||||||
if n.Orig != nil && n.Orig != n {
|
if n.Orig != nil && n.Orig != n {
|
||||||
w.expr(n.Orig)
|
w.expr(n.Orig)
|
||||||
|
|
@ -1256,7 +1257,7 @@ func (w *exportWriter) expr(n *Node) {
|
||||||
var s *types.Sym
|
var s *types.Sym
|
||||||
if n.Left != nil {
|
if n.Left != nil {
|
||||||
if n.Left.Op != ONONAME {
|
if n.Left.Op != ONONAME {
|
||||||
Fatalf("expected ONONAME, got %v", n.Left)
|
base.Fatalf("expected ONONAME, got %v", n.Left)
|
||||||
}
|
}
|
||||||
s = n.Left.Sym
|
s = n.Left.Sym
|
||||||
}
|
}
|
||||||
|
|
@ -1365,7 +1366,7 @@ func (w *exportWriter) expr(n *Node) {
|
||||||
if op == OAPPEND {
|
if op == OAPPEND {
|
||||||
w.bool(n.IsDDD())
|
w.bool(n.IsDDD())
|
||||||
} else if n.IsDDD() {
|
} else if n.IsDDD() {
|
||||||
Fatalf("exporter: unexpected '...' with %v call", op)
|
base.Fatalf("exporter: unexpected '...' with %v call", op)
|
||||||
}
|
}
|
||||||
|
|
||||||
case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER, OGETG:
|
case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER, OGETG:
|
||||||
|
|
@ -1419,7 +1420,7 @@ func (w *exportWriter) expr(n *Node) {
|
||||||
// has already been replaced with literals
|
// has already been replaced with literals
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Fatalf("cannot export %v (%d) node\n"+
|
base.Fatalf("cannot export %v (%d) node\n"+
|
||||||
"\t==> please file an issue and assign to gri@", n.Op, int(n.Op))
|
"\t==> please file an issue and assign to gri@", n.Op, int(n.Op))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1484,18 +1485,18 @@ func (w *exportWriter) localIdent(s *types.Sym, v int32) {
|
||||||
|
|
||||||
// TODO(mdempsky): Fix autotmp hack.
|
// TODO(mdempsky): Fix autotmp hack.
|
||||||
if i := strings.LastIndex(name, "."); i >= 0 && !strings.HasPrefix(name, ".autotmp_") {
|
if i := strings.LastIndex(name, "."); i >= 0 && !strings.HasPrefix(name, ".autotmp_") {
|
||||||
Fatalf("unexpected dot in identifier: %v", name)
|
base.Fatalf("unexpected dot in identifier: %v", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if v > 0 {
|
if v > 0 {
|
||||||
if strings.Contains(name, "·") {
|
if strings.Contains(name, "·") {
|
||||||
Fatalf("exporter: unexpected · in symbol name")
|
base.Fatalf("exporter: unexpected · in symbol name")
|
||||||
}
|
}
|
||||||
name = fmt.Sprintf("%s·%d", name, v)
|
name = fmt.Sprintf("%s·%d", name, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !types.IsExported(name) && s.Pkg != w.currPkg {
|
if !types.IsExported(name) && s.Pkg != w.currPkg {
|
||||||
Fatalf("weird package in name: %v => %v, not %q", s, name, w.currPkg.Path)
|
base.Fatalf("weird package in name: %v => %v, not %q", s, name, w.currPkg.Path)
|
||||||
}
|
}
|
||||||
|
|
||||||
w.string(name)
|
w.string(name)
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/bio"
|
"cmd/internal/bio"
|
||||||
"cmd/internal/goobj"
|
"cmd/internal/goobj"
|
||||||
|
|
@ -60,7 +61,7 @@ func expandInline(fn *Node) {
|
||||||
|
|
||||||
r := importReaderFor(fn, inlineImporter)
|
r := importReaderFor(fn, inlineImporter)
|
||||||
if r == nil {
|
if r == nil {
|
||||||
Fatalf("missing import reader for %v", fn)
|
base.Fatalf("missing import reader for %v", fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
r.doInline(fn)
|
r.doInline(fn)
|
||||||
|
|
@ -83,8 +84,8 @@ type intReader struct {
|
||||||
func (r *intReader) int64() int64 {
|
func (r *intReader) int64() int64 {
|
||||||
i, err := binary.ReadVarint(r.Reader)
|
i, err := binary.ReadVarint(r.Reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
yyerror("import %q: read error: %v", r.pkg.Path, err)
|
base.Errorf("import %q: read error: %v", r.pkg.Path, err)
|
||||||
errorexit()
|
base.ErrorExit()
|
||||||
}
|
}
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
@ -92,8 +93,8 @@ func (r *intReader) int64() int64 {
|
||||||
func (r *intReader) uint64() uint64 {
|
func (r *intReader) uint64() uint64 {
|
||||||
i, err := binary.ReadUvarint(r.Reader)
|
i, err := binary.ReadUvarint(r.Reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
yyerror("import %q: read error: %v", r.pkg.Path, err)
|
base.Errorf("import %q: read error: %v", r.pkg.Path, err)
|
||||||
errorexit()
|
base.ErrorExit()
|
||||||
}
|
}
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
@ -103,8 +104,8 @@ func iimport(pkg *types.Pkg, in *bio.Reader) (fingerprint goobj.FingerprintType)
|
||||||
|
|
||||||
version := ird.uint64()
|
version := ird.uint64()
|
||||||
if version != iexportVersion {
|
if version != iexportVersion {
|
||||||
yyerror("import %q: unknown export format version %d", pkg.Path, version)
|
base.Errorf("import %q: unknown export format version %d", pkg.Path, version)
|
||||||
errorexit()
|
base.ErrorExit()
|
||||||
}
|
}
|
||||||
|
|
||||||
sLen := ird.uint64()
|
sLen := ird.uint64()
|
||||||
|
|
@ -115,8 +116,8 @@ func iimport(pkg *types.Pkg, in *bio.Reader) (fingerprint goobj.FingerprintType)
|
||||||
// returning individual substrings very efficiently.
|
// returning individual substrings very efficiently.
|
||||||
data, err := mapFile(in.File(), in.Offset(), int64(sLen+dLen))
|
data, err := mapFile(in.File(), in.Offset(), int64(sLen+dLen))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
yyerror("import %q: mapping input: %v", pkg.Path, err)
|
base.Errorf("import %q: mapping input: %v", pkg.Path, err)
|
||||||
errorexit()
|
base.ErrorExit()
|
||||||
}
|
}
|
||||||
stringData := data[:sLen]
|
stringData := data[:sLen]
|
||||||
declData := data[sLen:]
|
declData := data[sLen:]
|
||||||
|
|
@ -152,10 +153,10 @@ func iimport(pkg *types.Pkg, in *bio.Reader) (fingerprint goobj.FingerprintType)
|
||||||
pkg.Lookup("_").Def = asTypesNode(nblank)
|
pkg.Lookup("_").Def = asTypesNode(nblank)
|
||||||
} else {
|
} else {
|
||||||
if pkg.Name != pkgName {
|
if pkg.Name != pkgName {
|
||||||
Fatalf("conflicting package names %v and %v for path %q", pkg.Name, pkgName, pkg.Path)
|
base.Fatalf("conflicting package names %v and %v for path %q", pkg.Name, pkgName, pkg.Path)
|
||||||
}
|
}
|
||||||
if pkg.Height != pkgHeight {
|
if pkg.Height != pkgHeight {
|
||||||
Fatalf("conflicting package heights %v and %v for path %q", pkg.Height, pkgHeight, pkg.Path)
|
base.Fatalf("conflicting package heights %v and %v for path %q", pkg.Height, pkgHeight, pkg.Path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -171,7 +172,7 @@ func iimport(pkg *types.Pkg, in *bio.Reader) (fingerprint goobj.FingerprintType)
|
||||||
// Create stub declaration. If used, this will
|
// Create stub declaration. If used, this will
|
||||||
// be overwritten by expandDecl.
|
// be overwritten by expandDecl.
|
||||||
if s.Def != nil {
|
if s.Def != nil {
|
||||||
Fatalf("unexpected definition for %v: %v", s, asNode(s.Def))
|
base.Fatalf("unexpected definition for %v: %v", s, asNode(s.Def))
|
||||||
}
|
}
|
||||||
s.Def = asTypesNode(npos(src.NoXPos, dclname(s)))
|
s.Def = asTypesNode(npos(src.NoXPos, dclname(s)))
|
||||||
}
|
}
|
||||||
|
|
@ -195,8 +196,8 @@ func iimport(pkg *types.Pkg, in *bio.Reader) (fingerprint goobj.FingerprintType)
|
||||||
// Fingerprint.
|
// Fingerprint.
|
||||||
_, err = io.ReadFull(in, fingerprint[:])
|
_, err = io.ReadFull(in, fingerprint[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
yyerror("import %s: error reading fingerprint", pkg.Path)
|
base.Errorf("import %s: error reading fingerprint", pkg.Path)
|
||||||
errorexit()
|
base.ErrorExit()
|
||||||
}
|
}
|
||||||
return fingerprint
|
return fingerprint
|
||||||
}
|
}
|
||||||
|
|
@ -218,7 +219,7 @@ func (p *iimporter) stringAt(off uint64) string {
|
||||||
|
|
||||||
slen, n := binary.Uvarint(x[:n])
|
slen, n := binary.Uvarint(x[:n])
|
||||||
if n <= 0 {
|
if n <= 0 {
|
||||||
Fatalf("varint failed")
|
base.Fatalf("varint failed")
|
||||||
}
|
}
|
||||||
spos := off + uint64(n)
|
spos := off + uint64(n)
|
||||||
return p.stringData[spos : spos+slen]
|
return p.stringData[spos : spos+slen]
|
||||||
|
|
@ -281,7 +282,7 @@ func (r *importReader) setPkg() {
|
||||||
|
|
||||||
func (r *importReader) doDecl(n *Node) {
|
func (r *importReader) doDecl(n *Node) {
|
||||||
if n.Op != ONONAME {
|
if n.Op != ONONAME {
|
||||||
Fatalf("doDecl: unexpected Op for %v: %v", n.Sym, n.Op)
|
base.Fatalf("doDecl: unexpected Op for %v: %v", n.Sym, n.Op)
|
||||||
}
|
}
|
||||||
|
|
||||||
tag := r.byte()
|
tag := r.byte()
|
||||||
|
|
@ -352,7 +353,7 @@ func (r *importReader) doDecl(n *Node) {
|
||||||
r.varExt(n)
|
r.varExt(n)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Fatalf("unexpected tag: %v", tag)
|
base.Fatalf("unexpected tag: %v", tag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -372,7 +373,7 @@ func (p *importReader) value(typ *types.Type) constant.Value {
|
||||||
return makeComplex(p.float(typ), p.float(typ))
|
return makeComplex(p.float(typ), p.float(typ))
|
||||||
}
|
}
|
||||||
|
|
||||||
Fatalf("unexpected value type: %v", typ)
|
base.Fatalf("unexpected value type: %v", typ)
|
||||||
panic("unreachable")
|
panic("unreachable")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -405,7 +406,7 @@ func (p *importReader) mpint(x *big.Int, typ *types.Type) {
|
||||||
v = -(n &^ 1) >> 1
|
v = -(n &^ 1) >> 1
|
||||||
}
|
}
|
||||||
if v < 1 || uint(v) > maxBytes {
|
if v < 1 || uint(v) > maxBytes {
|
||||||
Fatalf("weird decoding: %v, %v => %v", n, signed, v)
|
base.Fatalf("weird decoding: %v, %v => %v", n, signed, v)
|
||||||
}
|
}
|
||||||
b := make([]byte, v)
|
b := make([]byte, v)
|
||||||
p.Read(b)
|
p.Read(b)
|
||||||
|
|
@ -462,10 +463,10 @@ func (r *importReader) pos() src.XPos {
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.prevBase == nil {
|
if r.prevBase == nil {
|
||||||
Fatalf("missing posbase")
|
base.Fatalf("missing posbase")
|
||||||
}
|
}
|
||||||
pos := src.MakePos(r.prevBase, uint(r.prevLine), uint(r.prevColumn))
|
pos := src.MakePos(r.prevBase, uint(r.prevLine), uint(r.prevColumn))
|
||||||
return Ctxt.PosTable.XPos(pos)
|
return base.Ctxt.PosTable.XPos(pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *importReader) typ() *types.Type {
|
func (r *importReader) typ() *types.Type {
|
||||||
|
|
@ -476,7 +477,7 @@ func (p *iimporter) typAt(off uint64) *types.Type {
|
||||||
t, ok := p.typCache[off]
|
t, ok := p.typCache[off]
|
||||||
if !ok {
|
if !ok {
|
||||||
if off < predeclReserved {
|
if off < predeclReserved {
|
||||||
Fatalf("predeclared type missing from cache: %d", off)
|
base.Fatalf("predeclared type missing from cache: %d", off)
|
||||||
}
|
}
|
||||||
t = p.newReader(off-predeclReserved, nil).typ1()
|
t = p.newReader(off-predeclReserved, nil).typ1()
|
||||||
p.typCache[off] = t
|
p.typCache[off] = t
|
||||||
|
|
@ -487,7 +488,7 @@ func (p *iimporter) typAt(off uint64) *types.Type {
|
||||||
func (r *importReader) typ1() *types.Type {
|
func (r *importReader) typ1() *types.Type {
|
||||||
switch k := r.kind(); k {
|
switch k := r.kind(); k {
|
||||||
default:
|
default:
|
||||||
Fatalf("unexpected kind tag in %q: %v", r.p.ipkg.Path, k)
|
base.Fatalf("unexpected kind tag in %q: %v", r.p.ipkg.Path, k)
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
case definedType:
|
case definedType:
|
||||||
|
|
@ -502,7 +503,7 @@ func (r *importReader) typ1() *types.Type {
|
||||||
expandDecl(n)
|
expandDecl(n)
|
||||||
}
|
}
|
||||||
if n.Op != OTYPE {
|
if n.Op != OTYPE {
|
||||||
Fatalf("expected OTYPE, got %v: %v, %v", n.Op, n.Sym, n)
|
base.Fatalf("expected OTYPE, got %v: %v, %v", n.Op, n.Sym, n)
|
||||||
}
|
}
|
||||||
return n.Type
|
return n.Type
|
||||||
case pointerType:
|
case pointerType:
|
||||||
|
|
@ -610,7 +611,7 @@ func (r *importReader) bool() bool {
|
||||||
func (r *importReader) int64() int64 {
|
func (r *importReader) int64() int64 {
|
||||||
n, err := binary.ReadVarint(r)
|
n, err := binary.ReadVarint(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatalf("readVarint: %v", err)
|
base.Fatalf("readVarint: %v", err)
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
@ -618,7 +619,7 @@ func (r *importReader) int64() int64 {
|
||||||
func (r *importReader) uint64() uint64 {
|
func (r *importReader) uint64() uint64 {
|
||||||
n, err := binary.ReadUvarint(r)
|
n, err := binary.ReadUvarint(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatalf("readVarint: %v", err)
|
base.Fatalf("readVarint: %v", err)
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
@ -626,7 +627,7 @@ func (r *importReader) uint64() uint64 {
|
||||||
func (r *importReader) byte() byte {
|
func (r *importReader) byte() byte {
|
||||||
x, err := r.ReadByte()
|
x, err := r.ReadByte()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatalf("declReader.ReadByte: %v", err)
|
base.Fatalf("declReader.ReadByte: %v", err)
|
||||||
}
|
}
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
|
@ -674,7 +675,7 @@ func (r *importReader) symIdx(s *types.Sym) {
|
||||||
idx := int32(r.int64())
|
idx := int32(r.int64())
|
||||||
if idx != -1 {
|
if idx != -1 {
|
||||||
if s.Linkname != "" {
|
if s.Linkname != "" {
|
||||||
Fatalf("bad index for linknamed symbol: %v %d\n", lsym, idx)
|
base.Fatalf("bad index for linknamed symbol: %v %d\n", lsym, idx)
|
||||||
}
|
}
|
||||||
lsym.SymIdx = idx
|
lsym.SymIdx = idx
|
||||||
lsym.Set(obj.AttrIndexed, true)
|
lsym.Set(obj.AttrIndexed, true)
|
||||||
|
|
@ -695,7 +696,7 @@ var typeSymIdx = make(map[*types.Type][2]int64)
|
||||||
|
|
||||||
func (r *importReader) doInline(n *Node) {
|
func (r *importReader) doInline(n *Node) {
|
||||||
if len(n.Func.Inl.Body) != 0 {
|
if len(n.Func.Inl.Body) != 0 {
|
||||||
Fatalf("%v already has inline body", n)
|
base.Fatalf("%v already has inline body", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
funchdr(n)
|
funchdr(n)
|
||||||
|
|
@ -714,8 +715,8 @@ func (r *importReader) doInline(n *Node) {
|
||||||
|
|
||||||
importlist = append(importlist, n)
|
importlist = append(importlist, n)
|
||||||
|
|
||||||
if Flag.E > 0 && Flag.LowerM > 2 {
|
if base.Flag.E > 0 && base.Flag.LowerM > 2 {
|
||||||
if Flag.LowerM > 3 {
|
if base.Flag.LowerM > 3 {
|
||||||
fmt.Printf("inl body for %v %#v: %+v\n", n, n.Type, asNodes(n.Func.Inl.Body))
|
fmt.Printf("inl body for %v %#v: %+v\n", n, n.Type, asNodes(n.Func.Inl.Body))
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("inl body for %v %#v: %v\n", n, n.Type, asNodes(n.Func.Inl.Body))
|
fmt.Printf("inl body for %v %#v: %v\n", n, n.Type, asNodes(n.Func.Inl.Body))
|
||||||
|
|
@ -793,7 +794,7 @@ func (r *importReader) exprList() []*Node {
|
||||||
func (r *importReader) expr() *Node {
|
func (r *importReader) expr() *Node {
|
||||||
n := r.node()
|
n := r.node()
|
||||||
if n != nil && n.Op == OBLOCK {
|
if n != nil && n.Op == OBLOCK {
|
||||||
Fatalf("unexpected block node: %v", n)
|
base.Fatalf("unexpected block node: %v", n)
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
@ -854,11 +855,11 @@ func (r *importReader) node() *Node {
|
||||||
|
|
||||||
case OSTRUCTLIT:
|
case OSTRUCTLIT:
|
||||||
// TODO(mdempsky): Export position information for OSTRUCTKEY nodes.
|
// TODO(mdempsky): Export position information for OSTRUCTKEY nodes.
|
||||||
savedlineno := lineno
|
savedlineno := base.Pos
|
||||||
lineno = r.pos()
|
base.Pos = r.pos()
|
||||||
n := nodl(lineno, OCOMPLIT, nil, typenod(r.typ()))
|
n := nodl(base.Pos, OCOMPLIT, nil, typenod(r.typ()))
|
||||||
n.List.Set(r.elemList()) // special handling of field names
|
n.List.Set(r.elemList()) // special handling of field names
|
||||||
lineno = savedlineno
|
base.Pos = savedlineno
|
||||||
return n
|
return n
|
||||||
|
|
||||||
// case OARRAYLIT, OSLICELIT, OMAPLIT:
|
// case OARRAYLIT, OSLICELIT, OMAPLIT:
|
||||||
|
|
@ -1070,7 +1071,7 @@ func (r *importReader) node() *Node {
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Fatalf("cannot import %v (%d) node\n"+
|
base.Fatalf("cannot import %v (%d) node\n"+
|
||||||
"\t==> please file an issue and assign to gri@", op, int(op))
|
"\t==> please file an issue and assign to gri@", op, int(op))
|
||||||
panic("unreachable") // satisfy compiler
|
panic("unreachable") // satisfy compiler
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
)
|
)
|
||||||
|
|
@ -44,7 +45,7 @@ func fninit(n []*Node) {
|
||||||
|
|
||||||
// Make a function that contains all the initialization statements.
|
// Make a function that contains all the initialization statements.
|
||||||
if len(nf) > 0 {
|
if len(nf) > 0 {
|
||||||
lineno = nf[0].Pos // prolog/epilog gets line number of first init stmt
|
base.Pos = nf[0].Pos // prolog/epilog gets line number of first init stmt
|
||||||
initializers := lookup("init")
|
initializers := lookup("init")
|
||||||
fn := dclfunc(initializers, nod(OTFUNC, nil, nil))
|
fn := dclfunc(initializers, nod(OTFUNC, nil, nil))
|
||||||
for _, dcl := range initTodo.Func.Dcl {
|
for _, dcl := range initTodo.Func.Dcl {
|
||||||
|
|
@ -67,7 +68,7 @@ func fninit(n []*Node) {
|
||||||
// We only generate temps using initTodo if there
|
// We only generate temps using initTodo if there
|
||||||
// are package-scope initialization statements, so
|
// are package-scope initialization statements, so
|
||||||
// something's weird if we get here.
|
// something's weird if we get here.
|
||||||
Fatalf("initTodo still has declarations")
|
base.Fatalf("initTodo still has declarations")
|
||||||
}
|
}
|
||||||
initTodo = nil
|
initTodo = nil
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"container/heap"
|
"container/heap"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"cmd/compile/internal/base"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Package initialization
|
// Package initialization
|
||||||
|
|
@ -89,7 +91,7 @@ func initOrder(l []*Node) []*Node {
|
||||||
case ODCLCONST, ODCLFUNC, ODCLTYPE:
|
case ODCLCONST, ODCLFUNC, ODCLTYPE:
|
||||||
// nop
|
// nop
|
||||||
default:
|
default:
|
||||||
Fatalf("unexpected package-level statement: %v", n)
|
base.Fatalf("unexpected package-level statement: %v", n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -104,10 +106,10 @@ func initOrder(l []*Node) []*Node {
|
||||||
// confused us and there might not be
|
// confused us and there might not be
|
||||||
// a loop. Let the user fix those
|
// a loop. Let the user fix those
|
||||||
// first.
|
// first.
|
||||||
ExitIfErrors()
|
base.ExitIfErrors()
|
||||||
|
|
||||||
findInitLoopAndExit(firstLHS(n), new([]*Node))
|
findInitLoopAndExit(firstLHS(n), new([]*Node))
|
||||||
Fatalf("initialization unfinished, but failed to identify loop")
|
base.Fatalf("initialization unfinished, but failed to identify loop")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -115,7 +117,7 @@ func initOrder(l []*Node) []*Node {
|
||||||
// Invariant consistency check. If this is non-zero, then we
|
// Invariant consistency check. If this is non-zero, then we
|
||||||
// should have found a cycle above.
|
// should have found a cycle above.
|
||||||
if len(o.blocking) != 0 {
|
if len(o.blocking) != 0 {
|
||||||
Fatalf("expected empty map: %v", o.blocking)
|
base.Fatalf("expected empty map: %v", o.blocking)
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.out
|
return s.out
|
||||||
|
|
@ -123,7 +125,7 @@ func initOrder(l []*Node) []*Node {
|
||||||
|
|
||||||
func (o *InitOrder) processAssign(n *Node) {
|
func (o *InitOrder) processAssign(n *Node) {
|
||||||
if n.Initorder() != InitNotStarted || n.Xoffset != BADWIDTH {
|
if n.Initorder() != InitNotStarted || n.Xoffset != BADWIDTH {
|
||||||
Fatalf("unexpected state: %v, %v, %v", n, n.Initorder(), n.Xoffset)
|
base.Fatalf("unexpected state: %v, %v, %v", n, n.Initorder(), n.Xoffset)
|
||||||
}
|
}
|
||||||
|
|
||||||
n.SetInitorder(InitPending)
|
n.SetInitorder(InitPending)
|
||||||
|
|
@ -154,7 +156,7 @@ func (o *InitOrder) flushReady(initialize func(*Node)) {
|
||||||
for o.ready.Len() != 0 {
|
for o.ready.Len() != 0 {
|
||||||
n := heap.Pop(&o.ready).(*Node)
|
n := heap.Pop(&o.ready).(*Node)
|
||||||
if n.Initorder() != InitPending || n.Xoffset != 0 {
|
if n.Initorder() != InitPending || n.Xoffset != 0 {
|
||||||
Fatalf("unexpected state: %v, %v, %v", n, n.Initorder(), n.Xoffset)
|
base.Fatalf("unexpected state: %v, %v, %v", n, n.Initorder(), n.Xoffset)
|
||||||
}
|
}
|
||||||
|
|
||||||
initialize(n)
|
initialize(n)
|
||||||
|
|
@ -238,8 +240,8 @@ func reportInitLoopAndExit(l []*Node) {
|
||||||
}
|
}
|
||||||
fmt.Fprintf(&msg, "\t%v: %v", l[0].Line(), l[0])
|
fmt.Fprintf(&msg, "\t%v: %v", l[0].Line(), l[0])
|
||||||
|
|
||||||
yyerrorl(l[0].Pos, msg.String())
|
base.ErrorfAt(l[0].Pos, msg.String())
|
||||||
errorexit()
|
base.ErrorExit()
|
||||||
}
|
}
|
||||||
|
|
||||||
// collectDeps returns all of the package-level functions and
|
// collectDeps returns all of the package-level functions and
|
||||||
|
|
@ -256,7 +258,7 @@ func collectDeps(n *Node, transitive bool) NodeSet {
|
||||||
case ODCLFUNC:
|
case ODCLFUNC:
|
||||||
d.inspectList(n.Nbody)
|
d.inspectList(n.Nbody)
|
||||||
default:
|
default:
|
||||||
Fatalf("unexpected Op: %v", n.Op)
|
base.Fatalf("unexpected Op: %v", n.Op)
|
||||||
}
|
}
|
||||||
return d.seen
|
return d.seen
|
||||||
}
|
}
|
||||||
|
|
@ -347,6 +349,6 @@ func firstLHS(n *Node) *Node {
|
||||||
return n.List.First()
|
return n.List.First()
|
||||||
}
|
}
|
||||||
|
|
||||||
Fatalf("unexpected Op: %v", n.Op)
|
base.Fatalf("unexpected Op: %v", n.Op)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/logopt"
|
"cmd/compile/internal/logopt"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
|
|
@ -60,7 +61,7 @@ func fnpkg(fn *Node) *types.Pkg {
|
||||||
rcvr = rcvr.Elem()
|
rcvr = rcvr.Elem()
|
||||||
}
|
}
|
||||||
if rcvr.Sym == nil {
|
if rcvr.Sym == nil {
|
||||||
Fatalf("receiver with no sym: [%v] %L (%v)", fn.Sym, fn, rcvr)
|
base.Fatalf("receiver with no sym: [%v] %L (%v)", fn.Sym, fn, rcvr)
|
||||||
}
|
}
|
||||||
return rcvr.Sym.Pkg
|
return rcvr.Sym.Pkg
|
||||||
}
|
}
|
||||||
|
|
@ -86,7 +87,7 @@ func typecheckinl(fn *Node) {
|
||||||
return // typecheckinl on local function
|
return // typecheckinl on local function
|
||||||
}
|
}
|
||||||
|
|
||||||
if Flag.LowerM > 2 || Debug.Export != 0 {
|
if base.Flag.LowerM > 2 || base.Debug.Export != 0 {
|
||||||
fmt.Printf("typecheck import [%v] %L { %#v }\n", fn.Sym, fn, asNodes(fn.Func.Inl.Body))
|
fmt.Printf("typecheck import [%v] %L { %#v }\n", fn.Sym, fn, asNodes(fn.Func.Inl.Body))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -103,7 +104,7 @@ func typecheckinl(fn *Node) {
|
||||||
fn.Func.Inl.Dcl = append(fn.Func.Inl.Dcl, fn.Func.Dcl...)
|
fn.Func.Inl.Dcl = append(fn.Func.Inl.Dcl, fn.Func.Dcl...)
|
||||||
fn.Func.Dcl = nil
|
fn.Func.Dcl = nil
|
||||||
|
|
||||||
lineno = lno
|
base.Pos = lno
|
||||||
}
|
}
|
||||||
|
|
||||||
// Caninl determines whether fn is inlineable.
|
// Caninl determines whether fn is inlineable.
|
||||||
|
|
@ -111,17 +112,17 @@ func typecheckinl(fn *Node) {
|
||||||
// fn and ->nbody will already have been typechecked.
|
// fn and ->nbody will already have been typechecked.
|
||||||
func caninl(fn *Node) {
|
func caninl(fn *Node) {
|
||||||
if fn.Op != ODCLFUNC {
|
if fn.Op != ODCLFUNC {
|
||||||
Fatalf("caninl %v", fn)
|
base.Fatalf("caninl %v", fn)
|
||||||
}
|
}
|
||||||
if fn.Func.Nname == nil {
|
if fn.Func.Nname == nil {
|
||||||
Fatalf("caninl no nname %+v", fn)
|
base.Fatalf("caninl no nname %+v", fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
var reason string // reason, if any, that the function was not inlined
|
var reason string // reason, if any, that the function was not inlined
|
||||||
if Flag.LowerM > 1 || logopt.Enabled() {
|
if base.Flag.LowerM > 1 || logopt.Enabled() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if reason != "" {
|
if reason != "" {
|
||||||
if Flag.LowerM > 1 {
|
if base.Flag.LowerM > 1 {
|
||||||
fmt.Printf("%v: cannot inline %v: %s\n", fn.Line(), fn.Func.Nname, reason)
|
fmt.Printf("%v: cannot inline %v: %s\n", fn.Line(), fn.Func.Nname, reason)
|
||||||
}
|
}
|
||||||
if logopt.Enabled() {
|
if logopt.Enabled() {
|
||||||
|
|
@ -138,13 +139,13 @@ func caninl(fn *Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If marked "go:norace" and -race compilation, don't inline.
|
// If marked "go:norace" and -race compilation, don't inline.
|
||||||
if Flag.Race && fn.Func.Pragma&Norace != 0 {
|
if base.Flag.Race && fn.Func.Pragma&Norace != 0 {
|
||||||
reason = "marked go:norace with -race compilation"
|
reason = "marked go:norace with -race compilation"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// If marked "go:nocheckptr" and -d checkptr compilation, don't inline.
|
// If marked "go:nocheckptr" and -d checkptr compilation, don't inline.
|
||||||
if Debug.Checkptr != 0 && fn.Func.Pragma&NoCheckPtr != 0 {
|
if base.Debug.Checkptr != 0 && fn.Func.Pragma&NoCheckPtr != 0 {
|
||||||
reason = "marked go:nocheckptr"
|
reason = "marked go:nocheckptr"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -179,7 +180,7 @@ func caninl(fn *Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if fn.Typecheck() == 0 {
|
if fn.Typecheck() == 0 {
|
||||||
Fatalf("caninl on non-typechecked function %v", fn)
|
base.Fatalf("caninl on non-typechecked function %v", fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
n := fn.Func.Nname
|
n := fn.Func.Nname
|
||||||
|
|
@ -189,7 +190,7 @@ func caninl(fn *Node) {
|
||||||
defer n.Func.SetInlinabilityChecked(true)
|
defer n.Func.SetInlinabilityChecked(true)
|
||||||
|
|
||||||
cc := int32(inlineExtraCallCost)
|
cc := int32(inlineExtraCallCost)
|
||||||
if Flag.LowerL == 4 {
|
if base.Flag.LowerL == 4 {
|
||||||
cc = 1 // this appears to yield better performance than 0.
|
cc = 1 // this appears to yield better performance than 0.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -222,9 +223,9 @@ func caninl(fn *Node) {
|
||||||
Body: inlcopylist(fn.Nbody.Slice()),
|
Body: inlcopylist(fn.Nbody.Slice()),
|
||||||
}
|
}
|
||||||
|
|
||||||
if Flag.LowerM > 1 {
|
if base.Flag.LowerM > 1 {
|
||||||
fmt.Printf("%v: can inline %#v with cost %d as: %#v { %#v }\n", fn.Line(), n, inlineMaxBudget-visitor.budget, fn.Type, asNodes(n.Func.Inl.Body))
|
fmt.Printf("%v: can inline %#v with cost %d as: %#v { %#v }\n", fn.Line(), n, inlineMaxBudget-visitor.budget, fn.Type, asNodes(n.Func.Inl.Body))
|
||||||
} else if Flag.LowerM != 0 {
|
} else if base.Flag.LowerM != 0 {
|
||||||
fmt.Printf("%v: can inline %v\n", fn.Line(), n)
|
fmt.Printf("%v: can inline %v\n", fn.Line(), n)
|
||||||
}
|
}
|
||||||
if logopt.Enabled() {
|
if logopt.Enabled() {
|
||||||
|
|
@ -239,10 +240,10 @@ func inlFlood(n *Node) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if n.Op != ONAME || n.Class() != PFUNC {
|
if n.Op != ONAME || n.Class() != PFUNC {
|
||||||
Fatalf("inlFlood: unexpected %v, %v, %v", n, n.Op, n.Class())
|
base.Fatalf("inlFlood: unexpected %v, %v, %v", n, n.Op, n.Class())
|
||||||
}
|
}
|
||||||
if n.Func == nil {
|
if n.Func == nil {
|
||||||
Fatalf("inlFlood: missing Func on %v", n)
|
base.Fatalf("inlFlood: missing Func on %v", n)
|
||||||
}
|
}
|
||||||
if n.Func.Inl == nil {
|
if n.Func.Inl == nil {
|
||||||
return
|
return
|
||||||
|
|
@ -286,7 +287,7 @@ func inlFlood(n *Node) {
|
||||||
//
|
//
|
||||||
// When we do, we'll probably want:
|
// When we do, we'll probably want:
|
||||||
// inlFlood(n.Func.Closure.Func.Nname)
|
// inlFlood(n.Func.Closure.Func.Nname)
|
||||||
Fatalf("unexpected closure in inlinable function")
|
base.Fatalf("unexpected closure in inlinable function")
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
@ -352,7 +353,7 @@ func (v *hairyVisitor) visit(n *Node) bool {
|
||||||
case OCALLMETH:
|
case OCALLMETH:
|
||||||
t := n.Left.Type
|
t := n.Left.Type
|
||||||
if t == nil {
|
if t == nil {
|
||||||
Fatalf("no function type for [%p] %+v\n", n.Left, n.Left)
|
base.Fatalf("no function type for [%p] %+v\n", n.Left, n.Left)
|
||||||
}
|
}
|
||||||
if isRuntimePkg(n.Left.Sym.Pkg) {
|
if isRuntimePkg(n.Left.Sym.Pkg) {
|
||||||
fn := n.Left.Sym.Name
|
fn := n.Left.Sym.Name
|
||||||
|
|
@ -413,7 +414,7 @@ func (v *hairyVisitor) visit(n *Node) bool {
|
||||||
case OBREAK, OCONTINUE:
|
case OBREAK, OCONTINUE:
|
||||||
if n.Sym != nil {
|
if n.Sym != nil {
|
||||||
// Should have short-circuited due to labeledControl above.
|
// Should have short-circuited due to labeledControl above.
|
||||||
Fatalf("unexpected labeled break/continue: %v", n)
|
base.Fatalf("unexpected labeled break/continue: %v", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
case OIF:
|
case OIF:
|
||||||
|
|
@ -433,7 +434,7 @@ func (v *hairyVisitor) visit(n *Node) bool {
|
||||||
v.budget--
|
v.budget--
|
||||||
|
|
||||||
// When debugging, don't stop early, to get full cost of inlining this function
|
// When debugging, don't stop early, to get full cost of inlining this function
|
||||||
if v.budget < 0 && Flag.LowerM < 2 && !logopt.Enabled() {
|
if v.budget < 0 && base.Flag.LowerM < 2 && !logopt.Enabled() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -465,7 +466,7 @@ func inlcopy(n *Node) *Node {
|
||||||
|
|
||||||
m := n.copy()
|
m := n.copy()
|
||||||
if n.Op != OCALLPART && m.Func != nil {
|
if n.Op != OCALLPART && m.Func != nil {
|
||||||
Fatalf("unexpected Func: %v", m)
|
base.Fatalf("unexpected Func: %v", m)
|
||||||
}
|
}
|
||||||
m.Left = inlcopy(n.Left)
|
m.Left = inlcopy(n.Left)
|
||||||
m.Right = inlcopy(n.Right)
|
m.Right = inlcopy(n.Right)
|
||||||
|
|
@ -517,7 +518,7 @@ func inlcalls(fn *Node) {
|
||||||
inlMap := make(map[*Node]bool)
|
inlMap := make(map[*Node]bool)
|
||||||
fn = inlnode(fn, maxCost, inlMap)
|
fn = inlnode(fn, maxCost, inlMap)
|
||||||
if fn != Curfn {
|
if fn != Curfn {
|
||||||
Fatalf("inlnode replaced curfn")
|
base.Fatalf("inlnode replaced curfn")
|
||||||
}
|
}
|
||||||
Curfn = savefn
|
Curfn = savefn
|
||||||
}
|
}
|
||||||
|
|
@ -548,7 +549,7 @@ func inlconv2expr(n *Node) *Node {
|
||||||
// statements.
|
// statements.
|
||||||
func inlconv2list(n *Node) []*Node {
|
func inlconv2list(n *Node) []*Node {
|
||||||
if n.Op != OINLCALL || n.Rlist.Len() == 0 {
|
if n.Op != OINLCALL || n.Rlist.Len() == 0 {
|
||||||
Fatalf("inlconv2list %+v\n", n)
|
base.Fatalf("inlconv2list %+v\n", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
s := n.Rlist.Slice()
|
s := n.Rlist.Slice()
|
||||||
|
|
@ -595,7 +596,7 @@ func inlnode(n *Node, maxCost int32, inlMap map[*Node]bool) *Node {
|
||||||
case OCALLMETH:
|
case OCALLMETH:
|
||||||
// Prevent inlining some reflect.Value methods when using checkptr,
|
// Prevent inlining some reflect.Value methods when using checkptr,
|
||||||
// even when package reflect was compiled without it (#35073).
|
// even when package reflect was compiled without it (#35073).
|
||||||
if s := n.Left.Sym; Debug.Checkptr != 0 && isReflectPkg(s.Pkg) && (s.Name == "Value.UnsafeAddr" || s.Name == "Value.Pointer") {
|
if s := n.Left.Sym; base.Debug.Checkptr != 0 && isReflectPkg(s.Pkg) && (s.Name == "Value.UnsafeAddr" || s.Name == "Value.Pointer") {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -676,7 +677,7 @@ func inlnode(n *Node, maxCost int32, inlMap map[*Node]bool) *Node {
|
||||||
|
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
case OCALLFUNC:
|
case OCALLFUNC:
|
||||||
if Flag.LowerM > 3 {
|
if base.Flag.LowerM > 3 {
|
||||||
fmt.Printf("%v:call to func %+v\n", n.Line(), n.Left)
|
fmt.Printf("%v:call to func %+v\n", n.Line(), n.Left)
|
||||||
}
|
}
|
||||||
if isIntrinsicCall(n) {
|
if isIntrinsicCall(n) {
|
||||||
|
|
@ -687,19 +688,19 @@ func inlnode(n *Node, maxCost int32, inlMap map[*Node]bool) *Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
case OCALLMETH:
|
case OCALLMETH:
|
||||||
if Flag.LowerM > 3 {
|
if base.Flag.LowerM > 3 {
|
||||||
fmt.Printf("%v:call to meth %L\n", n.Line(), n.Left.Right)
|
fmt.Printf("%v:call to meth %L\n", n.Line(), n.Left.Right)
|
||||||
}
|
}
|
||||||
|
|
||||||
// typecheck should have resolved ODOTMETH->type, whose nname points to the actual function.
|
// typecheck should have resolved ODOTMETH->type, whose nname points to the actual function.
|
||||||
if n.Left.Type == nil {
|
if n.Left.Type == nil {
|
||||||
Fatalf("no function type for [%p] %+v\n", n.Left, n.Left)
|
base.Fatalf("no function type for [%p] %+v\n", n.Left, n.Left)
|
||||||
}
|
}
|
||||||
|
|
||||||
n = mkinlcall(n, n.Left.MethodName(), maxCost, inlMap)
|
n = mkinlcall(n, n.Left.MethodName(), maxCost, inlMap)
|
||||||
}
|
}
|
||||||
|
|
||||||
lineno = lno
|
base.Pos = lno
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -767,12 +768,12 @@ FindRHS:
|
||||||
break FindRHS
|
break FindRHS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Fatalf("%v missing from LHS of %v", n, defn)
|
base.Fatalf("%v missing from LHS of %v", n, defn)
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if rhs == nil {
|
if rhs == nil {
|
||||||
Fatalf("RHS is nil: %v", defn)
|
base.Fatalf("RHS is nil: %v", defn)
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe, _ := reassigned(n)
|
unsafe, _ := reassigned(n)
|
||||||
|
|
@ -791,7 +792,7 @@ FindRHS:
|
||||||
// TODO: handle initial declaration not including an assignment and followed by a single assignment?
|
// TODO: handle initial declaration not including an assignment and followed by a single assignment?
|
||||||
func reassigned(n *Node) (bool, *Node) {
|
func reassigned(n *Node) (bool, *Node) {
|
||||||
if n.Op != ONAME {
|
if n.Op != ONAME {
|
||||||
Fatalf("reassigned %v", n)
|
base.Fatalf("reassigned %v", n)
|
||||||
}
|
}
|
||||||
// no way to reliably check for no-reassignment of globals, assume it can be
|
// no way to reliably check for no-reassignment of globals, assume it can be
|
||||||
if n.Name.Curfn == nil {
|
if n.Name.Curfn == nil {
|
||||||
|
|
@ -869,7 +870,7 @@ func inlParam(t *types.Field, as *Node, inlvars map[*Node]*Node) *Node {
|
||||||
|
|
||||||
inlvar := inlvars[n]
|
inlvar := inlvars[n]
|
||||||
if inlvar == nil {
|
if inlvar == nil {
|
||||||
Fatalf("missing inlvar for %v", n)
|
base.Fatalf("missing inlvar for %v", n)
|
||||||
}
|
}
|
||||||
as.Ninit.Append(nod(ODCL, inlvar, nil))
|
as.Ninit.Append(nod(ODCL, inlvar, nil))
|
||||||
inlvar.Name.Defn = as
|
inlvar.Name.Defn = as
|
||||||
|
|
@ -922,7 +923,7 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
if inlMap[fn] {
|
if inlMap[fn] {
|
||||||
if Flag.LowerM > 1 {
|
if base.Flag.LowerM > 1 {
|
||||||
fmt.Printf("%v: cannot inline %v into %v: repeated recursive cycle\n", n.Line(), fn, Curfn.funcname())
|
fmt.Printf("%v: cannot inline %v into %v: repeated recursive cycle\n", n.Line(), fn, Curfn.funcname())
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
|
|
@ -931,17 +932,17 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
|
||||||
defer func() {
|
defer func() {
|
||||||
inlMap[fn] = false
|
inlMap[fn] = false
|
||||||
}()
|
}()
|
||||||
if Debug.TypecheckInl == 0 {
|
if base.Debug.TypecheckInl == 0 {
|
||||||
typecheckinl(fn)
|
typecheckinl(fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have a function node, and it has an inlineable body.
|
// We have a function node, and it has an inlineable body.
|
||||||
if Flag.LowerM > 1 {
|
if base.Flag.LowerM > 1 {
|
||||||
fmt.Printf("%v: inlining call to %v %#v { %#v }\n", n.Line(), fn.Sym, fn.Type, asNodes(fn.Func.Inl.Body))
|
fmt.Printf("%v: inlining call to %v %#v { %#v }\n", n.Line(), fn.Sym, fn.Type, asNodes(fn.Func.Inl.Body))
|
||||||
} else if Flag.LowerM != 0 {
|
} else if base.Flag.LowerM != 0 {
|
||||||
fmt.Printf("%v: inlining call to %v\n", n.Line(), fn)
|
fmt.Printf("%v: inlining call to %v\n", n.Line(), fn)
|
||||||
}
|
}
|
||||||
if Flag.LowerM > 2 {
|
if base.Flag.LowerM > 2 {
|
||||||
fmt.Printf("%v: Before inlining: %+v\n", n.Line(), n)
|
fmt.Printf("%v: Before inlining: %+v\n", n.Line(), n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -962,7 +963,7 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
|
||||||
callee = callee.Left
|
callee = callee.Left
|
||||||
}
|
}
|
||||||
if callee.Op != ONAME && callee.Op != OCLOSURE && callee.Op != OMETHEXPR {
|
if callee.Op != ONAME && callee.Op != OCLOSURE && callee.Op != OMETHEXPR {
|
||||||
Fatalf("unexpected callee expression: %v", callee)
|
base.Fatalf("unexpected callee expression: %v", callee)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -986,7 +987,7 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
|
||||||
// the reassigned check via some sort of copy propagation this would most
|
// the reassigned check via some sort of copy propagation this would most
|
||||||
// likely need to be changed to a loop to walk up to the correct Param
|
// likely need to be changed to a loop to walk up to the correct Param
|
||||||
if o == nil || (o.Name.Curfn != Curfn && o.Name.Curfn.Func.OClosure != Curfn) {
|
if o == nil || (o.Name.Curfn != Curfn && o.Name.Curfn.Func.OClosure != Curfn) {
|
||||||
Fatalf("%v: unresolvable capture %v %v\n", n.Line(), fn, v)
|
base.Fatalf("%v: unresolvable capture %v %v\n", n.Line(), fn, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
if v.Name.Byval() {
|
if v.Name.Byval() {
|
||||||
|
|
@ -1022,11 +1023,11 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
|
||||||
// this never actually happens. We currently
|
// this never actually happens. We currently
|
||||||
// perform inlining before escape analysis, so
|
// perform inlining before escape analysis, so
|
||||||
// nothing should have moved to the heap yet.
|
// nothing should have moved to the heap yet.
|
||||||
Fatalf("impossible: %v", ln)
|
base.Fatalf("impossible: %v", ln)
|
||||||
}
|
}
|
||||||
inlf := typecheck(inlvar(ln), ctxExpr)
|
inlf := typecheck(inlvar(ln), ctxExpr)
|
||||||
inlvars[ln] = inlf
|
inlvars[ln] = inlf
|
||||||
if Flag.GenDwarfInl > 0 {
|
if base.Flag.GenDwarfInl > 0 {
|
||||||
if ln.Class() == PPARAM {
|
if ln.Class() == PPARAM {
|
||||||
inlf.Name.SetInlFormal(true)
|
inlf.Name.SetInlFormal(true)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1064,7 +1065,7 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
|
||||||
m = retvar(t, i)
|
m = retvar(t, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
if Flag.GenDwarfInl > 0 {
|
if base.Flag.GenDwarfInl > 0 {
|
||||||
// Don't update the src.Pos on a return variable if it
|
// Don't update the src.Pos on a return variable if it
|
||||||
// was manufactured by the inliner (e.g. "~R2"); such vars
|
// was manufactured by the inliner (e.g. "~R2"); such vars
|
||||||
// were not part of the original callee.
|
// were not part of the original callee.
|
||||||
|
|
@ -1083,7 +1084,7 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
|
||||||
as.SetColas(true)
|
as.SetColas(true)
|
||||||
if n.Op == OCALLMETH {
|
if n.Op == OCALLMETH {
|
||||||
if n.Left.Left == nil {
|
if n.Left.Left == nil {
|
||||||
Fatalf("method call without receiver: %+v", n)
|
base.Fatalf("method call without receiver: %+v", n)
|
||||||
}
|
}
|
||||||
as.Rlist.Append(n.Left.Left)
|
as.Rlist.Append(n.Left.Left)
|
||||||
}
|
}
|
||||||
|
|
@ -1150,10 +1151,10 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
|
||||||
inlgen++
|
inlgen++
|
||||||
|
|
||||||
parent := -1
|
parent := -1
|
||||||
if b := Ctxt.PosTable.Pos(n.Pos).Base(); b != nil {
|
if b := base.Ctxt.PosTable.Pos(n.Pos).Base(); b != nil {
|
||||||
parent = b.InliningIndex()
|
parent = b.InliningIndex()
|
||||||
}
|
}
|
||||||
newIndex := Ctxt.InlTree.Add(parent, n.Pos, fn.Sym.Linksym())
|
newIndex := base.Ctxt.InlTree.Add(parent, n.Pos, fn.Sym.Linksym())
|
||||||
|
|
||||||
// Add an inline mark just before the inlined body.
|
// Add an inline mark just before the inlined body.
|
||||||
// This mark is inline in the code so that it's a reasonable spot
|
// This mark is inline in the code so that it's a reasonable spot
|
||||||
|
|
@ -1165,9 +1166,9 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
|
||||||
inlMark.Xoffset = int64(newIndex)
|
inlMark.Xoffset = int64(newIndex)
|
||||||
ninit.Append(inlMark)
|
ninit.Append(inlMark)
|
||||||
|
|
||||||
if Flag.GenDwarfInl > 0 {
|
if base.Flag.GenDwarfInl > 0 {
|
||||||
if !fn.Sym.Linksym().WasInlined() {
|
if !fn.Sym.Linksym().WasInlined() {
|
||||||
Ctxt.DwFixups.SetPrecursorFunc(fn.Sym.Linksym(), fn)
|
base.Ctxt.DwFixups.SetPrecursorFunc(fn.Sym.Linksym(), fn)
|
||||||
fn.Sym.Linksym().Set(obj.AttrWasInlined, true)
|
fn.Sym.Linksym().Set(obj.AttrWasInlined, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1188,7 +1189,7 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
|
||||||
|
|
||||||
typecheckslice(body, ctxStmt)
|
typecheckslice(body, ctxStmt)
|
||||||
|
|
||||||
if Flag.GenDwarfInl > 0 {
|
if base.Flag.GenDwarfInl > 0 {
|
||||||
for _, v := range inlfvars {
|
for _, v := range inlfvars {
|
||||||
v.Pos = subst.updatedPos(v.Pos)
|
v.Pos = subst.updatedPos(v.Pos)
|
||||||
}
|
}
|
||||||
|
|
@ -1216,7 +1217,7 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if Flag.LowerM > 2 {
|
if base.Flag.LowerM > 2 {
|
||||||
fmt.Printf("%v: After inlining %+v\n\n", call.Line(), call)
|
fmt.Printf("%v: After inlining %+v\n\n", call.Line(), call)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1227,7 +1228,7 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
|
||||||
// PAUTO's in the calling functions, and link them off of the
|
// PAUTO's in the calling functions, and link them off of the
|
||||||
// PPARAM's, PAUTOS and PPARAMOUTs of the called function.
|
// PPARAM's, PAUTOS and PPARAMOUTs of the called function.
|
||||||
func inlvar(var_ *Node) *Node {
|
func inlvar(var_ *Node) *Node {
|
||||||
if Flag.LowerM > 3 {
|
if base.Flag.LowerM > 3 {
|
||||||
fmt.Printf("inlvar %+v\n", var_)
|
fmt.Printf("inlvar %+v\n", var_)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1310,13 +1311,13 @@ func (subst *inlsubst) node(n *Node) *Node {
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
case ONAME:
|
case ONAME:
|
||||||
if inlvar := subst.inlvars[n]; inlvar != nil { // These will be set during inlnode
|
if inlvar := subst.inlvars[n]; inlvar != nil { // These will be set during inlnode
|
||||||
if Flag.LowerM > 2 {
|
if base.Flag.LowerM > 2 {
|
||||||
fmt.Printf("substituting name %+v -> %+v\n", n, inlvar)
|
fmt.Printf("substituting name %+v -> %+v\n", n, inlvar)
|
||||||
}
|
}
|
||||||
return inlvar
|
return inlvar
|
||||||
}
|
}
|
||||||
|
|
||||||
if Flag.LowerM > 2 {
|
if base.Flag.LowerM > 2 {
|
||||||
fmt.Printf("not substituting name %+v\n", n)
|
fmt.Printf("not substituting name %+v\n", n)
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
|
|
@ -1382,7 +1383,7 @@ func (subst *inlsubst) node(n *Node) *Node {
|
||||||
m.Ninit.Set(nil)
|
m.Ninit.Set(nil)
|
||||||
|
|
||||||
if n.Op == OCLOSURE {
|
if n.Op == OCLOSURE {
|
||||||
Fatalf("cannot inline function containing closure: %+v", n)
|
base.Fatalf("cannot inline function containing closure: %+v", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
m.Left = subst.node(n.Left)
|
m.Left = subst.node(n.Left)
|
||||||
|
|
@ -1396,7 +1397,7 @@ func (subst *inlsubst) node(n *Node) *Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (subst *inlsubst) updatedPos(xpos src.XPos) src.XPos {
|
func (subst *inlsubst) updatedPos(xpos src.XPos) src.XPos {
|
||||||
pos := Ctxt.PosTable.Pos(xpos)
|
pos := base.Ctxt.PosTable.Pos(xpos)
|
||||||
oldbase := pos.Base() // can be nil
|
oldbase := pos.Base() // can be nil
|
||||||
newbase := subst.bases[oldbase]
|
newbase := subst.bases[oldbase]
|
||||||
if newbase == nil {
|
if newbase == nil {
|
||||||
|
|
@ -1404,7 +1405,7 @@ func (subst *inlsubst) updatedPos(xpos src.XPos) src.XPos {
|
||||||
subst.bases[oldbase] = newbase
|
subst.bases[oldbase] = newbase
|
||||||
}
|
}
|
||||||
pos.SetBase(newbase)
|
pos.SetBase(newbase)
|
||||||
return Ctxt.PosTable.XPos(pos)
|
return base.Ctxt.PosTable.XPos(pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
func pruneUnusedAutos(ll []*Node, vis *hairyVisitor) []*Node {
|
func pruneUnusedAutos(ll []*Node, vis *hairyVisitor) []*Node {
|
||||||
|
|
@ -1449,22 +1450,22 @@ func devirtualizeCall(call *Node) {
|
||||||
x = typecheck(x, ctxExpr|ctxCallee)
|
x = typecheck(x, ctxExpr|ctxCallee)
|
||||||
switch x.Op {
|
switch x.Op {
|
||||||
case ODOTMETH:
|
case ODOTMETH:
|
||||||
if Flag.LowerM != 0 {
|
if base.Flag.LowerM != 0 {
|
||||||
Warnl(call.Pos, "devirtualizing %v to %v", call.Left, typ)
|
base.WarnfAt(call.Pos, "devirtualizing %v to %v", call.Left, typ)
|
||||||
}
|
}
|
||||||
call.Op = OCALLMETH
|
call.Op = OCALLMETH
|
||||||
call.Left = x
|
call.Left = x
|
||||||
case ODOTINTER:
|
case ODOTINTER:
|
||||||
// Promoted method from embedded interface-typed field (#42279).
|
// Promoted method from embedded interface-typed field (#42279).
|
||||||
if Flag.LowerM != 0 {
|
if base.Flag.LowerM != 0 {
|
||||||
Warnl(call.Pos, "partially devirtualizing %v to %v", call.Left, typ)
|
base.WarnfAt(call.Pos, "partially devirtualizing %v to %v", call.Left, typ)
|
||||||
}
|
}
|
||||||
call.Op = OCALLINTER
|
call.Op = OCALLINTER
|
||||||
call.Left = x
|
call.Left = x
|
||||||
default:
|
default:
|
||||||
// TODO(mdempsky): Turn back into Fatalf after more testing.
|
// TODO(mdempsky): Turn back into Fatalf after more testing.
|
||||||
if Flag.LowerM != 0 {
|
if base.Flag.LowerM != 0 {
|
||||||
Warnl(call.Pos, "failed to devirtualize %v (%v)", x, x.Op)
|
base.WarnfAt(call.Pos, "failed to devirtualize %v (%v)", x, x.Op)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/syntax"
|
"cmd/compile/internal/syntax"
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/src"
|
"cmd/internal/src"
|
||||||
|
|
@ -13,7 +14,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func makePos(b *src.PosBase, line, col uint) src.XPos {
|
func makePos(b *src.PosBase, line, col uint) src.XPos {
|
||||||
return Ctxt.PosTable.XPos(src.MakePos(b, line, col))
|
return base.Ctxt.PosTable.XPos(src.MakePos(b, line, col))
|
||||||
}
|
}
|
||||||
|
|
||||||
func isSpace(c rune) bool {
|
func isSpace(c rune) bool {
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ package gc
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/logopt"
|
"cmd/compile/internal/logopt"
|
||||||
"cmd/compile/internal/ssa"
|
"cmd/compile/internal/ssa"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
|
|
@ -35,13 +36,13 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func hidePanic() {
|
func hidePanic() {
|
||||||
if Debug.Panic == 0 && Errors() > 0 {
|
if base.Debug.Panic == 0 && base.Errors() > 0 {
|
||||||
// If we've already complained about things
|
// If we've already complained about things
|
||||||
// in the program, don't bother complaining
|
// in the program, don't bother complaining
|
||||||
// about a panic too; let the user clean up
|
// about a panic too; let the user clean up
|
||||||
// the code and try again.
|
// the code and try again.
|
||||||
if err := recover(); err != nil {
|
if err := recover(); err != nil {
|
||||||
errorexit()
|
base.ErrorExit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -61,16 +62,16 @@ func Main(archInit func(*Arch)) {
|
||||||
|
|
||||||
archInit(&thearch)
|
archInit(&thearch)
|
||||||
|
|
||||||
Ctxt = obj.Linknew(thearch.LinkArch)
|
base.Ctxt = obj.Linknew(thearch.LinkArch)
|
||||||
Ctxt.DiagFunc = yyerror
|
base.Ctxt.DiagFunc = base.Errorf
|
||||||
Ctxt.DiagFlush = flusherrors
|
base.Ctxt.DiagFlush = base.FlushErrors
|
||||||
Ctxt.Bso = bufio.NewWriter(os.Stdout)
|
base.Ctxt.Bso = bufio.NewWriter(os.Stdout)
|
||||||
|
|
||||||
// UseBASEntries is preferred because it shaves about 2% off build time, but LLDB, dsymutil, and dwarfdump
|
// UseBASEntries is preferred because it shaves about 2% off build time, but LLDB, dsymutil, and dwarfdump
|
||||||
// on Darwin don't support it properly, especially since macOS 10.14 (Mojave). This is exposed as a flag
|
// on Darwin don't support it properly, especially since macOS 10.14 (Mojave). This is exposed as a flag
|
||||||
// to allow testing with LLVM tools on Linux, and to help with reporting this bug to the LLVM project.
|
// to allow testing with LLVM tools on Linux, and to help with reporting this bug to the LLVM project.
|
||||||
// See bugs 31188 and 21945 (CLs 170638, 98075, 72371).
|
// See bugs 31188 and 21945 (CLs 170638, 98075, 72371).
|
||||||
Ctxt.UseBASEntries = Ctxt.Headtype != objabi.Hdarwin
|
base.Ctxt.UseBASEntries = base.Ctxt.Headtype != objabi.Hdarwin
|
||||||
|
|
||||||
localpkg = types.NewPkg("", "")
|
localpkg = types.NewPkg("", "")
|
||||||
localpkg.Prefix = "\"\""
|
localpkg.Prefix = "\"\""
|
||||||
|
|
@ -112,15 +113,15 @@ func Main(archInit func(*Arch)) {
|
||||||
// pseudo-package used for methods with anonymous receivers
|
// pseudo-package used for methods with anonymous receivers
|
||||||
gopkg = types.NewPkg("go", "")
|
gopkg = types.NewPkg("go", "")
|
||||||
|
|
||||||
DebugSSA = ssa.PhaseOption
|
base.DebugSSA = ssa.PhaseOption
|
||||||
ParseFlags()
|
base.ParseFlags()
|
||||||
|
|
||||||
// Record flags that affect the build result. (And don't
|
// Record flags that affect the build result. (And don't
|
||||||
// record flags that don't, since that would cause spurious
|
// record flags that don't, since that would cause spurious
|
||||||
// changes in the binary.)
|
// changes in the binary.)
|
||||||
recordFlags("B", "N", "l", "msan", "race", "shared", "dynlink", "dwarflocationlists", "dwarfbasentries", "smallframes", "spectre")
|
recordFlags("B", "N", "l", "msan", "race", "shared", "dynlink", "dwarflocationlists", "dwarfbasentries", "smallframes", "spectre")
|
||||||
|
|
||||||
if !enableTrace && Flag.LowerT {
|
if !enableTrace && base.Flag.LowerT {
|
||||||
log.Fatalf("compiler not built with support for -t")
|
log.Fatalf("compiler not built with support for -t")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -128,59 +129,59 @@ func Main(archInit func(*Arch)) {
|
||||||
// default: inlining on. (Flag.LowerL == 1)
|
// default: inlining on. (Flag.LowerL == 1)
|
||||||
// -l: inlining off (Flag.LowerL == 0)
|
// -l: inlining off (Flag.LowerL == 0)
|
||||||
// -l=2, -l=3: inlining on again, with extra debugging (Flag.LowerL > 1)
|
// -l=2, -l=3: inlining on again, with extra debugging (Flag.LowerL > 1)
|
||||||
if Flag.LowerL <= 1 {
|
if base.Flag.LowerL <= 1 {
|
||||||
Flag.LowerL = 1 - Flag.LowerL
|
base.Flag.LowerL = 1 - base.Flag.LowerL
|
||||||
}
|
}
|
||||||
|
|
||||||
if Flag.SmallFrames {
|
if base.Flag.SmallFrames {
|
||||||
maxStackVarSize = 128 * 1024
|
maxStackVarSize = 128 * 1024
|
||||||
maxImplicitStackVarSize = 16 * 1024
|
maxImplicitStackVarSize = 16 * 1024
|
||||||
}
|
}
|
||||||
|
|
||||||
if Flag.Dwarf {
|
if base.Flag.Dwarf {
|
||||||
Ctxt.DebugInfo = debuginfo
|
base.Ctxt.DebugInfo = debuginfo
|
||||||
Ctxt.GenAbstractFunc = genAbstractFunc
|
base.Ctxt.GenAbstractFunc = genAbstractFunc
|
||||||
Ctxt.DwFixups = obj.NewDwarfFixupTable(Ctxt)
|
base.Ctxt.DwFixups = obj.NewDwarfFixupTable(base.Ctxt)
|
||||||
} else {
|
} else {
|
||||||
// turn off inline generation if no dwarf at all
|
// turn off inline generation if no dwarf at all
|
||||||
Flag.GenDwarfInl = 0
|
base.Flag.GenDwarfInl = 0
|
||||||
Ctxt.Flag_locationlists = false
|
base.Ctxt.Flag_locationlists = false
|
||||||
}
|
}
|
||||||
if Ctxt.Flag_locationlists && len(Ctxt.Arch.DWARFRegisters) == 0 {
|
if base.Ctxt.Flag_locationlists && len(base.Ctxt.Arch.DWARFRegisters) == 0 {
|
||||||
log.Fatalf("location lists requested but register mapping not available on %v", Ctxt.Arch.Name)
|
log.Fatalf("location lists requested but register mapping not available on %v", base.Ctxt.Arch.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
checkLang()
|
checkLang()
|
||||||
|
|
||||||
if Flag.SymABIs != "" {
|
if base.Flag.SymABIs != "" {
|
||||||
readSymABIs(Flag.SymABIs, Ctxt.Pkgpath)
|
readSymABIs(base.Flag.SymABIs, base.Ctxt.Pkgpath)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ispkgin(omit_pkgs) {
|
if ispkgin(omit_pkgs) {
|
||||||
Flag.Race = false
|
base.Flag.Race = false
|
||||||
Flag.MSan = false
|
base.Flag.MSan = false
|
||||||
}
|
}
|
||||||
|
|
||||||
thearch.LinkArch.Init(Ctxt)
|
thearch.LinkArch.Init(base.Ctxt)
|
||||||
startProfile()
|
startProfile()
|
||||||
if Flag.Race {
|
if base.Flag.Race {
|
||||||
racepkg = types.NewPkg("runtime/race", "")
|
racepkg = types.NewPkg("runtime/race", "")
|
||||||
}
|
}
|
||||||
if Flag.MSan {
|
if base.Flag.MSan {
|
||||||
msanpkg = types.NewPkg("runtime/msan", "")
|
msanpkg = types.NewPkg("runtime/msan", "")
|
||||||
}
|
}
|
||||||
if Flag.Race || Flag.MSan {
|
if base.Flag.Race || base.Flag.MSan {
|
||||||
instrumenting = true
|
instrumenting = true
|
||||||
}
|
}
|
||||||
if Flag.Dwarf {
|
if base.Flag.Dwarf {
|
||||||
dwarf.EnableLogging(Debug.DwarfInl != 0)
|
dwarf.EnableLogging(base.Debug.DwarfInl != 0)
|
||||||
}
|
}
|
||||||
if Debug.SoftFloat != 0 {
|
if base.Debug.SoftFloat != 0 {
|
||||||
thearch.SoftFloat = true
|
thearch.SoftFloat = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if Flag.JSON != "" { // parse version,destination from json logging optimization.
|
if base.Flag.JSON != "" { // parse version,destination from json logging optimization.
|
||||||
logopt.LogJsonOption(Flag.JSON)
|
logopt.LogJsonOption(base.Flag.JSON)
|
||||||
}
|
}
|
||||||
|
|
||||||
ssaDump = os.Getenv("GOSSAFUNC")
|
ssaDump = os.Getenv("GOSSAFUNC")
|
||||||
|
|
@ -197,7 +198,7 @@ func Main(archInit func(*Arch)) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trackScopes = Flag.Dwarf
|
trackScopes = base.Flag.Dwarf
|
||||||
|
|
||||||
Widthptr = thearch.LinkArch.PtrSize
|
Widthptr = thearch.LinkArch.PtrSize
|
||||||
Widthreg = thearch.LinkArch.RegSize
|
Widthreg = thearch.LinkArch.RegSize
|
||||||
|
|
@ -207,7 +208,7 @@ func Main(archInit func(*Arch)) {
|
||||||
// would lead to import cycles)
|
// would lead to import cycles)
|
||||||
types.Widthptr = Widthptr
|
types.Widthptr = Widthptr
|
||||||
types.Dowidth = dowidth
|
types.Dowidth = dowidth
|
||||||
types.Fatalf = Fatalf
|
types.Fatalf = base.Fatalf
|
||||||
types.Sconv = func(s *types.Sym, flag, mode int) string {
|
types.Sconv = func(s *types.Sym, flag, mode int) string {
|
||||||
return sconv(s, FmtFlag(flag), fmtMode(mode))
|
return sconv(s, FmtFlag(flag), fmtMode(mode))
|
||||||
}
|
}
|
||||||
|
|
@ -226,7 +227,7 @@ func Main(archInit func(*Arch)) {
|
||||||
types.FmtLeft = int(FmtLeft)
|
types.FmtLeft = int(FmtLeft)
|
||||||
types.FmtUnsigned = int(FmtUnsigned)
|
types.FmtUnsigned = int(FmtUnsigned)
|
||||||
types.FErr = int(FErr)
|
types.FErr = int(FErr)
|
||||||
types.Ctxt = Ctxt
|
types.Ctxt = base.Ctxt
|
||||||
|
|
||||||
initUniverse()
|
initUniverse()
|
||||||
|
|
||||||
|
|
@ -288,10 +289,10 @@ func Main(archInit func(*Arch)) {
|
||||||
if n.Op == ODCLFUNC {
|
if n.Op == ODCLFUNC {
|
||||||
Curfn = n
|
Curfn = n
|
||||||
decldepth = 1
|
decldepth = 1
|
||||||
errorsBefore := Errors()
|
errorsBefore := base.Errors()
|
||||||
typecheckslice(Curfn.Nbody.Slice(), ctxStmt)
|
typecheckslice(Curfn.Nbody.Slice(), ctxStmt)
|
||||||
checkreturn(Curfn)
|
checkreturn(Curfn)
|
||||||
if Errors() > errorsBefore {
|
if base.Errors() > errorsBefore {
|
||||||
Curfn.Nbody.Set(nil) // type errors; do not compile
|
Curfn.Nbody.Set(nil) // type errors; do not compile
|
||||||
}
|
}
|
||||||
// Now that we've checked whether n terminates,
|
// Now that we've checked whether n terminates,
|
||||||
|
|
@ -304,7 +305,7 @@ func Main(archInit func(*Arch)) {
|
||||||
// check past phase 9 isn't sufficient, as we may exit with other errors
|
// check past phase 9 isn't sufficient, as we may exit with other errors
|
||||||
// before then, thus skipping map key errors.
|
// before then, thus skipping map key errors.
|
||||||
checkMapKeys()
|
checkMapKeys()
|
||||||
ExitIfErrors()
|
base.ExitIfErrors()
|
||||||
|
|
||||||
timings.AddEvent(fcount, "funcs")
|
timings.AddEvent(fcount, "funcs")
|
||||||
|
|
||||||
|
|
@ -322,11 +323,11 @@ func Main(archInit func(*Arch)) {
|
||||||
}
|
}
|
||||||
capturevarscomplete = true
|
capturevarscomplete = true
|
||||||
Curfn = nil
|
Curfn = nil
|
||||||
ExitIfErrors()
|
base.ExitIfErrors()
|
||||||
|
|
||||||
// Phase 5: Inlining
|
// Phase 5: Inlining
|
||||||
timings.Start("fe", "inlining")
|
timings.Start("fe", "inlining")
|
||||||
if Debug.TypecheckInl != 0 {
|
if base.Debug.TypecheckInl != 0 {
|
||||||
// Typecheck imported function bodies if Debug.l > 1,
|
// Typecheck imported function bodies if Debug.l > 1,
|
||||||
// otherwise lazily when used or re-exported.
|
// otherwise lazily when used or re-exported.
|
||||||
for _, n := range importlist {
|
for _, n := range importlist {
|
||||||
|
|
@ -334,10 +335,10 @@ func Main(archInit func(*Arch)) {
|
||||||
typecheckinl(n)
|
typecheckinl(n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExitIfErrors()
|
base.ExitIfErrors()
|
||||||
}
|
}
|
||||||
|
|
||||||
if Flag.LowerL != 0 {
|
if base.Flag.LowerL != 0 {
|
||||||
// Find functions that can be inlined and clone them before walk expands them.
|
// Find functions that can be inlined and clone them before walk expands them.
|
||||||
visitBottomUp(xtop, func(list []*Node, recursive bool) {
|
visitBottomUp(xtop, func(list []*Node, recursive bool) {
|
||||||
numfns := numNonClosures(list)
|
numfns := numNonClosures(list)
|
||||||
|
|
@ -348,7 +349,7 @@ func Main(archInit func(*Arch)) {
|
||||||
// across more than one function.
|
// across more than one function.
|
||||||
caninl(n)
|
caninl(n)
|
||||||
} else {
|
} else {
|
||||||
if Flag.LowerM > 1 {
|
if base.Flag.LowerM > 1 {
|
||||||
fmt.Printf("%v: cannot inline %v: recursive\n", n.Line(), n.Func.Nname)
|
fmt.Printf("%v: cannot inline %v: recursive\n", n.Line(), n.Func.Nname)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -379,7 +380,7 @@ func Main(archInit func(*Arch)) {
|
||||||
// checking. This must happen before transformclosure.
|
// checking. This must happen before transformclosure.
|
||||||
// We'll do the final check after write barriers are
|
// We'll do the final check after write barriers are
|
||||||
// inserted.
|
// inserted.
|
||||||
if Flag.CompilingRuntime {
|
if base.Flag.CompilingRuntime {
|
||||||
nowritebarrierrecCheck = newNowritebarrierrecChecker()
|
nowritebarrierrecCheck = newNowritebarrierrecChecker()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -430,10 +431,10 @@ func Main(archInit func(*Arch)) {
|
||||||
// Finalize DWARF inline routine DIEs, then explicitly turn off
|
// Finalize DWARF inline routine DIEs, then explicitly turn off
|
||||||
// DWARF inlining gen so as to avoid problems with generated
|
// DWARF inlining gen so as to avoid problems with generated
|
||||||
// method wrappers.
|
// method wrappers.
|
||||||
if Ctxt.DwFixups != nil {
|
if base.Ctxt.DwFixups != nil {
|
||||||
Ctxt.DwFixups.Finalize(Ctxt.Pkgpath, Debug.DwarfInl != 0)
|
base.Ctxt.DwFixups.Finalize(base.Ctxt.Pkgpath, base.Debug.DwarfInl != 0)
|
||||||
Ctxt.DwFixups = nil
|
base.Ctxt.DwFixups = nil
|
||||||
Flag.GenDwarfInl = 0
|
base.Flag.GenDwarfInl = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Phase 9: Check external declarations.
|
// Phase 9: Check external declarations.
|
||||||
|
|
@ -446,14 +447,14 @@ func Main(archInit func(*Arch)) {
|
||||||
// Check the map keys again, since we typechecked the external
|
// Check the map keys again, since we typechecked the external
|
||||||
// declarations.
|
// declarations.
|
||||||
checkMapKeys()
|
checkMapKeys()
|
||||||
ExitIfErrors()
|
base.ExitIfErrors()
|
||||||
|
|
||||||
// Write object data to disk.
|
// Write object data to disk.
|
||||||
timings.Start("be", "dumpobj")
|
timings.Start("be", "dumpobj")
|
||||||
dumpdata()
|
dumpdata()
|
||||||
Ctxt.NumberSyms()
|
base.Ctxt.NumberSyms()
|
||||||
dumpobj()
|
dumpobj()
|
||||||
if Flag.AsmHdr != "" {
|
if base.Flag.AsmHdr != "" {
|
||||||
dumpasmhdr()
|
dumpasmhdr()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -463,27 +464,27 @@ func Main(archInit func(*Arch)) {
|
||||||
})
|
})
|
||||||
for _, large := range largeStackFrames {
|
for _, large := range largeStackFrames {
|
||||||
if large.callee != 0 {
|
if large.callee != 0 {
|
||||||
yyerrorl(large.pos, "stack frame too large (>1GB): %d MB locals + %d MB args + %d MB callee", large.locals>>20, large.args>>20, large.callee>>20)
|
base.ErrorfAt(large.pos, "stack frame too large (>1GB): %d MB locals + %d MB args + %d MB callee", large.locals>>20, large.args>>20, large.callee>>20)
|
||||||
} else {
|
} else {
|
||||||
yyerrorl(large.pos, "stack frame too large (>1GB): %d MB locals + %d MB args", large.locals>>20, large.args>>20)
|
base.ErrorfAt(large.pos, "stack frame too large (>1GB): %d MB locals + %d MB args", large.locals>>20, large.args>>20)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(funcStack) != 0 {
|
if len(funcStack) != 0 {
|
||||||
Fatalf("funcStack is non-empty: %v", len(funcStack))
|
base.Fatalf("funcStack is non-empty: %v", len(funcStack))
|
||||||
}
|
}
|
||||||
if len(compilequeue) != 0 {
|
if len(compilequeue) != 0 {
|
||||||
Fatalf("%d uncompiled functions", len(compilequeue))
|
base.Fatalf("%d uncompiled functions", len(compilequeue))
|
||||||
}
|
}
|
||||||
|
|
||||||
logopt.FlushLoggedOpts(Ctxt, Ctxt.Pkgpath)
|
logopt.FlushLoggedOpts(base.Ctxt, base.Ctxt.Pkgpath)
|
||||||
ExitIfErrors()
|
base.ExitIfErrors()
|
||||||
|
|
||||||
flusherrors()
|
base.FlushErrors()
|
||||||
timings.Stop()
|
timings.Stop()
|
||||||
|
|
||||||
if Flag.Bench != "" {
|
if base.Flag.Bench != "" {
|
||||||
if err := writebench(Flag.Bench); err != nil {
|
if err := writebench(base.Flag.Bench); err != nil {
|
||||||
log.Fatalf("cannot write benchmark data: %v", err)
|
log.Fatalf("cannot write benchmark data: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -510,7 +511,7 @@ func writebench(filename string) error {
|
||||||
fmt.Fprintln(&buf, "commit:", objabi.Version)
|
fmt.Fprintln(&buf, "commit:", objabi.Version)
|
||||||
fmt.Fprintln(&buf, "goos:", runtime.GOOS)
|
fmt.Fprintln(&buf, "goos:", runtime.GOOS)
|
||||||
fmt.Fprintln(&buf, "goarch:", runtime.GOARCH)
|
fmt.Fprintln(&buf, "goarch:", runtime.GOARCH)
|
||||||
timings.Write(&buf, "BenchmarkCompile:"+Ctxt.Pkgpath+":")
|
timings.Write(&buf, "BenchmarkCompile:"+base.Ctxt.Pkgpath+":")
|
||||||
|
|
||||||
n, err := f.Write(buf.Bytes())
|
n, err := f.Write(buf.Bytes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -622,12 +623,12 @@ func islocalname(name string) bool {
|
||||||
|
|
||||||
func findpkg(name string) (file string, ok bool) {
|
func findpkg(name string) (file string, ok bool) {
|
||||||
if islocalname(name) {
|
if islocalname(name) {
|
||||||
if Flag.NoLocalImports {
|
if base.Flag.NoLocalImports {
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
if Flag.Cfg.PackageFile != nil {
|
if base.Flag.Cfg.PackageFile != nil {
|
||||||
file, ok = Flag.Cfg.PackageFile[name]
|
file, ok = base.Flag.Cfg.PackageFile[name]
|
||||||
return file, ok
|
return file, ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -649,16 +650,16 @@ func findpkg(name string) (file string, ok bool) {
|
||||||
// don't want to see "encoding/../encoding/base64"
|
// don't want to see "encoding/../encoding/base64"
|
||||||
// as different from "encoding/base64".
|
// as different from "encoding/base64".
|
||||||
if q := path.Clean(name); q != name {
|
if q := path.Clean(name); q != name {
|
||||||
yyerror("non-canonical import path %q (should be %q)", name, q)
|
base.Errorf("non-canonical import path %q (should be %q)", name, q)
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
if Flag.Cfg.PackageFile != nil {
|
if base.Flag.Cfg.PackageFile != nil {
|
||||||
file, ok = Flag.Cfg.PackageFile[name]
|
file, ok = base.Flag.Cfg.PackageFile[name]
|
||||||
return file, ok
|
return file, ok
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, dir := range Flag.Cfg.ImportDirs {
|
for _, dir := range base.Flag.Cfg.ImportDirs {
|
||||||
file = fmt.Sprintf("%s/%s.a", dir, name)
|
file = fmt.Sprintf("%s/%s.a", dir, name)
|
||||||
if _, err := os.Stat(file); err == nil {
|
if _, err := os.Stat(file); err == nil {
|
||||||
return file, true
|
return file, true
|
||||||
|
|
@ -672,13 +673,13 @@ func findpkg(name string) (file string, ok bool) {
|
||||||
if objabi.GOROOT != "" {
|
if objabi.GOROOT != "" {
|
||||||
suffix := ""
|
suffix := ""
|
||||||
suffixsep := ""
|
suffixsep := ""
|
||||||
if Flag.InstallSuffix != "" {
|
if base.Flag.InstallSuffix != "" {
|
||||||
suffixsep = "_"
|
suffixsep = "_"
|
||||||
suffix = Flag.InstallSuffix
|
suffix = base.Flag.InstallSuffix
|
||||||
} else if Flag.Race {
|
} else if base.Flag.Race {
|
||||||
suffixsep = "_"
|
suffixsep = "_"
|
||||||
suffix = "race"
|
suffix = "race"
|
||||||
} else if Flag.MSan {
|
} else if base.Flag.MSan {
|
||||||
suffixsep = "_"
|
suffixsep = "_"
|
||||||
suffix = "msan"
|
suffix = "msan"
|
||||||
}
|
}
|
||||||
|
|
@ -715,7 +716,7 @@ func loadsys() {
|
||||||
case varTag:
|
case varTag:
|
||||||
importvar(Runtimepkg, src.NoXPos, sym, typ)
|
importvar(Runtimepkg, src.NoXPos, sym, typ)
|
||||||
default:
|
default:
|
||||||
Fatalf("unhandled declaration tag %v", d.tag)
|
base.Fatalf("unhandled declaration tag %v", d.tag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -729,13 +730,13 @@ var myheight int
|
||||||
|
|
||||||
func importfile(f constant.Value) *types.Pkg {
|
func importfile(f constant.Value) *types.Pkg {
|
||||||
if f.Kind() != constant.String {
|
if f.Kind() != constant.String {
|
||||||
yyerror("import path must be a string")
|
base.Errorf("import path must be a string")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
path_ := constant.StringVal(f)
|
path_ := constant.StringVal(f)
|
||||||
if len(path_) == 0 {
|
if len(path_) == 0 {
|
||||||
yyerror("import path is empty")
|
base.Errorf("import path is empty")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -748,16 +749,16 @@ func importfile(f constant.Value) *types.Pkg {
|
||||||
// the main package, just as we reserve the import
|
// the main package, just as we reserve the import
|
||||||
// path "math" to identify the standard math package.
|
// path "math" to identify the standard math package.
|
||||||
if path_ == "main" {
|
if path_ == "main" {
|
||||||
yyerror("cannot import \"main\"")
|
base.Errorf("cannot import \"main\"")
|
||||||
errorexit()
|
base.ErrorExit()
|
||||||
}
|
}
|
||||||
|
|
||||||
if Ctxt.Pkgpath != "" && path_ == Ctxt.Pkgpath {
|
if base.Ctxt.Pkgpath != "" && path_ == base.Ctxt.Pkgpath {
|
||||||
yyerror("import %q while compiling that package (import cycle)", path_)
|
base.Errorf("import %q while compiling that package (import cycle)", path_)
|
||||||
errorexit()
|
base.ErrorExit()
|
||||||
}
|
}
|
||||||
|
|
||||||
if mapped, ok := Flag.Cfg.ImportMap[path_]; ok {
|
if mapped, ok := base.Flag.Cfg.ImportMap[path_]; ok {
|
||||||
path_ = mapped
|
path_ = mapped
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -767,13 +768,13 @@ func importfile(f constant.Value) *types.Pkg {
|
||||||
|
|
||||||
if islocalname(path_) {
|
if islocalname(path_) {
|
||||||
if path_[0] == '/' {
|
if path_[0] == '/' {
|
||||||
yyerror("import path cannot be absolute path")
|
base.Errorf("import path cannot be absolute path")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
prefix := Ctxt.Pathname
|
prefix := base.Ctxt.Pathname
|
||||||
if Flag.D != "" {
|
if base.Flag.D != "" {
|
||||||
prefix = Flag.D
|
prefix = base.Flag.D
|
||||||
}
|
}
|
||||||
path_ = path.Join(prefix, path_)
|
path_ = path.Join(prefix, path_)
|
||||||
|
|
||||||
|
|
@ -784,8 +785,8 @@ func importfile(f constant.Value) *types.Pkg {
|
||||||
|
|
||||||
file, found := findpkg(path_)
|
file, found := findpkg(path_)
|
||||||
if !found {
|
if !found {
|
||||||
yyerror("can't find import: %q", path_)
|
base.Errorf("can't find import: %q", path_)
|
||||||
errorexit()
|
base.ErrorExit()
|
||||||
}
|
}
|
||||||
|
|
||||||
importpkg := types.NewPkg(path_, "")
|
importpkg := types.NewPkg(path_, "")
|
||||||
|
|
@ -797,48 +798,48 @@ func importfile(f constant.Value) *types.Pkg {
|
||||||
|
|
||||||
imp, err := bio.Open(file)
|
imp, err := bio.Open(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
yyerror("can't open import: %q: %v", path_, err)
|
base.Errorf("can't open import: %q: %v", path_, err)
|
||||||
errorexit()
|
base.ErrorExit()
|
||||||
}
|
}
|
||||||
defer imp.Close()
|
defer imp.Close()
|
||||||
|
|
||||||
// check object header
|
// check object header
|
||||||
p, err := imp.ReadString('\n')
|
p, err := imp.ReadString('\n')
|
||||||
if err != nil {
|
if err != nil {
|
||||||
yyerror("import %s: reading input: %v", file, err)
|
base.Errorf("import %s: reading input: %v", file, err)
|
||||||
errorexit()
|
base.ErrorExit()
|
||||||
}
|
}
|
||||||
|
|
||||||
if p == "!<arch>\n" { // package archive
|
if p == "!<arch>\n" { // package archive
|
||||||
// package export block should be first
|
// package export block should be first
|
||||||
sz := arsize(imp.Reader, "__.PKGDEF")
|
sz := arsize(imp.Reader, "__.PKGDEF")
|
||||||
if sz <= 0 {
|
if sz <= 0 {
|
||||||
yyerror("import %s: not a package file", file)
|
base.Errorf("import %s: not a package file", file)
|
||||||
errorexit()
|
base.ErrorExit()
|
||||||
}
|
}
|
||||||
p, err = imp.ReadString('\n')
|
p, err = imp.ReadString('\n')
|
||||||
if err != nil {
|
if err != nil {
|
||||||
yyerror("import %s: reading input: %v", file, err)
|
base.Errorf("import %s: reading input: %v", file, err)
|
||||||
errorexit()
|
base.ErrorExit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !strings.HasPrefix(p, "go object ") {
|
if !strings.HasPrefix(p, "go object ") {
|
||||||
yyerror("import %s: not a go object file: %s", file, p)
|
base.Errorf("import %s: not a go object file: %s", file, p)
|
||||||
errorexit()
|
base.ErrorExit()
|
||||||
}
|
}
|
||||||
q := fmt.Sprintf("%s %s %s %s\n", objabi.GOOS, objabi.GOARCH, objabi.Version, objabi.Expstring())
|
q := fmt.Sprintf("%s %s %s %s\n", objabi.GOOS, objabi.GOARCH, objabi.Version, objabi.Expstring())
|
||||||
if p[10:] != q {
|
if p[10:] != q {
|
||||||
yyerror("import %s: object is [%s] expected [%s]", file, p[10:], q)
|
base.Errorf("import %s: object is [%s] expected [%s]", file, p[10:], q)
|
||||||
errorexit()
|
base.ErrorExit()
|
||||||
}
|
}
|
||||||
|
|
||||||
// process header lines
|
// process header lines
|
||||||
for {
|
for {
|
||||||
p, err = imp.ReadString('\n')
|
p, err = imp.ReadString('\n')
|
||||||
if err != nil {
|
if err != nil {
|
||||||
yyerror("import %s: reading input: %v", file, err)
|
base.Errorf("import %s: reading input: %v", file, err)
|
||||||
errorexit()
|
base.ErrorExit()
|
||||||
}
|
}
|
||||||
if p == "\n" {
|
if p == "\n" {
|
||||||
break // header ends with blank line
|
break // header ends with blank line
|
||||||
|
|
@ -870,41 +871,41 @@ func importfile(f constant.Value) *types.Pkg {
|
||||||
var fingerprint goobj.FingerprintType
|
var fingerprint goobj.FingerprintType
|
||||||
switch c {
|
switch c {
|
||||||
case '\n':
|
case '\n':
|
||||||
yyerror("cannot import %s: old export format no longer supported (recompile library)", path_)
|
base.Errorf("cannot import %s: old export format no longer supported (recompile library)", path_)
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
case 'B':
|
case 'B':
|
||||||
if Debug.Export != 0 {
|
if base.Debug.Export != 0 {
|
||||||
fmt.Printf("importing %s (%s)\n", path_, file)
|
fmt.Printf("importing %s (%s)\n", path_, file)
|
||||||
}
|
}
|
||||||
imp.ReadByte() // skip \n after $$B
|
imp.ReadByte() // skip \n after $$B
|
||||||
|
|
||||||
c, err = imp.ReadByte()
|
c, err = imp.ReadByte()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
yyerror("import %s: reading input: %v", file, err)
|
base.Errorf("import %s: reading input: %v", file, err)
|
||||||
errorexit()
|
base.ErrorExit()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Indexed format is distinguished by an 'i' byte,
|
// Indexed format is distinguished by an 'i' byte,
|
||||||
// whereas previous export formats started with 'c', 'd', or 'v'.
|
// whereas previous export formats started with 'c', 'd', or 'v'.
|
||||||
if c != 'i' {
|
if c != 'i' {
|
||||||
yyerror("import %s: unexpected package format byte: %v", file, c)
|
base.Errorf("import %s: unexpected package format byte: %v", file, c)
|
||||||
errorexit()
|
base.ErrorExit()
|
||||||
}
|
}
|
||||||
fingerprint = iimport(importpkg, imp)
|
fingerprint = iimport(importpkg, imp)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
yyerror("no import in %q", path_)
|
base.Errorf("no import in %q", path_)
|
||||||
errorexit()
|
base.ErrorExit()
|
||||||
}
|
}
|
||||||
|
|
||||||
// assume files move (get installed) so don't record the full path
|
// assume files move (get installed) so don't record the full path
|
||||||
if Flag.Cfg.PackageFile != nil {
|
if base.Flag.Cfg.PackageFile != nil {
|
||||||
// If using a packageFile map, assume path_ can be recorded directly.
|
// If using a packageFile map, assume path_ can be recorded directly.
|
||||||
Ctxt.AddImport(path_, fingerprint)
|
base.Ctxt.AddImport(path_, fingerprint)
|
||||||
} else {
|
} else {
|
||||||
// For file "/Users/foo/go/pkg/darwin_amd64/math.a" record "math.a".
|
// For file "/Users/foo/go/pkg/darwin_amd64/math.a" record "math.a".
|
||||||
Ctxt.AddImport(file[len(file)-len(path_)-len(".a"):], fingerprint)
|
base.Ctxt.AddImport(file[len(file)-len(path_)-len(".a"):], fingerprint)
|
||||||
}
|
}
|
||||||
|
|
||||||
if importpkg.Height >= myheight {
|
if importpkg.Height >= myheight {
|
||||||
|
|
@ -926,21 +927,21 @@ func pkgnotused(lineno src.XPos, path string, name string) {
|
||||||
elem = elem[i+1:]
|
elem = elem[i+1:]
|
||||||
}
|
}
|
||||||
if name == "" || elem == name {
|
if name == "" || elem == name {
|
||||||
yyerrorl(lineno, "imported and not used: %q", path)
|
base.ErrorfAt(lineno, "imported and not used: %q", path)
|
||||||
} else {
|
} else {
|
||||||
yyerrorl(lineno, "imported and not used: %q as %s", path, name)
|
base.ErrorfAt(lineno, "imported and not used: %q as %s", path, name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func mkpackage(pkgname string) {
|
func mkpackage(pkgname string) {
|
||||||
if localpkg.Name == "" {
|
if localpkg.Name == "" {
|
||||||
if pkgname == "_" {
|
if pkgname == "_" {
|
||||||
yyerror("invalid package name _")
|
base.Errorf("invalid package name _")
|
||||||
}
|
}
|
||||||
localpkg.Name = pkgname
|
localpkg.Name = pkgname
|
||||||
} else {
|
} else {
|
||||||
if pkgname != localpkg.Name {
|
if pkgname != localpkg.Name {
|
||||||
yyerror("package %s; expected %s", pkgname, localpkg.Name)
|
base.Errorf("package %s; expected %s", pkgname, localpkg.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -964,7 +965,7 @@ func clearImports() {
|
||||||
// leave s->block set to cause redeclaration
|
// leave s->block set to cause redeclaration
|
||||||
// errors if a conflicting top-level name is
|
// errors if a conflicting top-level name is
|
||||||
// introduced by a different file.
|
// introduced by a different file.
|
||||||
if !n.Name.Used() && SyntaxErrors() == 0 {
|
if !n.Name.Used() && base.SyntaxErrors() == 0 {
|
||||||
unused = append(unused, importedPkg{n.Pos, n.Name.Pkg.Path, s.Name})
|
unused = append(unused, importedPkg{n.Pos, n.Name.Pkg.Path, s.Name})
|
||||||
}
|
}
|
||||||
s.Def = nil
|
s.Def = nil
|
||||||
|
|
@ -973,7 +974,7 @@ func clearImports() {
|
||||||
if IsAlias(s) {
|
if IsAlias(s) {
|
||||||
// throw away top-level name left over
|
// throw away top-level name left over
|
||||||
// from previous import . "x"
|
// from previous import . "x"
|
||||||
if n.Name != nil && n.Name.Pack != nil && !n.Name.Pack.Name.Used() && SyntaxErrors() == 0 {
|
if n.Name != nil && n.Name.Pack != nil && !n.Name.Pack.Name.Used() && base.SyntaxErrors() == 0 {
|
||||||
unused = append(unused, importedPkg{n.Name.Pack.Pos, n.Name.Pack.Name.Pkg.Path, ""})
|
unused = append(unused, importedPkg{n.Name.Pack.Pos, n.Name.Pack.Name.Pkg.Path, ""})
|
||||||
n.Name.Pack.Name.SetUsed(true)
|
n.Name.Pack.Name.SetUsed(true)
|
||||||
}
|
}
|
||||||
|
|
@ -995,7 +996,7 @@ func IsAlias(sym *types.Sym) bool {
|
||||||
// recordFlags records the specified command-line flags to be placed
|
// recordFlags records the specified command-line flags to be placed
|
||||||
// in the DWARF info.
|
// in the DWARF info.
|
||||||
func recordFlags(flags ...string) {
|
func recordFlags(flags ...string) {
|
||||||
if Ctxt.Pkgpath == "" {
|
if base.Ctxt.Pkgpath == "" {
|
||||||
// We can't record the flags if we don't know what the
|
// We can't record the flags if we don't know what the
|
||||||
// package name is.
|
// package name is.
|
||||||
return
|
return
|
||||||
|
|
@ -1038,24 +1039,24 @@ func recordFlags(flags ...string) {
|
||||||
if cmd.Len() == 0 {
|
if cmd.Len() == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s := Ctxt.Lookup(dwarf.CUInfoPrefix + "producer." + Ctxt.Pkgpath)
|
s := base.Ctxt.Lookup(dwarf.CUInfoPrefix + "producer." + base.Ctxt.Pkgpath)
|
||||||
s.Type = objabi.SDWARFCUINFO
|
s.Type = objabi.SDWARFCUINFO
|
||||||
// Sometimes (for example when building tests) we can link
|
// Sometimes (for example when building tests) we can link
|
||||||
// together two package main archives. So allow dups.
|
// together two package main archives. So allow dups.
|
||||||
s.Set(obj.AttrDuplicateOK, true)
|
s.Set(obj.AttrDuplicateOK, true)
|
||||||
Ctxt.Data = append(Ctxt.Data, s)
|
base.Ctxt.Data = append(base.Ctxt.Data, s)
|
||||||
s.P = cmd.Bytes()[1:]
|
s.P = cmd.Bytes()[1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
// recordPackageName records the name of the package being
|
// recordPackageName records the name of the package being
|
||||||
// compiled, so that the linker can save it in the compile unit's DIE.
|
// compiled, so that the linker can save it in the compile unit's DIE.
|
||||||
func recordPackageName() {
|
func recordPackageName() {
|
||||||
s := Ctxt.Lookup(dwarf.CUInfoPrefix + "packagename." + Ctxt.Pkgpath)
|
s := base.Ctxt.Lookup(dwarf.CUInfoPrefix + "packagename." + base.Ctxt.Pkgpath)
|
||||||
s.Type = objabi.SDWARFCUINFO
|
s.Type = objabi.SDWARFCUINFO
|
||||||
// Sometimes (for example when building tests) we can link
|
// Sometimes (for example when building tests) we can link
|
||||||
// together two package main archives. So allow dups.
|
// together two package main archives. So allow dups.
|
||||||
s.Set(obj.AttrDuplicateOK, true)
|
s.Set(obj.AttrDuplicateOK, true)
|
||||||
Ctxt.Data = append(Ctxt.Data, s)
|
base.Ctxt.Data = append(base.Ctxt.Data, s)
|
||||||
s.P = []byte(localpkg.Name)
|
s.P = []byte(localpkg.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1099,23 +1100,23 @@ func langSupported(major, minor int, pkg *types.Pkg) bool {
|
||||||
// checkLang verifies that the -lang flag holds a valid value, and
|
// checkLang verifies that the -lang flag holds a valid value, and
|
||||||
// exits if not. It initializes data used by langSupported.
|
// exits if not. It initializes data used by langSupported.
|
||||||
func checkLang() {
|
func checkLang() {
|
||||||
if Flag.Lang == "" {
|
if base.Flag.Lang == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
langWant, err = parseLang(Flag.Lang)
|
langWant, err = parseLang(base.Flag.Lang)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("invalid value %q for -lang: %v", Flag.Lang, err)
|
log.Fatalf("invalid value %q for -lang: %v", base.Flag.Lang, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if def := currentLang(); Flag.Lang != def {
|
if def := currentLang(); base.Flag.Lang != def {
|
||||||
defVers, err := parseLang(def)
|
defVers, err := parseLang(def)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("internal error parsing default lang %q: %v", def, err)
|
log.Fatalf("internal error parsing default lang %q: %v", def, err)
|
||||||
}
|
}
|
||||||
if langWant.major > defVers.major || (langWant.major == defVers.major && langWant.minor > defVers.minor) {
|
if langWant.major > defVers.major || (langWant.major == defVers.major && langWant.minor > defVers.minor) {
|
||||||
log.Fatalf("invalid value %q for -lang: max known version is %q", Flag.Lang, def)
|
log.Fatalf("invalid value %q for -lang: max known version is %q", base.Flag.Lang, def)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ import (
|
||||||
"unicode"
|
"unicode"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/syntax"
|
"cmd/compile/internal/syntax"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
|
|
@ -59,15 +60,15 @@ func parseFiles(filenames []string) uint {
|
||||||
var lines uint
|
var lines uint
|
||||||
for _, p := range noders {
|
for _, p := range noders {
|
||||||
for e := range p.err {
|
for e := range p.err {
|
||||||
p.yyerrorpos(e.Pos, "%s", e.Msg)
|
p.errorAt(e.Pos, "%s", e.Msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.node()
|
p.node()
|
||||||
lines += p.file.Lines
|
lines += p.file.Lines
|
||||||
p.file = nil // release memory
|
p.file = nil // release memory
|
||||||
|
|
||||||
if SyntaxErrors() != 0 {
|
if base.SyntaxErrors() != 0 {
|
||||||
errorexit()
|
base.ErrorExit()
|
||||||
}
|
}
|
||||||
// Always run testdclstack here, even when debug_dclstack is not set, as a sanity measure.
|
// Always run testdclstack here, even when debug_dclstack is not set, as a sanity measure.
|
||||||
testdclstack()
|
testdclstack()
|
||||||
|
|
@ -111,20 +112,20 @@ func (p *noder) makeSrcPosBase(b0 *syntax.PosBase) *src.PosBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *noder) makeXPos(pos syntax.Pos) (_ src.XPos) {
|
func (p *noder) makeXPos(pos syntax.Pos) (_ src.XPos) {
|
||||||
return Ctxt.PosTable.XPos(src.MakePos(p.makeSrcPosBase(pos.Base()), pos.Line(), pos.Col()))
|
return base.Ctxt.PosTable.XPos(src.MakePos(p.makeSrcPosBase(pos.Base()), pos.Line(), pos.Col()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *noder) yyerrorpos(pos syntax.Pos, format string, args ...interface{}) {
|
func (p *noder) errorAt(pos syntax.Pos, format string, args ...interface{}) {
|
||||||
yyerrorl(p.makeXPos(pos), format, args...)
|
base.ErrorfAt(p.makeXPos(pos), format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(gri) Can we eliminate fileh in favor of absFilename?
|
// TODO(gri) Can we eliminate fileh in favor of absFilename?
|
||||||
func fileh(name string) string {
|
func fileh(name string) string {
|
||||||
return objabi.AbsFile("", name, Flag.TrimPath)
|
return objabi.AbsFile("", name, base.Flag.TrimPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func absFilename(name string) string {
|
func absFilename(name string) string {
|
||||||
return objabi.AbsFile(Ctxt.Pathname, name, Flag.TrimPath)
|
return objabi.AbsFile(base.Ctxt.Pathname, name, base.Flag.TrimPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// noder transforms package syntax's AST into a Node tree.
|
// noder transforms package syntax's AST into a Node tree.
|
||||||
|
|
@ -162,8 +163,8 @@ func (p *noder) funcBody(fn *Node, block *syntax.BlockStmt) {
|
||||||
}
|
}
|
||||||
fn.Nbody.Set(body)
|
fn.Nbody.Set(body)
|
||||||
|
|
||||||
lineno = p.makeXPos(block.Rbrace)
|
base.Pos = p.makeXPos(block.Rbrace)
|
||||||
fn.Func.Endlineno = lineno
|
fn.Func.Endlineno = base.Pos
|
||||||
}
|
}
|
||||||
|
|
||||||
funcbody()
|
funcbody()
|
||||||
|
|
@ -193,7 +194,7 @@ func (p *noder) closeScope(pos syntax.Pos) {
|
||||||
// no variables were declared in this scope, so we can retract it.
|
// no variables were declared in this scope, so we can retract it.
|
||||||
|
|
||||||
if int(p.scope) != len(Curfn.Func.Parents) {
|
if int(p.scope) != len(Curfn.Func.Parents) {
|
||||||
Fatalf("scope tracking inconsistency, no variables declared but scopes were not retracted")
|
base.Fatalf("scope tracking inconsistency, no variables declared but scopes were not retracted")
|
||||||
}
|
}
|
||||||
|
|
||||||
p.scope = Curfn.Func.Parents[p.scope-1]
|
p.scope = Curfn.Func.Parents[p.scope-1]
|
||||||
|
|
@ -258,7 +259,7 @@ func (p *noder) node() {
|
||||||
|
|
||||||
for _, n := range p.linknames {
|
for _, n := range p.linknames {
|
||||||
if !p.importedUnsafe {
|
if !p.importedUnsafe {
|
||||||
p.yyerrorpos(n.pos, "//go:linkname only allowed in Go files that import \"unsafe\"")
|
p.errorAt(n.pos, "//go:linkname only allowed in Go files that import \"unsafe\"")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
s := lookup(n.local)
|
s := lookup(n.local)
|
||||||
|
|
@ -267,10 +268,10 @@ func (p *noder) node() {
|
||||||
} else {
|
} else {
|
||||||
// Use the default object symbol name if the
|
// Use the default object symbol name if the
|
||||||
// user didn't provide one.
|
// user didn't provide one.
|
||||||
if Ctxt.Pkgpath == "" {
|
if base.Ctxt.Pkgpath == "" {
|
||||||
p.yyerrorpos(n.pos, "//go:linkname requires linkname argument or -p compiler flag")
|
p.errorAt(n.pos, "//go:linkname requires linkname argument or -p compiler flag")
|
||||||
} else {
|
} else {
|
||||||
s.Linkname = objabi.PathToPrefix(Ctxt.Pkgpath) + "." + n.local
|
s.Linkname = objabi.PathToPrefix(base.Ctxt.Pkgpath) + "." + n.local
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -288,7 +289,7 @@ func (p *noder) node() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pragcgobuf = append(pragcgobuf, p.pragcgobuf...)
|
pragcgobuf = append(pragcgobuf, p.pragcgobuf...)
|
||||||
lineno = src.NoXPos
|
base.Pos = src.NoXPos
|
||||||
clearImports()
|
clearImports()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -332,8 +333,8 @@ func (p *noder) importDecl(imp *syntax.ImportDecl) {
|
||||||
|
|
||||||
ipkg := importfile(p.basicLit(imp.Path))
|
ipkg := importfile(p.basicLit(imp.Path))
|
||||||
if ipkg == nil {
|
if ipkg == nil {
|
||||||
if Errors() == 0 {
|
if base.Errors() == 0 {
|
||||||
Fatalf("phase error in import")
|
base.Fatalf("phase error in import")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -363,7 +364,7 @@ func (p *noder) importDecl(imp *syntax.ImportDecl) {
|
||||||
importdot(ipkg, pack)
|
importdot(ipkg, pack)
|
||||||
return
|
return
|
||||||
case "init":
|
case "init":
|
||||||
yyerrorl(pack.Pos, "cannot import package as init - init must be a func")
|
base.ErrorfAt(pack.Pos, "cannot import package as init - init must be a func")
|
||||||
return
|
return
|
||||||
case "_":
|
case "_":
|
||||||
return
|
return
|
||||||
|
|
@ -393,7 +394,7 @@ func (p *noder) varDecl(decl *syntax.VarDecl) []*Node {
|
||||||
// so at that point it hasn't seen the imports.
|
// so at that point it hasn't seen the imports.
|
||||||
// We're left to check now, just before applying the //go:embed lines.
|
// We're left to check now, just before applying the //go:embed lines.
|
||||||
for _, e := range pragma.Embeds {
|
for _, e := range pragma.Embeds {
|
||||||
p.yyerrorpos(e.Pos, "//go:embed only allowed in Go files that import \"embed\"")
|
p.errorAt(e.Pos, "//go:embed only allowed in Go files that import \"embed\"")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
exprs = varEmbed(p, names, typ, exprs, pragma.Embeds)
|
exprs = varEmbed(p, names, typ, exprs, pragma.Embeds)
|
||||||
|
|
@ -437,7 +438,7 @@ func (p *noder) constDecl(decl *syntax.ConstDecl, cs *constState) []*Node {
|
||||||
cs.typ, cs.values = typ, values
|
cs.typ, cs.values = typ, values
|
||||||
} else {
|
} else {
|
||||||
if typ != nil {
|
if typ != nil {
|
||||||
yyerror("const declaration cannot have type without expression")
|
base.Errorf("const declaration cannot have type without expression")
|
||||||
}
|
}
|
||||||
typ, values = cs.typ, cs.values
|
typ, values = cs.typ, cs.values
|
||||||
}
|
}
|
||||||
|
|
@ -445,7 +446,7 @@ func (p *noder) constDecl(decl *syntax.ConstDecl, cs *constState) []*Node {
|
||||||
nn := make([]*Node, 0, len(names))
|
nn := make([]*Node, 0, len(names))
|
||||||
for i, n := range names {
|
for i, n := range names {
|
||||||
if i >= len(values) {
|
if i >= len(values) {
|
||||||
yyerror("missing value in const declaration")
|
base.Errorf("missing value in const declaration")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
v := values[i]
|
v := values[i]
|
||||||
|
|
@ -464,7 +465,7 @@ func (p *noder) constDecl(decl *syntax.ConstDecl, cs *constState) []*Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(values) > len(names) {
|
if len(values) > len(names) {
|
||||||
yyerror("extra expression in const declaration")
|
base.Errorf("extra expression in const declaration")
|
||||||
}
|
}
|
||||||
|
|
||||||
cs.iota++
|
cs.iota++
|
||||||
|
|
@ -493,7 +494,7 @@ func (p *noder) typeDecl(decl *syntax.TypeDecl) *Node {
|
||||||
|
|
||||||
nod := p.nod(decl, ODCLTYPE, n, nil)
|
nod := p.nod(decl, ODCLTYPE, n, nil)
|
||||||
if param.Alias() && !langSupported(1, 9, localpkg) {
|
if param.Alias() && !langSupported(1, 9, localpkg) {
|
||||||
yyerrorl(nod.Pos, "type aliases only supported as of -lang=go1.9")
|
base.ErrorfAt(nod.Pos, "type aliases only supported as of -lang=go1.9")
|
||||||
}
|
}
|
||||||
return nod
|
return nod
|
||||||
}
|
}
|
||||||
|
|
@ -521,13 +522,13 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) *Node {
|
||||||
if name.Name == "init" {
|
if name.Name == "init" {
|
||||||
name = renameinit()
|
name = renameinit()
|
||||||
if t.List.Len() > 0 || t.Rlist.Len() > 0 {
|
if t.List.Len() > 0 || t.Rlist.Len() > 0 {
|
||||||
yyerrorl(f.Pos, "func init must have no arguments and no return values")
|
base.ErrorfAt(f.Pos, "func init must have no arguments and no return values")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if localpkg.Name == "main" && name.Name == "main" {
|
if localpkg.Name == "main" && name.Name == "main" {
|
||||||
if t.List.Len() > 0 || t.Rlist.Len() > 0 {
|
if t.List.Len() > 0 || t.Rlist.Len() > 0 {
|
||||||
yyerrorl(f.Pos, "func main must have no arguments and no return values")
|
base.ErrorfAt(f.Pos, "func main must have no arguments and no return values")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -542,7 +543,7 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) *Node {
|
||||||
if pragma, ok := fun.Pragma.(*Pragma); ok {
|
if pragma, ok := fun.Pragma.(*Pragma); ok {
|
||||||
f.Func.Pragma = pragma.Flag & FuncPragmas
|
f.Func.Pragma = pragma.Flag & FuncPragmas
|
||||||
if pragma.Flag&Systemstack != 0 && pragma.Flag&Nosplit != 0 {
|
if pragma.Flag&Systemstack != 0 && pragma.Flag&Nosplit != 0 {
|
||||||
yyerrorl(f.Pos, "go:nosplit and go:systemstack cannot be combined")
|
base.ErrorfAt(f.Pos, "go:nosplit and go:systemstack cannot be combined")
|
||||||
}
|
}
|
||||||
pragma.Flag &^= FuncPragmas
|
pragma.Flag &^= FuncPragmas
|
||||||
p.checkUnused(pragma)
|
p.checkUnused(pragma)
|
||||||
|
|
@ -556,10 +557,10 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) *Node {
|
||||||
|
|
||||||
if fun.Body != nil {
|
if fun.Body != nil {
|
||||||
if f.Func.Pragma&Noescape != 0 {
|
if f.Func.Pragma&Noescape != 0 {
|
||||||
yyerrorl(f.Pos, "can only use //go:noescape with external func implementations")
|
base.ErrorfAt(f.Pos, "can only use //go:noescape with external func implementations")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if Flag.Complete || strings.HasPrefix(f.funcname(), "init.") {
|
if base.Flag.Complete || strings.HasPrefix(f.funcname(), "init.") {
|
||||||
// Linknamed functions are allowed to have no body. Hopefully
|
// Linknamed functions are allowed to have no body. Hopefully
|
||||||
// the linkname target has a body. See issue 23311.
|
// the linkname target has a body. See issue 23311.
|
||||||
isLinknamed := false
|
isLinknamed := false
|
||||||
|
|
@ -570,7 +571,7 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) *Node {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !isLinknamed {
|
if !isLinknamed {
|
||||||
yyerrorl(f.Pos, "missing function body")
|
base.ErrorfAt(f.Pos, "missing function body")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -610,13 +611,13 @@ func (p *noder) param(param *syntax.Field, dddOk, final bool) *Node {
|
||||||
if typ.Op == ODDD {
|
if typ.Op == ODDD {
|
||||||
if !dddOk {
|
if !dddOk {
|
||||||
// We mark these as syntax errors to get automatic elimination
|
// We mark these as syntax errors to get automatic elimination
|
||||||
// of multiple such errors per line (see yyerrorl in subr.go).
|
// of multiple such errors per line (see ErrorfAt in subr.go).
|
||||||
yyerror("syntax error: cannot use ... in receiver or result parameter list")
|
base.Errorf("syntax error: cannot use ... in receiver or result parameter list")
|
||||||
} else if !final {
|
} else if !final {
|
||||||
if param.Name == nil {
|
if param.Name == nil {
|
||||||
yyerror("syntax error: cannot use ... with non-final parameter")
|
base.Errorf("syntax error: cannot use ... with non-final parameter")
|
||||||
} else {
|
} else {
|
||||||
p.yyerrorpos(param.Name.Pos(), "syntax error: cannot use ... with non-final parameter %s", param.Name.Value)
|
p.errorAt(param.Name.Pos(), "syntax error: cannot use ... with non-final parameter %s", param.Name.Value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
typ.Op = OTARRAY
|
typ.Op = OTARRAY
|
||||||
|
|
@ -670,7 +671,7 @@ func (p *noder) expr(expr syntax.Expr) *Node {
|
||||||
l[i] = p.wrapname(expr.ElemList[i], e)
|
l[i] = p.wrapname(expr.ElemList[i], e)
|
||||||
}
|
}
|
||||||
n.List.Set(l)
|
n.List.Set(l)
|
||||||
lineno = p.makeXPos(expr.Rbrace)
|
base.Pos = p.makeXPos(expr.Rbrace)
|
||||||
return n
|
return n
|
||||||
case *syntax.KeyValueExpr:
|
case *syntax.KeyValueExpr:
|
||||||
// use position of expr.Key rather than of expr (which has position of ':')
|
// use position of expr.Key rather than of expr (which has position of ':')
|
||||||
|
|
@ -752,7 +753,7 @@ func (p *noder) expr(expr syntax.Expr) *Node {
|
||||||
if expr.Lhs != nil {
|
if expr.Lhs != nil {
|
||||||
n.Left = p.declName(expr.Lhs)
|
n.Left = p.declName(expr.Lhs)
|
||||||
if n.Left.isBlank() {
|
if n.Left.isBlank() {
|
||||||
yyerror("invalid variable name %v in type switch", n.Left)
|
base.Errorf("invalid variable name %v in type switch", n.Left)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
|
|
@ -916,12 +917,12 @@ func (p *noder) packname(expr syntax.Expr) *types.Sym {
|
||||||
name := p.name(expr.X.(*syntax.Name))
|
name := p.name(expr.X.(*syntax.Name))
|
||||||
def := asNode(name.Def)
|
def := asNode(name.Def)
|
||||||
if def == nil {
|
if def == nil {
|
||||||
yyerror("undefined: %v", name)
|
base.Errorf("undefined: %v", name)
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
var pkg *types.Pkg
|
var pkg *types.Pkg
|
||||||
if def.Op != OPACK {
|
if def.Op != OPACK {
|
||||||
yyerror("%v is not a package", name)
|
base.Errorf("%v is not a package", name)
|
||||||
pkg = localpkg
|
pkg = localpkg
|
||||||
} else {
|
} else {
|
||||||
def.Name.SetUsed(true)
|
def.Name.SetUsed(true)
|
||||||
|
|
@ -1026,7 +1027,7 @@ func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) *Node {
|
||||||
op = OCONTINUE
|
op = OCONTINUE
|
||||||
case syntax.Fallthrough:
|
case syntax.Fallthrough:
|
||||||
if !fallOK {
|
if !fallOK {
|
||||||
yyerror("fallthrough statement out of place")
|
base.Errorf("fallthrough statement out of place")
|
||||||
}
|
}
|
||||||
op = OFALL
|
op = OFALL
|
||||||
case syntax.Goto:
|
case syntax.Goto:
|
||||||
|
|
@ -1066,7 +1067,7 @@ func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) *Node {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if asNode(ln.Sym.Def) != ln {
|
if asNode(ln.Sym.Def) != ln {
|
||||||
yyerror("%s is shadowed during return", ln.Sym.Name)
|
base.Errorf("%s is shadowed during return", ln.Sym.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1107,7 +1108,7 @@ func (p *noder) assignList(expr syntax.Expr, defn *Node, colas bool) []*Node {
|
||||||
|
|
||||||
name, ok := expr.(*syntax.Name)
|
name, ok := expr.(*syntax.Name)
|
||||||
if !ok {
|
if !ok {
|
||||||
p.yyerrorpos(expr.Pos(), "non-name %v on left side of :=", p.expr(expr))
|
p.errorAt(expr.Pos(), "non-name %v on left side of :=", p.expr(expr))
|
||||||
newOrErr = true
|
newOrErr = true
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -1118,7 +1119,7 @@ func (p *noder) assignList(expr syntax.Expr, defn *Node, colas bool) []*Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
if seen[sym] {
|
if seen[sym] {
|
||||||
p.yyerrorpos(expr.Pos(), "%v repeated on left side of :=", sym)
|
p.errorAt(expr.Pos(), "%v repeated on left side of :=", sym)
|
||||||
newOrErr = true
|
newOrErr = true
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -1138,7 +1139,7 @@ func (p *noder) assignList(expr syntax.Expr, defn *Node, colas bool) []*Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !newOrErr {
|
if !newOrErr {
|
||||||
yyerrorl(defn.Pos, "no new variables on left side of :=")
|
base.ErrorfAt(defn.Pos, "no new variables on left side of :=")
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
@ -1256,10 +1257,10 @@ func (p *noder) caseClauses(clauses []*syntax.CaseClause, tswitch *Node, rbrace
|
||||||
n.Nbody.Set(p.stmtsFall(body, true))
|
n.Nbody.Set(p.stmtsFall(body, true))
|
||||||
if l := n.Nbody.Len(); l > 0 && n.Nbody.Index(l-1).Op == OFALL {
|
if l := n.Nbody.Len(); l > 0 && n.Nbody.Index(l-1).Op == OFALL {
|
||||||
if tswitch != nil {
|
if tswitch != nil {
|
||||||
yyerror("cannot fallthrough in type switch")
|
base.Errorf("cannot fallthrough in type switch")
|
||||||
}
|
}
|
||||||
if i+1 == len(clauses) {
|
if i+1 == len(clauses) {
|
||||||
yyerror("cannot fallthrough final case in switch")
|
base.Errorf("cannot fallthrough final case in switch")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1378,7 +1379,7 @@ func checkLangCompat(lit *syntax.BasicLit) {
|
||||||
}
|
}
|
||||||
// len(s) > 2
|
// len(s) > 2
|
||||||
if strings.Contains(s, "_") {
|
if strings.Contains(s, "_") {
|
||||||
yyerrorv("go1.13", "underscores in numeric literals")
|
base.ErrorfVers("go1.13", "underscores in numeric literals")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if s[0] != '0' {
|
if s[0] != '0' {
|
||||||
|
|
@ -1386,15 +1387,15 @@ func checkLangCompat(lit *syntax.BasicLit) {
|
||||||
}
|
}
|
||||||
radix := s[1]
|
radix := s[1]
|
||||||
if radix == 'b' || radix == 'B' {
|
if radix == 'b' || radix == 'B' {
|
||||||
yyerrorv("go1.13", "binary literals")
|
base.ErrorfVers("go1.13", "binary literals")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if radix == 'o' || radix == 'O' {
|
if radix == 'o' || radix == 'O' {
|
||||||
yyerrorv("go1.13", "0o/0O-style octal literals")
|
base.ErrorfVers("go1.13", "0o/0O-style octal literals")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if lit.Kind != syntax.IntLit && (radix == 'x' || radix == 'X') {
|
if lit.Kind != syntax.IntLit && (radix == 'x' || radix == 'X') {
|
||||||
yyerrorv("go1.13", "hexadecimal floating-point literals")
|
base.ErrorfVers("go1.13", "hexadecimal floating-point literals")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1415,7 +1416,7 @@ func (p *noder) basicLit(lit *syntax.BasicLit) constant.Value {
|
||||||
v := constant.MakeFromLiteral(lit.Value, tokenForLitKind[lit.Kind], 0)
|
v := constant.MakeFromLiteral(lit.Value, tokenForLitKind[lit.Kind], 0)
|
||||||
if v.Kind() == constant.Unknown {
|
if v.Kind() == constant.Unknown {
|
||||||
// TODO(mdempsky): Better error message?
|
// TODO(mdempsky): Better error message?
|
||||||
p.yyerrorpos(lit.Pos(), "malformed constant: %s", lit.Value)
|
p.errorAt(lit.Pos(), "malformed constant: %s", lit.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// go/constant uses big.Rat by default, which is more precise, but
|
// go/constant uses big.Rat by default, which is more precise, but
|
||||||
|
|
@ -1474,7 +1475,7 @@ func (p *noder) nodSym(orig syntax.Node, op Op, left *Node, sym *types.Sym) *Nod
|
||||||
|
|
||||||
func (p *noder) pos(n syntax.Node) src.XPos {
|
func (p *noder) pos(n syntax.Node) src.XPos {
|
||||||
// TODO(gri): orig.Pos() should always be known - fix package syntax
|
// TODO(gri): orig.Pos() should always be known - fix package syntax
|
||||||
xpos := lineno
|
xpos := base.Pos
|
||||||
if pos := n.Pos(); pos.IsKnown() {
|
if pos := n.Pos(); pos.IsKnown() {
|
||||||
xpos = p.makeXPos(pos)
|
xpos = p.makeXPos(pos)
|
||||||
}
|
}
|
||||||
|
|
@ -1483,7 +1484,7 @@ func (p *noder) pos(n syntax.Node) src.XPos {
|
||||||
|
|
||||||
func (p *noder) setlineno(n syntax.Node) {
|
func (p *noder) setlineno(n syntax.Node) {
|
||||||
if n != nil {
|
if n != nil {
|
||||||
lineno = p.pos(n)
|
base.Pos = p.pos(n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1525,12 +1526,12 @@ type PragmaEmbed struct {
|
||||||
func (p *noder) checkUnused(pragma *Pragma) {
|
func (p *noder) checkUnused(pragma *Pragma) {
|
||||||
for _, pos := range pragma.Pos {
|
for _, pos := range pragma.Pos {
|
||||||
if pos.Flag&pragma.Flag != 0 {
|
if pos.Flag&pragma.Flag != 0 {
|
||||||
p.yyerrorpos(pos.Pos, "misplaced compiler directive")
|
p.errorAt(pos.Pos, "misplaced compiler directive")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(pragma.Embeds) > 0 {
|
if len(pragma.Embeds) > 0 {
|
||||||
for _, e := range pragma.Embeds {
|
for _, e := range pragma.Embeds {
|
||||||
p.yyerrorpos(e.Pos, "misplaced go:embed directive")
|
p.errorAt(e.Pos, "misplaced go:embed directive")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1619,7 +1620,7 @@ func (p *noder) pragma(pos syntax.Pos, blankLine bool, text string, old syntax.P
|
||||||
// For security, we disallow //go:cgo_* directives other
|
// For security, we disallow //go:cgo_* directives other
|
||||||
// than cgo_import_dynamic outside cgo-generated files.
|
// than cgo_import_dynamic outside cgo-generated files.
|
||||||
// Exception: they are allowed in the standard library, for runtime and syscall.
|
// Exception: they are allowed in the standard library, for runtime and syscall.
|
||||||
if !isCgoGeneratedFile(pos) && !Flag.Std {
|
if !isCgoGeneratedFile(pos) && !base.Flag.Std {
|
||||||
p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("//%s only allowed in cgo-generated code", text)})
|
p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("//%s only allowed in cgo-generated code", text)})
|
||||||
}
|
}
|
||||||
p.pragcgo(pos, text)
|
p.pragcgo(pos, text)
|
||||||
|
|
@ -1631,10 +1632,10 @@ func (p *noder) pragma(pos syntax.Pos, blankLine bool, text string, old syntax.P
|
||||||
}
|
}
|
||||||
flag := pragmaFlag(verb)
|
flag := pragmaFlag(verb)
|
||||||
const runtimePragmas = Systemstack | Nowritebarrier | Nowritebarrierrec | Yeswritebarrierrec
|
const runtimePragmas = Systemstack | Nowritebarrier | Nowritebarrierrec | Yeswritebarrierrec
|
||||||
if !Flag.CompilingRuntime && flag&runtimePragmas != 0 {
|
if !base.Flag.CompilingRuntime && flag&runtimePragmas != 0 {
|
||||||
p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("//%s only allowed in runtime", verb)})
|
p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("//%s only allowed in runtime", verb)})
|
||||||
}
|
}
|
||||||
if flag == 0 && !allowedStdPragmas[verb] && Flag.Std {
|
if flag == 0 && !allowedStdPragmas[verb] && base.Flag.Std {
|
||||||
p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("//%s is not allowed in the standard library", verb)})
|
p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("//%s is not allowed in the standard library", verb)})
|
||||||
}
|
}
|
||||||
pragma.Flag |= flag
|
pragma.Flag |= flag
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/bio"
|
"cmd/internal/bio"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
|
|
@ -47,20 +48,20 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
func dumpobj() {
|
func dumpobj() {
|
||||||
if Flag.LinkObj == "" {
|
if base.Flag.LinkObj == "" {
|
||||||
dumpobj1(Flag.LowerO, modeCompilerObj|modeLinkerObj)
|
dumpobj1(base.Flag.LowerO, modeCompilerObj|modeLinkerObj)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
dumpobj1(Flag.LowerO, modeCompilerObj)
|
dumpobj1(base.Flag.LowerO, modeCompilerObj)
|
||||||
dumpobj1(Flag.LinkObj, modeLinkerObj)
|
dumpobj1(base.Flag.LinkObj, modeLinkerObj)
|
||||||
}
|
}
|
||||||
|
|
||||||
func dumpobj1(outfile string, mode int) {
|
func dumpobj1(outfile string, mode int) {
|
||||||
bout, err := bio.Create(outfile)
|
bout, err := bio.Create(outfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
flusherrors()
|
base.FlushErrors()
|
||||||
fmt.Printf("can't create %s: %v\n", outfile, err)
|
fmt.Printf("can't create %s: %v\n", outfile, err)
|
||||||
errorexit()
|
base.ErrorExit()
|
||||||
}
|
}
|
||||||
defer bout.Close()
|
defer bout.Close()
|
||||||
bout.WriteString("!<arch>\n")
|
bout.WriteString("!<arch>\n")
|
||||||
|
|
@ -79,8 +80,8 @@ func dumpobj1(outfile string, mode int) {
|
||||||
|
|
||||||
func printObjHeader(bout *bio.Writer) {
|
func printObjHeader(bout *bio.Writer) {
|
||||||
fmt.Fprintf(bout, "go object %s %s %s %s\n", objabi.GOOS, objabi.GOARCH, objabi.Version, objabi.Expstring())
|
fmt.Fprintf(bout, "go object %s %s %s %s\n", objabi.GOOS, objabi.GOARCH, objabi.Version, objabi.Expstring())
|
||||||
if Flag.BuildID != "" {
|
if base.Flag.BuildID != "" {
|
||||||
fmt.Fprintf(bout, "build id %q\n", Flag.BuildID)
|
fmt.Fprintf(bout, "build id %q\n", base.Flag.BuildID)
|
||||||
}
|
}
|
||||||
if localpkg.Name == "main" {
|
if localpkg.Name == "main" {
|
||||||
fmt.Fprintf(bout, "main\n")
|
fmt.Fprintf(bout, "main\n")
|
||||||
|
|
@ -169,13 +170,13 @@ func dumpdata() {
|
||||||
addGCLocals()
|
addGCLocals()
|
||||||
|
|
||||||
if exportlistLen != len(exportlist) {
|
if exportlistLen != len(exportlist) {
|
||||||
Fatalf("exportlist changed after compile functions loop")
|
base.Fatalf("exportlist changed after compile functions loop")
|
||||||
}
|
}
|
||||||
if ptabsLen != len(ptabs) {
|
if ptabsLen != len(ptabs) {
|
||||||
Fatalf("ptabs changed after compile functions loop")
|
base.Fatalf("ptabs changed after compile functions loop")
|
||||||
}
|
}
|
||||||
if itabsLen != len(itabs) {
|
if itabsLen != len(itabs) {
|
||||||
Fatalf("itabs changed after compile functions loop")
|
base.Fatalf("itabs changed after compile functions loop")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -187,18 +188,18 @@ func dumpLinkerObj(bout *bio.Writer) {
|
||||||
fmt.Fprintf(bout, "\n$$\n\n$$\n\n")
|
fmt.Fprintf(bout, "\n$$\n\n$$\n\n")
|
||||||
fmt.Fprintf(bout, "\n$$ // cgo\n")
|
fmt.Fprintf(bout, "\n$$ // cgo\n")
|
||||||
if err := json.NewEncoder(bout).Encode(pragcgobuf); err != nil {
|
if err := json.NewEncoder(bout).Encode(pragcgobuf); err != nil {
|
||||||
Fatalf("serializing pragcgobuf: %v", err)
|
base.Fatalf("serializing pragcgobuf: %v", err)
|
||||||
}
|
}
|
||||||
fmt.Fprintf(bout, "\n$$\n\n")
|
fmt.Fprintf(bout, "\n$$\n\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintf(bout, "\n!\n")
|
fmt.Fprintf(bout, "\n!\n")
|
||||||
|
|
||||||
obj.WriteObjFile(Ctxt, bout)
|
obj.WriteObjFile(base.Ctxt, bout)
|
||||||
}
|
}
|
||||||
|
|
||||||
func addptabs() {
|
func addptabs() {
|
||||||
if !Ctxt.Flag_dynlink || localpkg.Name != "main" {
|
if !base.Ctxt.Flag_dynlink || localpkg.Name != "main" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, exportn := range exportlist {
|
for _, exportn := range exportlist {
|
||||||
|
|
@ -228,7 +229,7 @@ func addptabs() {
|
||||||
|
|
||||||
func dumpGlobal(n *Node) {
|
func dumpGlobal(n *Node) {
|
||||||
if n.Type == nil {
|
if n.Type == nil {
|
||||||
Fatalf("external %v nil type\n", n)
|
base.Fatalf("external %v nil type\n", n)
|
||||||
}
|
}
|
||||||
if n.Class() == PFUNC {
|
if n.Class() == PFUNC {
|
||||||
return
|
return
|
||||||
|
|
@ -261,7 +262,7 @@ func dumpGlobalConst(n *Node) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ctxt.DwarfIntConst(Ctxt.Pkgpath, n.Sym.Name, typesymname(t), int64Val(t, v))
|
base.Ctxt.DwarfIntConst(base.Ctxt.Pkgpath, n.Sym.Name, typesymname(t), int64Val(t, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
func dumpglobls() {
|
func dumpglobls() {
|
||||||
|
|
@ -293,7 +294,7 @@ func dumpglobls() {
|
||||||
// This is done during the sequential phase after compilation, since
|
// This is done during the sequential phase after compilation, since
|
||||||
// global symbols can't be declared during parallel compilation.
|
// global symbols can't be declared during parallel compilation.
|
||||||
func addGCLocals() {
|
func addGCLocals() {
|
||||||
for _, s := range Ctxt.Text {
|
for _, s := range base.Ctxt.Text {
|
||||||
fn := s.Func()
|
fn := s.Func()
|
||||||
if fn == nil {
|
if fn == nil {
|
||||||
continue
|
continue
|
||||||
|
|
@ -316,9 +317,9 @@ func addGCLocals() {
|
||||||
|
|
||||||
func duintxx(s *obj.LSym, off int, v uint64, wid int) int {
|
func duintxx(s *obj.LSym, off int, v uint64, wid int) int {
|
||||||
if off&(wid-1) != 0 {
|
if off&(wid-1) != 0 {
|
||||||
Fatalf("duintxxLSym: misaligned: v=%d wid=%d off=%d", v, wid, off)
|
base.Fatalf("duintxxLSym: misaligned: v=%d wid=%d off=%d", v, wid, off)
|
||||||
}
|
}
|
||||||
s.WriteInt(Ctxt, int64(off), wid, int64(v))
|
s.WriteInt(base.Ctxt, int64(off), wid, int64(v))
|
||||||
return off + wid
|
return off + wid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -369,7 +370,7 @@ func stringsym(pos src.XPos, s string) (data *obj.LSym) {
|
||||||
symname = strconv.Quote(s)
|
symname = strconv.Quote(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
symdata := Ctxt.Lookup(stringSymPrefix + symname)
|
symdata := base.Ctxt.Lookup(stringSymPrefix + symname)
|
||||||
if !symdata.OnList() {
|
if !symdata.OnList() {
|
||||||
off := dstringdata(symdata, 0, s, pos, "string")
|
off := dstringdata(symdata, 0, s, pos, "string")
|
||||||
ggloblsym(symdata, int32(off), obj.DUPOK|obj.RODATA|obj.LOCAL)
|
ggloblsym(symdata, int32(off), obj.DUPOK|obj.RODATA|obj.LOCAL)
|
||||||
|
|
@ -447,7 +448,7 @@ func fileStringSym(pos src.XPos, file string, readonly bool, hash []byte) (*obj.
|
||||||
var symdata *obj.LSym
|
var symdata *obj.LSym
|
||||||
if readonly {
|
if readonly {
|
||||||
symname := fmt.Sprintf(stringSymPattern, size, sum)
|
symname := fmt.Sprintf(stringSymPattern, size, sum)
|
||||||
symdata = Ctxt.Lookup(stringSymPrefix + symname)
|
symdata = base.Ctxt.Lookup(stringSymPrefix + symname)
|
||||||
if !symdata.OnList() {
|
if !symdata.OnList() {
|
||||||
info := symdata.NewFileInfo()
|
info := symdata.NewFileInfo()
|
||||||
info.Name = file
|
info.Name = file
|
||||||
|
|
@ -489,7 +490,7 @@ func slicedata(pos src.XPos, s string) *Node {
|
||||||
|
|
||||||
func slicebytes(nam *Node, s string) {
|
func slicebytes(nam *Node, s string) {
|
||||||
if nam.Op != ONAME {
|
if nam.Op != ONAME {
|
||||||
Fatalf("slicebytes %v", nam)
|
base.Fatalf("slicebytes %v", nam)
|
||||||
}
|
}
|
||||||
slicesym(nam, slicedata(nam.Pos, s), int64(len(s)))
|
slicesym(nam, slicedata(nam.Pos, s), int64(len(s)))
|
||||||
}
|
}
|
||||||
|
|
@ -499,29 +500,29 @@ func dstringdata(s *obj.LSym, off int, t string, pos src.XPos, what string) int
|
||||||
// causing a cryptic error message by the linker. Check for oversize objects here
|
// causing a cryptic error message by the linker. Check for oversize objects here
|
||||||
// and provide a useful error message instead.
|
// and provide a useful error message instead.
|
||||||
if int64(len(t)) > 2e9 {
|
if int64(len(t)) > 2e9 {
|
||||||
yyerrorl(pos, "%v with length %v is too big", what, len(t))
|
base.ErrorfAt(pos, "%v with length %v is too big", what, len(t))
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
s.WriteString(Ctxt, int64(off), len(t), t)
|
s.WriteString(base.Ctxt, int64(off), len(t), t)
|
||||||
return off + len(t)
|
return off + len(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func dsymptr(s *obj.LSym, off int, x *obj.LSym, xoff int) int {
|
func dsymptr(s *obj.LSym, off int, x *obj.LSym, xoff int) int {
|
||||||
off = int(Rnd(int64(off), int64(Widthptr)))
|
off = int(Rnd(int64(off), int64(Widthptr)))
|
||||||
s.WriteAddr(Ctxt, int64(off), Widthptr, x, int64(xoff))
|
s.WriteAddr(base.Ctxt, int64(off), Widthptr, x, int64(xoff))
|
||||||
off += Widthptr
|
off += Widthptr
|
||||||
return off
|
return off
|
||||||
}
|
}
|
||||||
|
|
||||||
func dsymptrOff(s *obj.LSym, off int, x *obj.LSym) int {
|
func dsymptrOff(s *obj.LSym, off int, x *obj.LSym) int {
|
||||||
s.WriteOff(Ctxt, int64(off), x, 0)
|
s.WriteOff(base.Ctxt, int64(off), x, 0)
|
||||||
off += 4
|
off += 4
|
||||||
return off
|
return off
|
||||||
}
|
}
|
||||||
|
|
||||||
func dsymptrWeakOff(s *obj.LSym, off int, x *obj.LSym) int {
|
func dsymptrWeakOff(s *obj.LSym, off int, x *obj.LSym) int {
|
||||||
s.WriteWeakOff(Ctxt, int64(off), x, 0)
|
s.WriteWeakOff(base.Ctxt, int64(off), x, 0)
|
||||||
off += 4
|
off += 4
|
||||||
return off
|
return off
|
||||||
}
|
}
|
||||||
|
|
@ -532,79 +533,79 @@ func slicesym(n, arr *Node, lencap int64) {
|
||||||
s := n.Sym.Linksym()
|
s := n.Sym.Linksym()
|
||||||
off := n.Xoffset
|
off := n.Xoffset
|
||||||
if arr.Op != ONAME {
|
if arr.Op != ONAME {
|
||||||
Fatalf("slicesym non-name arr %v", arr)
|
base.Fatalf("slicesym non-name arr %v", arr)
|
||||||
}
|
}
|
||||||
s.WriteAddr(Ctxt, off, Widthptr, arr.Sym.Linksym(), arr.Xoffset)
|
s.WriteAddr(base.Ctxt, off, Widthptr, arr.Sym.Linksym(), arr.Xoffset)
|
||||||
s.WriteInt(Ctxt, off+sliceLenOffset, Widthptr, lencap)
|
s.WriteInt(base.Ctxt, off+sliceLenOffset, Widthptr, lencap)
|
||||||
s.WriteInt(Ctxt, off+sliceCapOffset, Widthptr, lencap)
|
s.WriteInt(base.Ctxt, off+sliceCapOffset, Widthptr, lencap)
|
||||||
}
|
}
|
||||||
|
|
||||||
// addrsym writes the static address of a to n. a must be an ONAME.
|
// addrsym writes the static address of a to n. a must be an ONAME.
|
||||||
// Neither n nor a is modified.
|
// Neither n nor a is modified.
|
||||||
func addrsym(n, a *Node) {
|
func addrsym(n, a *Node) {
|
||||||
if n.Op != ONAME {
|
if n.Op != ONAME {
|
||||||
Fatalf("addrsym n op %v", n.Op)
|
base.Fatalf("addrsym n op %v", n.Op)
|
||||||
}
|
}
|
||||||
if n.Sym == nil {
|
if n.Sym == nil {
|
||||||
Fatalf("addrsym nil n sym")
|
base.Fatalf("addrsym nil n sym")
|
||||||
}
|
}
|
||||||
if a.Op != ONAME {
|
if a.Op != ONAME {
|
||||||
Fatalf("addrsym a op %v", a.Op)
|
base.Fatalf("addrsym a op %v", a.Op)
|
||||||
}
|
}
|
||||||
s := n.Sym.Linksym()
|
s := n.Sym.Linksym()
|
||||||
s.WriteAddr(Ctxt, n.Xoffset, Widthptr, a.Sym.Linksym(), a.Xoffset)
|
s.WriteAddr(base.Ctxt, n.Xoffset, Widthptr, a.Sym.Linksym(), a.Xoffset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// pfuncsym writes the static address of f to n. f must be a global function.
|
// pfuncsym writes the static address of f to n. f must be a global function.
|
||||||
// Neither n nor f is modified.
|
// Neither n nor f is modified.
|
||||||
func pfuncsym(n, f *Node) {
|
func pfuncsym(n, f *Node) {
|
||||||
if n.Op != ONAME {
|
if n.Op != ONAME {
|
||||||
Fatalf("pfuncsym n op %v", n.Op)
|
base.Fatalf("pfuncsym n op %v", n.Op)
|
||||||
}
|
}
|
||||||
if n.Sym == nil {
|
if n.Sym == nil {
|
||||||
Fatalf("pfuncsym nil n sym")
|
base.Fatalf("pfuncsym nil n sym")
|
||||||
}
|
}
|
||||||
if f.Class() != PFUNC {
|
if f.Class() != PFUNC {
|
||||||
Fatalf("pfuncsym class not PFUNC %d", f.Class())
|
base.Fatalf("pfuncsym class not PFUNC %d", f.Class())
|
||||||
}
|
}
|
||||||
s := n.Sym.Linksym()
|
s := n.Sym.Linksym()
|
||||||
s.WriteAddr(Ctxt, n.Xoffset, Widthptr, funcsym(f.Sym).Linksym(), f.Xoffset)
|
s.WriteAddr(base.Ctxt, n.Xoffset, Widthptr, funcsym(f.Sym).Linksym(), f.Xoffset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// litsym writes the static literal c to n.
|
// litsym writes the static literal c to n.
|
||||||
// Neither n nor c is modified.
|
// Neither n nor c is modified.
|
||||||
func litsym(n, c *Node, wid int) {
|
func litsym(n, c *Node, wid int) {
|
||||||
if n.Op != ONAME {
|
if n.Op != ONAME {
|
||||||
Fatalf("litsym n op %v", n.Op)
|
base.Fatalf("litsym n op %v", n.Op)
|
||||||
}
|
}
|
||||||
if n.Sym == nil {
|
if n.Sym == nil {
|
||||||
Fatalf("litsym nil n sym")
|
base.Fatalf("litsym nil n sym")
|
||||||
}
|
}
|
||||||
if !types.Identical(n.Type, c.Type) {
|
if !types.Identical(n.Type, c.Type) {
|
||||||
Fatalf("litsym: type mismatch: %v has type %v, but %v has type %v", n, n.Type, c, c.Type)
|
base.Fatalf("litsym: type mismatch: %v has type %v, but %v has type %v", n, n.Type, c, c.Type)
|
||||||
}
|
}
|
||||||
if c.Op == ONIL {
|
if c.Op == ONIL {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if c.Op != OLITERAL {
|
if c.Op != OLITERAL {
|
||||||
Fatalf("litsym c op %v", c.Op)
|
base.Fatalf("litsym c op %v", c.Op)
|
||||||
}
|
}
|
||||||
s := n.Sym.Linksym()
|
s := n.Sym.Linksym()
|
||||||
switch u := c.Val(); u.Kind() {
|
switch u := c.Val(); u.Kind() {
|
||||||
case constant.Bool:
|
case constant.Bool:
|
||||||
i := int64(obj.Bool2int(constant.BoolVal(u)))
|
i := int64(obj.Bool2int(constant.BoolVal(u)))
|
||||||
s.WriteInt(Ctxt, n.Xoffset, wid, i)
|
s.WriteInt(base.Ctxt, n.Xoffset, wid, i)
|
||||||
|
|
||||||
case constant.Int:
|
case constant.Int:
|
||||||
s.WriteInt(Ctxt, n.Xoffset, wid, int64Val(n.Type, u))
|
s.WriteInt(base.Ctxt, n.Xoffset, wid, int64Val(n.Type, u))
|
||||||
|
|
||||||
case constant.Float:
|
case constant.Float:
|
||||||
f, _ := constant.Float64Val(u)
|
f, _ := constant.Float64Val(u)
|
||||||
switch n.Type.Etype {
|
switch n.Type.Etype {
|
||||||
case TFLOAT32:
|
case TFLOAT32:
|
||||||
s.WriteFloat32(Ctxt, n.Xoffset, float32(f))
|
s.WriteFloat32(base.Ctxt, n.Xoffset, float32(f))
|
||||||
case TFLOAT64:
|
case TFLOAT64:
|
||||||
s.WriteFloat64(Ctxt, n.Xoffset, f)
|
s.WriteFloat64(base.Ctxt, n.Xoffset, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
case constant.Complex:
|
case constant.Complex:
|
||||||
|
|
@ -612,20 +613,20 @@ func litsym(n, c *Node, wid int) {
|
||||||
im, _ := constant.Float64Val(constant.Imag(u))
|
im, _ := constant.Float64Val(constant.Imag(u))
|
||||||
switch n.Type.Etype {
|
switch n.Type.Etype {
|
||||||
case TCOMPLEX64:
|
case TCOMPLEX64:
|
||||||
s.WriteFloat32(Ctxt, n.Xoffset, float32(re))
|
s.WriteFloat32(base.Ctxt, n.Xoffset, float32(re))
|
||||||
s.WriteFloat32(Ctxt, n.Xoffset+4, float32(im))
|
s.WriteFloat32(base.Ctxt, n.Xoffset+4, float32(im))
|
||||||
case TCOMPLEX128:
|
case TCOMPLEX128:
|
||||||
s.WriteFloat64(Ctxt, n.Xoffset, re)
|
s.WriteFloat64(base.Ctxt, n.Xoffset, re)
|
||||||
s.WriteFloat64(Ctxt, n.Xoffset+8, im)
|
s.WriteFloat64(base.Ctxt, n.Xoffset+8, im)
|
||||||
}
|
}
|
||||||
|
|
||||||
case constant.String:
|
case constant.String:
|
||||||
i := constant.StringVal(u)
|
i := constant.StringVal(u)
|
||||||
symdata := stringsym(n.Pos, i)
|
symdata := stringsym(n.Pos, i)
|
||||||
s.WriteAddr(Ctxt, n.Xoffset, Widthptr, symdata, 0)
|
s.WriteAddr(base.Ctxt, n.Xoffset, Widthptr, symdata, 0)
|
||||||
s.WriteInt(Ctxt, n.Xoffset+int64(Widthptr), Widthptr, int64(len(i)))
|
s.WriteInt(base.Ctxt, n.Xoffset+int64(Widthptr), Widthptr, int64(len(i)))
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Fatalf("litsym unhandled OLITERAL %v", c)
|
base.Fatalf("litsym unhandled OLITERAL %v", c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/src"
|
"cmd/internal/src"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
@ -50,7 +51,7 @@ type Order struct {
|
||||||
// Order rewrites fn.Nbody to apply the ordering constraints
|
// Order rewrites fn.Nbody to apply the ordering constraints
|
||||||
// described in the comment at the top of the file.
|
// described in the comment at the top of the file.
|
||||||
func order(fn *Node) {
|
func order(fn *Node) {
|
||||||
if Flag.W > 1 {
|
if base.Flag.W > 1 {
|
||||||
s := fmt.Sprintf("\nbefore order %v", fn.Func.Nname.Sym)
|
s := fmt.Sprintf("\nbefore order %v", fn.Func.Nname.Sym)
|
||||||
dumplist(s, fn.Nbody)
|
dumplist(s, fn.Nbody)
|
||||||
}
|
}
|
||||||
|
|
@ -181,7 +182,7 @@ func (o *Order) safeExpr(n *Node) *Node {
|
||||||
return typecheck(a, ctxExpr)
|
return typecheck(a, ctxExpr)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Fatalf("order.safeExpr %v", n.Op)
|
base.Fatalf("order.safeExpr %v", n.Op)
|
||||||
return nil // not reached
|
return nil // not reached
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -210,7 +211,7 @@ func (o *Order) addrTemp(n *Node) *Node {
|
||||||
var s InitSchedule
|
var s InitSchedule
|
||||||
s.staticassign(vstat, n)
|
s.staticassign(vstat, n)
|
||||||
if s.out != nil {
|
if s.out != nil {
|
||||||
Fatalf("staticassign of const generated code: %+v", n)
|
base.Fatalf("staticassign of const generated code: %+v", n)
|
||||||
}
|
}
|
||||||
vstat = typecheck(vstat, ctxExpr)
|
vstat = typecheck(vstat, ctxExpr)
|
||||||
return vstat
|
return vstat
|
||||||
|
|
@ -323,7 +324,7 @@ func (o *Order) stmtList(l Nodes) {
|
||||||
// and rewrites it to:
|
// and rewrites it to:
|
||||||
// m = OMAKESLICECOPY([]T, x, s); nil
|
// m = OMAKESLICECOPY([]T, x, s); nil
|
||||||
func orderMakeSliceCopy(s []*Node) {
|
func orderMakeSliceCopy(s []*Node) {
|
||||||
if Flag.N != 0 || instrumenting {
|
if base.Flag.N != 0 || instrumenting {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -384,7 +385,7 @@ func orderMakeSliceCopy(s []*Node) {
|
||||||
|
|
||||||
// edge inserts coverage instrumentation for libfuzzer.
|
// edge inserts coverage instrumentation for libfuzzer.
|
||||||
func (o *Order) edge() {
|
func (o *Order) edge() {
|
||||||
if Debug.Libfuzzer == 0 {
|
if base.Debug.Libfuzzer == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -450,7 +451,7 @@ func (o *Order) init(n *Node) {
|
||||||
// For concurrency safety, don't mutate potentially shared nodes.
|
// For concurrency safety, don't mutate potentially shared nodes.
|
||||||
// First, ensure that no work is required here.
|
// First, ensure that no work is required here.
|
||||||
if n.Ninit.Len() > 0 {
|
if n.Ninit.Len() > 0 {
|
||||||
Fatalf("order.init shared node with ninit")
|
base.Fatalf("order.init shared node with ninit")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -463,7 +464,7 @@ func (o *Order) init(n *Node) {
|
||||||
func (o *Order) call(n *Node) {
|
func (o *Order) call(n *Node) {
|
||||||
if n.Ninit.Len() > 0 {
|
if n.Ninit.Len() > 0 {
|
||||||
// Caller should have already called o.init(n).
|
// Caller should have already called o.init(n).
|
||||||
Fatalf("%v with unexpected ninit", n.Op)
|
base.Fatalf("%v with unexpected ninit", n.Op)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Builtin functions.
|
// Builtin functions.
|
||||||
|
|
@ -526,7 +527,7 @@ func (o *Order) call(n *Node) {
|
||||||
func (o *Order) mapAssign(n *Node) {
|
func (o *Order) mapAssign(n *Node) {
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
default:
|
default:
|
||||||
Fatalf("order.mapAssign %v", n.Op)
|
base.Fatalf("order.mapAssign %v", n.Op)
|
||||||
|
|
||||||
case OAS, OASOP:
|
case OAS, OASOP:
|
||||||
if n.Left.Op == OINDEXMAP {
|
if n.Left.Op == OINDEXMAP {
|
||||||
|
|
@ -582,7 +583,7 @@ func (o *Order) stmt(n *Node) {
|
||||||
|
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
default:
|
default:
|
||||||
Fatalf("order.stmt %v", n.Op)
|
base.Fatalf("order.stmt %v", n.Op)
|
||||||
|
|
||||||
case OVARKILL, OVARLIVE, OINLMARK:
|
case OVARKILL, OVARLIVE, OINLMARK:
|
||||||
o.out = append(o.out, n)
|
o.out = append(o.out, n)
|
||||||
|
|
@ -659,7 +660,7 @@ func (o *Order) stmt(n *Node) {
|
||||||
_ = mapKeyReplaceStrConv(r.Right)
|
_ = mapKeyReplaceStrConv(r.Right)
|
||||||
r.Right = o.mapKeyTemp(r.Left.Type, r.Right)
|
r.Right = o.mapKeyTemp(r.Left.Type, r.Right)
|
||||||
default:
|
default:
|
||||||
Fatalf("order.stmt: %v", r.Op)
|
base.Fatalf("order.stmt: %v", r.Op)
|
||||||
}
|
}
|
||||||
|
|
||||||
o.okAs2(n)
|
o.okAs2(n)
|
||||||
|
|
@ -776,7 +777,7 @@ func (o *Order) stmt(n *Node) {
|
||||||
orderBody := true
|
orderBody := true
|
||||||
switch n.Type.Etype {
|
switch n.Type.Etype {
|
||||||
default:
|
default:
|
||||||
Fatalf("order.stmt range %v", n.Type)
|
base.Fatalf("order.stmt range %v", n.Type)
|
||||||
|
|
||||||
case TARRAY, TSLICE:
|
case TARRAY, TSLICE:
|
||||||
if n.List.Len() < 2 || n.List.Second().isBlank() {
|
if n.List.Len() < 2 || n.List.Second().isBlank() {
|
||||||
|
|
@ -843,7 +844,7 @@ func (o *Order) stmt(n *Node) {
|
||||||
|
|
||||||
for _, n2 := range n.List.Slice() {
|
for _, n2 := range n.List.Slice() {
|
||||||
if n2.Op != OCASE {
|
if n2.Op != OCASE {
|
||||||
Fatalf("order select case %v", n2.Op)
|
base.Fatalf("order select case %v", n2.Op)
|
||||||
}
|
}
|
||||||
r := n2.Left
|
r := n2.Left
|
||||||
setlineno(n2)
|
setlineno(n2)
|
||||||
|
|
@ -851,7 +852,7 @@ func (o *Order) stmt(n *Node) {
|
||||||
// Append any new body prologue to ninit.
|
// Append any new body prologue to ninit.
|
||||||
// The next loop will insert ninit into nbody.
|
// The next loop will insert ninit into nbody.
|
||||||
if n2.Ninit.Len() != 0 {
|
if n2.Ninit.Len() != 0 {
|
||||||
Fatalf("order select ninit")
|
base.Fatalf("order select ninit")
|
||||||
}
|
}
|
||||||
if r == nil {
|
if r == nil {
|
||||||
continue
|
continue
|
||||||
|
|
@ -859,7 +860,7 @@ func (o *Order) stmt(n *Node) {
|
||||||
switch r.Op {
|
switch r.Op {
|
||||||
default:
|
default:
|
||||||
Dump("select case", r)
|
Dump("select case", r)
|
||||||
Fatalf("unknown op in select %v", r.Op)
|
base.Fatalf("unknown op in select %v", r.Op)
|
||||||
|
|
||||||
// If this is case x := <-ch or case x, y := <-ch, the case has
|
// If this is case x := <-ch or case x, y := <-ch, the case has
|
||||||
// the ODCL nodes to declare x and y. We want to delay that
|
// the ODCL nodes to declare x and y. We want to delay that
|
||||||
|
|
@ -881,7 +882,7 @@ func (o *Order) stmt(n *Node) {
|
||||||
|
|
||||||
if r.Ninit.Len() != 0 {
|
if r.Ninit.Len() != 0 {
|
||||||
dumplist("ninit", r.Ninit)
|
dumplist("ninit", r.Ninit)
|
||||||
Fatalf("ninit on select recv")
|
base.Fatalf("ninit on select recv")
|
||||||
}
|
}
|
||||||
|
|
||||||
// case x = <-c
|
// case x = <-c
|
||||||
|
|
@ -943,7 +944,7 @@ func (o *Order) stmt(n *Node) {
|
||||||
case OSEND:
|
case OSEND:
|
||||||
if r.Ninit.Len() != 0 {
|
if r.Ninit.Len() != 0 {
|
||||||
dumplist("ninit", r.Ninit)
|
dumplist("ninit", r.Ninit)
|
||||||
Fatalf("ninit on select send")
|
base.Fatalf("ninit on select send")
|
||||||
}
|
}
|
||||||
|
|
||||||
// case c <- x
|
// case c <- x
|
||||||
|
|
@ -998,7 +999,7 @@ func (o *Order) stmt(n *Node) {
|
||||||
// For now just clean all the temporaries at the end.
|
// For now just clean all the temporaries at the end.
|
||||||
// In practice that's fine.
|
// In practice that's fine.
|
||||||
case OSWITCH:
|
case OSWITCH:
|
||||||
if Debug.Libfuzzer != 0 && !hasDefaultCase(n) {
|
if base.Debug.Libfuzzer != 0 && !hasDefaultCase(n) {
|
||||||
// Add empty "default:" case for instrumentation.
|
// Add empty "default:" case for instrumentation.
|
||||||
n.List.Append(nod(OCASE, nil, nil))
|
n.List.Append(nod(OCASE, nil, nil))
|
||||||
}
|
}
|
||||||
|
|
@ -1007,7 +1008,7 @@ func (o *Order) stmt(n *Node) {
|
||||||
n.Left = o.expr(n.Left, nil)
|
n.Left = o.expr(n.Left, nil)
|
||||||
for _, ncas := range n.List.Slice() {
|
for _, ncas := range n.List.Slice() {
|
||||||
if ncas.Op != OCASE {
|
if ncas.Op != OCASE {
|
||||||
Fatalf("order switch case %v", ncas.Op)
|
base.Fatalf("order switch case %v", ncas.Op)
|
||||||
}
|
}
|
||||||
o.exprListInPlace(ncas.List)
|
o.exprListInPlace(ncas.List)
|
||||||
orderBlock(&ncas.Nbody, o.free)
|
orderBlock(&ncas.Nbody, o.free)
|
||||||
|
|
@ -1017,13 +1018,13 @@ func (o *Order) stmt(n *Node) {
|
||||||
o.cleanTemp(t)
|
o.cleanTemp(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
lineno = lno
|
base.Pos = lno
|
||||||
}
|
}
|
||||||
|
|
||||||
func hasDefaultCase(n *Node) bool {
|
func hasDefaultCase(n *Node) bool {
|
||||||
for _, ncas := range n.List.Slice() {
|
for _, ncas := range n.List.Slice() {
|
||||||
if ncas.Op != OCASE {
|
if ncas.Op != OCASE {
|
||||||
Fatalf("expected case, found %v", ncas.Op)
|
base.Fatalf("expected case, found %v", ncas.Op)
|
||||||
}
|
}
|
||||||
if ncas.List.Len() == 0 {
|
if ncas.List.Len() == 0 {
|
||||||
return true
|
return true
|
||||||
|
|
@ -1330,7 +1331,7 @@ func (o *Order) expr(n, lhs *Node) *Node {
|
||||||
var dynamics []*Node
|
var dynamics []*Node
|
||||||
for _, r := range entries {
|
for _, r := range entries {
|
||||||
if r.Op != OKEY {
|
if r.Op != OKEY {
|
||||||
Fatalf("OMAPLIT entry not OKEY: %v\n", r)
|
base.Fatalf("OMAPLIT entry not OKEY: %v\n", r)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isStaticCompositeLiteral(r.Left) || !isStaticCompositeLiteral(r.Right) {
|
if !isStaticCompositeLiteral(r.Left) || !isStaticCompositeLiteral(r.Right) {
|
||||||
|
|
@ -1369,7 +1370,7 @@ func (o *Order) expr(n, lhs *Node) *Node {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lineno = lno
|
base.Pos = lno
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/ssa"
|
"cmd/compile/internal/ssa"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/dwarf"
|
"cmd/internal/dwarf"
|
||||||
|
|
@ -29,7 +30,7 @@ func emitptrargsmap(fn *Node) {
|
||||||
if fn.funcname() == "_" || fn.Func.Nname.Sym.Linkname != "" {
|
if fn.funcname() == "_" || fn.Func.Nname.Sym.Linkname != "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
lsym := Ctxt.Lookup(fn.Func.lsym.Name + ".args_stackmap")
|
lsym := base.Ctxt.Lookup(fn.Func.lsym.Name + ".args_stackmap")
|
||||||
|
|
||||||
nptr := int(fn.Type.ArgWidth() / int64(Widthptr))
|
nptr := int(fn.Type.ArgWidth() / int64(Widthptr))
|
||||||
bv := bvalloc(int32(nptr) * 2)
|
bv := bvalloc(int32(nptr) * 2)
|
||||||
|
|
@ -164,7 +165,7 @@ func (s *ssafn) AllocFrame(f *ssa.Func) {
|
||||||
dowidth(n.Type)
|
dowidth(n.Type)
|
||||||
w := n.Type.Width
|
w := n.Type.Width
|
||||||
if w >= thearch.MAXWIDTH || w < 0 {
|
if w >= thearch.MAXWIDTH || w < 0 {
|
||||||
Fatalf("bad width")
|
base.Fatalf("bad width")
|
||||||
}
|
}
|
||||||
if w == 0 && lastHasPtr {
|
if w == 0 && lastHasPtr {
|
||||||
// Pad between a pointer-containing object and a zero-sized object.
|
// Pad between a pointer-containing object and a zero-sized object.
|
||||||
|
|
@ -193,12 +194,12 @@ func (s *ssafn) AllocFrame(f *ssa.Func) {
|
||||||
|
|
||||||
func funccompile(fn *Node) {
|
func funccompile(fn *Node) {
|
||||||
if Curfn != nil {
|
if Curfn != nil {
|
||||||
Fatalf("funccompile %v inside %v", fn.Func.Nname.Sym, Curfn.Func.Nname.Sym)
|
base.Fatalf("funccompile %v inside %v", fn.Func.Nname.Sym, Curfn.Func.Nname.Sym)
|
||||||
}
|
}
|
||||||
|
|
||||||
if fn.Type == nil {
|
if fn.Type == nil {
|
||||||
if Errors() == 0 {
|
if base.Errors() == 0 {
|
||||||
Fatalf("funccompile missing type")
|
base.Fatalf("funccompile missing type")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -223,9 +224,9 @@ func funccompile(fn *Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func compile(fn *Node) {
|
func compile(fn *Node) {
|
||||||
errorsBefore := Errors()
|
errorsBefore := base.Errors()
|
||||||
order(fn)
|
order(fn)
|
||||||
if Errors() > errorsBefore {
|
if base.Errors() > errorsBefore {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -235,7 +236,7 @@ func compile(fn *Node) {
|
||||||
fn.Func.initLSym(true)
|
fn.Func.initLSym(true)
|
||||||
|
|
||||||
walk(fn)
|
walk(fn)
|
||||||
if Errors() > errorsBefore {
|
if base.Errors() > errorsBefore {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if instrumenting {
|
if instrumenting {
|
||||||
|
|
@ -265,7 +266,7 @@ func compile(fn *Node) {
|
||||||
// Also make sure we allocate a linker symbol
|
// Also make sure we allocate a linker symbol
|
||||||
// for the stack object data, for the same reason.
|
// for the stack object data, for the same reason.
|
||||||
if fn.Func.lsym.Func().StackObjects == nil {
|
if fn.Func.lsym.Func().StackObjects == nil {
|
||||||
fn.Func.lsym.Func().StackObjects = Ctxt.Lookup(fn.Func.lsym.Name + ".stkobj")
|
fn.Func.lsym.Func().StackObjects = base.Ctxt.Lookup(fn.Func.lsym.Name + ".stkobj")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -291,7 +292,7 @@ func compilenow(fn *Node) bool {
|
||||||
if fn.IsMethod() && isInlinableButNotInlined(fn) {
|
if fn.IsMethod() && isInlinableButNotInlined(fn) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return Flag.LowerC == 1 && Debug.CompileLater == 0
|
return base.Flag.LowerC == 1 && base.Debug.CompileLater == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// isInlinableButNotInlined returns true if 'fn' was marked as an
|
// isInlinableButNotInlined returns true if 'fn' was marked as an
|
||||||
|
|
@ -373,9 +374,9 @@ func compileFunctions() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
Ctxt.InParallel = true
|
base.Ctxt.InParallel = true
|
||||||
c := make(chan *Node, Flag.LowerC)
|
c := make(chan *Node, base.Flag.LowerC)
|
||||||
for i := 0; i < Flag.LowerC; i++ {
|
for i := 0; i < base.Flag.LowerC; i++ {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(worker int) {
|
go func(worker int) {
|
||||||
for fn := range c {
|
for fn := range c {
|
||||||
|
|
@ -390,7 +391,7 @@ func compileFunctions() {
|
||||||
close(c)
|
close(c)
|
||||||
compilequeue = nil
|
compilequeue = nil
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
Ctxt.InParallel = false
|
base.Ctxt.InParallel = false
|
||||||
sizeCalculationDisabled = false
|
sizeCalculationDisabled = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -399,7 +400,7 @@ func debuginfo(fnsym *obj.LSym, infosym *obj.LSym, curfn interface{}) ([]dwarf.S
|
||||||
fn := curfn.(*Node)
|
fn := curfn.(*Node)
|
||||||
if fn.Func.Nname != nil {
|
if fn.Func.Nname != nil {
|
||||||
if expect := fn.Func.Nname.Sym.Linksym(); fnsym != expect {
|
if expect := fn.Func.Nname.Sym.Linksym(); fnsym != expect {
|
||||||
Fatalf("unexpected fnsym: %v != %v", fnsym, expect)
|
base.Fatalf("unexpected fnsym: %v != %v", fnsym, expect)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -442,7 +443,7 @@ func debuginfo(fnsym *obj.LSym, infosym *obj.LSym, curfn interface{}) ([]dwarf.S
|
||||||
if !n.Name.Used() {
|
if !n.Name.Used() {
|
||||||
// Text == nil -> generating abstract function
|
// Text == nil -> generating abstract function
|
||||||
if fnsym.Func().Text != nil {
|
if fnsym.Func().Text != nil {
|
||||||
Fatalf("debuginfo unused node (AllocFrame should truncate fn.Func.Dcl)")
|
base.Fatalf("debuginfo unused node (AllocFrame should truncate fn.Func.Dcl)")
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -481,7 +482,7 @@ func debuginfo(fnsym *obj.LSym, infosym *obj.LSym, curfn interface{}) ([]dwarf.S
|
||||||
|
|
||||||
scopes := assembleScopes(fnsym, fn, dwarfVars, varScopes)
|
scopes := assembleScopes(fnsym, fn, dwarfVars, varScopes)
|
||||||
var inlcalls dwarf.InlCalls
|
var inlcalls dwarf.InlCalls
|
||||||
if Flag.GenDwarfInl > 0 {
|
if base.Flag.GenDwarfInl > 0 {
|
||||||
inlcalls = assembleInlines(fnsym, dwarfVars)
|
inlcalls = assembleInlines(fnsym, dwarfVars)
|
||||||
}
|
}
|
||||||
return scopes, inlcalls
|
return scopes, inlcalls
|
||||||
|
|
@ -533,7 +534,7 @@ func createSimpleVar(fnsym *obj.LSym, n *Node) *dwarf.Var {
|
||||||
switch n.Class() {
|
switch n.Class() {
|
||||||
case PAUTO:
|
case PAUTO:
|
||||||
abbrev = dwarf.DW_ABRV_AUTO
|
abbrev = dwarf.DW_ABRV_AUTO
|
||||||
if Ctxt.FixedFrameSize() == 0 {
|
if base.Ctxt.FixedFrameSize() == 0 {
|
||||||
offs -= int64(Widthptr)
|
offs -= int64(Widthptr)
|
||||||
}
|
}
|
||||||
if objabi.Framepointer_enabled || objabi.GOARCH == "arm64" {
|
if objabi.Framepointer_enabled || objabi.GOARCH == "arm64" {
|
||||||
|
|
@ -543,15 +544,15 @@ func createSimpleVar(fnsym *obj.LSym, n *Node) *dwarf.Var {
|
||||||
|
|
||||||
case PPARAM, PPARAMOUT:
|
case PPARAM, PPARAMOUT:
|
||||||
abbrev = dwarf.DW_ABRV_PARAM
|
abbrev = dwarf.DW_ABRV_PARAM
|
||||||
offs += Ctxt.FixedFrameSize()
|
offs += base.Ctxt.FixedFrameSize()
|
||||||
default:
|
default:
|
||||||
Fatalf("createSimpleVar unexpected class %v for node %v", n.Class(), n)
|
base.Fatalf("createSimpleVar unexpected class %v for node %v", n.Class(), n)
|
||||||
}
|
}
|
||||||
|
|
||||||
typename := dwarf.InfoPrefix + typesymname(n.Type)
|
typename := dwarf.InfoPrefix + typesymname(n.Type)
|
||||||
delete(fnsym.Func().Autot, ngotype(n).Linksym())
|
delete(fnsym.Func().Autot, ngotype(n).Linksym())
|
||||||
inlIndex := 0
|
inlIndex := 0
|
||||||
if Flag.GenDwarfInl > 1 {
|
if base.Flag.GenDwarfInl > 1 {
|
||||||
if n.Name.InlFormal() || n.Name.InlLocal() {
|
if n.Name.InlFormal() || n.Name.InlLocal() {
|
||||||
inlIndex = posInlIndex(n.Pos) + 1
|
inlIndex = posInlIndex(n.Pos) + 1
|
||||||
if n.Name.InlFormal() {
|
if n.Name.InlFormal() {
|
||||||
|
|
@ -559,14 +560,14 @@ func createSimpleVar(fnsym *obj.LSym, n *Node) *dwarf.Var {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
declpos := Ctxt.InnermostPos(declPos(n))
|
declpos := base.Ctxt.InnermostPos(declPos(n))
|
||||||
return &dwarf.Var{
|
return &dwarf.Var{
|
||||||
Name: n.Sym.Name,
|
Name: n.Sym.Name,
|
||||||
IsReturnValue: n.Class() == PPARAMOUT,
|
IsReturnValue: n.Class() == PPARAMOUT,
|
||||||
IsInlFormal: n.Name.InlFormal(),
|
IsInlFormal: n.Name.InlFormal(),
|
||||||
Abbrev: abbrev,
|
Abbrev: abbrev,
|
||||||
StackOffset: int32(offs),
|
StackOffset: int32(offs),
|
||||||
Type: Ctxt.Lookup(typename),
|
Type: base.Ctxt.Lookup(typename),
|
||||||
DeclFile: declpos.RelFilename(),
|
DeclFile: declpos.RelFilename(),
|
||||||
DeclLine: declpos.RelLine(),
|
DeclLine: declpos.RelLine(),
|
||||||
DeclCol: declpos.Col(),
|
DeclCol: declpos.Col(),
|
||||||
|
|
@ -608,7 +609,7 @@ func createDwarfVars(fnsym *obj.LSym, complexOK bool, fn *Func, apDecls []*Node)
|
||||||
var vars []*dwarf.Var
|
var vars []*dwarf.Var
|
||||||
var decls []*Node
|
var decls []*Node
|
||||||
var selected map[*Node]bool
|
var selected map[*Node]bool
|
||||||
if Ctxt.Flag_locationlists && Ctxt.Flag_optimize && fn.DebugInfo != nil && complexOK {
|
if base.Ctxt.Flag_locationlists && base.Ctxt.Flag_optimize && fn.DebugInfo != nil && complexOK {
|
||||||
decls, vars, selected = createComplexVars(fnsym, fn)
|
decls, vars, selected = createComplexVars(fnsym, fn)
|
||||||
} else {
|
} else {
|
||||||
decls, vars, selected = createSimpleVars(fnsym, apDecls)
|
decls, vars, selected = createSimpleVars(fnsym, apDecls)
|
||||||
|
|
@ -672,7 +673,7 @@ func createDwarfVars(fnsym *obj.LSym, complexOK bool, fn *Func, apDecls []*Node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inlIndex := 0
|
inlIndex := 0
|
||||||
if Flag.GenDwarfInl > 1 {
|
if base.Flag.GenDwarfInl > 1 {
|
||||||
if n.Name.InlFormal() || n.Name.InlLocal() {
|
if n.Name.InlFormal() || n.Name.InlLocal() {
|
||||||
inlIndex = posInlIndex(n.Pos) + 1
|
inlIndex = posInlIndex(n.Pos) + 1
|
||||||
if n.Name.InlFormal() {
|
if n.Name.InlFormal() {
|
||||||
|
|
@ -680,13 +681,13 @@ func createDwarfVars(fnsym *obj.LSym, complexOK bool, fn *Func, apDecls []*Node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
declpos := Ctxt.InnermostPos(n.Pos)
|
declpos := base.Ctxt.InnermostPos(n.Pos)
|
||||||
vars = append(vars, &dwarf.Var{
|
vars = append(vars, &dwarf.Var{
|
||||||
Name: n.Sym.Name,
|
Name: n.Sym.Name,
|
||||||
IsReturnValue: isReturnValue,
|
IsReturnValue: isReturnValue,
|
||||||
Abbrev: abbrev,
|
Abbrev: abbrev,
|
||||||
StackOffset: int32(n.Xoffset),
|
StackOffset: int32(n.Xoffset),
|
||||||
Type: Ctxt.Lookup(typename),
|
Type: base.Ctxt.Lookup(typename),
|
||||||
DeclFile: declpos.RelFilename(),
|
DeclFile: declpos.RelFilename(),
|
||||||
DeclLine: declpos.RelLine(),
|
DeclLine: declpos.RelLine(),
|
||||||
DeclCol: declpos.Col(),
|
DeclCol: declpos.Col(),
|
||||||
|
|
@ -707,7 +708,7 @@ func createDwarfVars(fnsym *obj.LSym, complexOK bool, fn *Func, apDecls []*Node)
|
||||||
// names of the variables may have been "versioned" to avoid conflicts
|
// names of the variables may have been "versioned" to avoid conflicts
|
||||||
// with local vars; disregard this versioning when sorting.
|
// with local vars; disregard this versioning when sorting.
|
||||||
func preInliningDcls(fnsym *obj.LSym) []*Node {
|
func preInliningDcls(fnsym *obj.LSym) []*Node {
|
||||||
fn := Ctxt.DwFixups.GetPrecursorFunc(fnsym).(*Node)
|
fn := base.Ctxt.DwFixups.GetPrecursorFunc(fnsym).(*Node)
|
||||||
var rdcl []*Node
|
var rdcl []*Node
|
||||||
for _, n := range fn.Func.Inl.Dcl {
|
for _, n := range fn.Func.Inl.Dcl {
|
||||||
c := n.Sym.Name[0]
|
c := n.Sym.Name[0]
|
||||||
|
|
@ -729,7 +730,7 @@ func stackOffset(slot ssa.LocalSlot) int32 {
|
||||||
var off int64
|
var off int64
|
||||||
switch n.Class() {
|
switch n.Class() {
|
||||||
case PAUTO:
|
case PAUTO:
|
||||||
if Ctxt.FixedFrameSize() == 0 {
|
if base.Ctxt.FixedFrameSize() == 0 {
|
||||||
off -= int64(Widthptr)
|
off -= int64(Widthptr)
|
||||||
}
|
}
|
||||||
if objabi.Framepointer_enabled || objabi.GOARCH == "arm64" {
|
if objabi.Framepointer_enabled || objabi.GOARCH == "arm64" {
|
||||||
|
|
@ -737,7 +738,7 @@ func stackOffset(slot ssa.LocalSlot) int32 {
|
||||||
off -= int64(Widthptr)
|
off -= int64(Widthptr)
|
||||||
}
|
}
|
||||||
case PPARAM, PPARAMOUT:
|
case PPARAM, PPARAMOUT:
|
||||||
off += Ctxt.FixedFrameSize()
|
off += base.Ctxt.FixedFrameSize()
|
||||||
}
|
}
|
||||||
return int32(off + n.Xoffset + slot.Off)
|
return int32(off + n.Xoffset + slot.Off)
|
||||||
}
|
}
|
||||||
|
|
@ -761,7 +762,7 @@ func createComplexVar(fnsym *obj.LSym, fn *Func, varID ssa.VarID) *dwarf.Var {
|
||||||
delete(fnsym.Func().Autot, gotype)
|
delete(fnsym.Func().Autot, gotype)
|
||||||
typename := dwarf.InfoPrefix + gotype.Name[len("type."):]
|
typename := dwarf.InfoPrefix + gotype.Name[len("type."):]
|
||||||
inlIndex := 0
|
inlIndex := 0
|
||||||
if Flag.GenDwarfInl > 1 {
|
if base.Flag.GenDwarfInl > 1 {
|
||||||
if n.Name.InlFormal() || n.Name.InlLocal() {
|
if n.Name.InlFormal() || n.Name.InlLocal() {
|
||||||
inlIndex = posInlIndex(n.Pos) + 1
|
inlIndex = posInlIndex(n.Pos) + 1
|
||||||
if n.Name.InlFormal() {
|
if n.Name.InlFormal() {
|
||||||
|
|
@ -769,13 +770,13 @@ func createComplexVar(fnsym *obj.LSym, fn *Func, varID ssa.VarID) *dwarf.Var {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
declpos := Ctxt.InnermostPos(n.Pos)
|
declpos := base.Ctxt.InnermostPos(n.Pos)
|
||||||
dvar := &dwarf.Var{
|
dvar := &dwarf.Var{
|
||||||
Name: n.Sym.Name,
|
Name: n.Sym.Name,
|
||||||
IsReturnValue: n.Class() == PPARAMOUT,
|
IsReturnValue: n.Class() == PPARAMOUT,
|
||||||
IsInlFormal: n.Name.InlFormal(),
|
IsInlFormal: n.Name.InlFormal(),
|
||||||
Abbrev: abbrev,
|
Abbrev: abbrev,
|
||||||
Type: Ctxt.Lookup(typename),
|
Type: base.Ctxt.Lookup(typename),
|
||||||
// The stack offset is used as a sorting key, so for decomposed
|
// The stack offset is used as a sorting key, so for decomposed
|
||||||
// variables just give it the first one. It's not used otherwise.
|
// variables just give it the first one. It's not used otherwise.
|
||||||
// This won't work well if the first slot hasn't been assigned a stack
|
// This won't work well if the first slot hasn't been assigned a stack
|
||||||
|
|
@ -790,7 +791,7 @@ func createComplexVar(fnsym *obj.LSym, fn *Func, varID ssa.VarID) *dwarf.Var {
|
||||||
list := debug.LocationLists[varID]
|
list := debug.LocationLists[varID]
|
||||||
if len(list) != 0 {
|
if len(list) != 0 {
|
||||||
dvar.PutLocationList = func(listSym, startPC dwarf.Sym) {
|
dvar.PutLocationList = func(listSym, startPC dwarf.Sym) {
|
||||||
debug.PutLocationList(list, Ctxt, listSym.(*obj.LSym), startPC.(*obj.LSym))
|
debug.PutLocationList(list, base.Ctxt, listSym.(*obj.LSym), startPC.(*obj.LSym))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return dvar
|
return dvar
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/ssa"
|
"cmd/compile/internal/ssa"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
|
|
@ -226,7 +227,7 @@ func getvariables(fn *Node) ([]*Node, map[*Node]int32) {
|
||||||
|
|
||||||
func (lv *Liveness) initcache() {
|
func (lv *Liveness) initcache() {
|
||||||
if lv.cache.initialized {
|
if lv.cache.initialized {
|
||||||
Fatalf("liveness cache initialized twice")
|
base.Fatalf("liveness cache initialized twice")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
lv.cache.initialized = true
|
lv.cache.initialized = true
|
||||||
|
|
@ -341,7 +342,7 @@ func affectedNode(v *ssa.Value) (*Node, ssa.SymEffect) {
|
||||||
case *Node:
|
case *Node:
|
||||||
return a, e
|
return a, e
|
||||||
default:
|
default:
|
||||||
Fatalf("weird aux: %s", v.LongString())
|
base.Fatalf("weird aux: %s", v.LongString())
|
||||||
return nil, e
|
return nil, e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -406,7 +407,7 @@ func (lv *Liveness) blockEffects(b *ssa.Block) *BlockEffects {
|
||||||
// on future calls with the same type t.
|
// on future calls with the same type t.
|
||||||
func onebitwalktype1(t *types.Type, off int64, bv bvec) {
|
func onebitwalktype1(t *types.Type, off int64, bv bvec) {
|
||||||
if t.Align > 0 && off&int64(t.Align-1) != 0 {
|
if t.Align > 0 && off&int64(t.Align-1) != 0 {
|
||||||
Fatalf("onebitwalktype1: invalid initial alignment: type %v has alignment %d, but offset is %v", t, t.Align, off)
|
base.Fatalf("onebitwalktype1: invalid initial alignment: type %v has alignment %d, but offset is %v", t, t.Align, off)
|
||||||
}
|
}
|
||||||
if !t.HasPointers() {
|
if !t.HasPointers() {
|
||||||
// Note: this case ensures that pointers to go:notinheap types
|
// Note: this case ensures that pointers to go:notinheap types
|
||||||
|
|
@ -417,14 +418,14 @@ func onebitwalktype1(t *types.Type, off int64, bv bvec) {
|
||||||
switch t.Etype {
|
switch t.Etype {
|
||||||
case TPTR, TUNSAFEPTR, TFUNC, TCHAN, TMAP:
|
case TPTR, TUNSAFEPTR, TFUNC, TCHAN, TMAP:
|
||||||
if off&int64(Widthptr-1) != 0 {
|
if off&int64(Widthptr-1) != 0 {
|
||||||
Fatalf("onebitwalktype1: invalid alignment, %v", t)
|
base.Fatalf("onebitwalktype1: invalid alignment, %v", t)
|
||||||
}
|
}
|
||||||
bv.Set(int32(off / int64(Widthptr))) // pointer
|
bv.Set(int32(off / int64(Widthptr))) // pointer
|
||||||
|
|
||||||
case TSTRING:
|
case TSTRING:
|
||||||
// struct { byte *str; intgo len; }
|
// struct { byte *str; intgo len; }
|
||||||
if off&int64(Widthptr-1) != 0 {
|
if off&int64(Widthptr-1) != 0 {
|
||||||
Fatalf("onebitwalktype1: invalid alignment, %v", t)
|
base.Fatalf("onebitwalktype1: invalid alignment, %v", t)
|
||||||
}
|
}
|
||||||
bv.Set(int32(off / int64(Widthptr))) //pointer in first slot
|
bv.Set(int32(off / int64(Widthptr))) //pointer in first slot
|
||||||
|
|
||||||
|
|
@ -433,7 +434,7 @@ func onebitwalktype1(t *types.Type, off int64, bv bvec) {
|
||||||
// or, when isnilinter(t)==true:
|
// or, when isnilinter(t)==true:
|
||||||
// struct { Type *type; void *data; }
|
// struct { Type *type; void *data; }
|
||||||
if off&int64(Widthptr-1) != 0 {
|
if off&int64(Widthptr-1) != 0 {
|
||||||
Fatalf("onebitwalktype1: invalid alignment, %v", t)
|
base.Fatalf("onebitwalktype1: invalid alignment, %v", t)
|
||||||
}
|
}
|
||||||
// The first word of an interface is a pointer, but we don't
|
// The first word of an interface is a pointer, but we don't
|
||||||
// treat it as such.
|
// treat it as such.
|
||||||
|
|
@ -452,7 +453,7 @@ func onebitwalktype1(t *types.Type, off int64, bv bvec) {
|
||||||
case TSLICE:
|
case TSLICE:
|
||||||
// struct { byte *array; uintgo len; uintgo cap; }
|
// struct { byte *array; uintgo len; uintgo cap; }
|
||||||
if off&int64(Widthptr-1) != 0 {
|
if off&int64(Widthptr-1) != 0 {
|
||||||
Fatalf("onebitwalktype1: invalid TARRAY alignment, %v", t)
|
base.Fatalf("onebitwalktype1: invalid TARRAY alignment, %v", t)
|
||||||
}
|
}
|
||||||
bv.Set(int32(off / int64(Widthptr))) // pointer in first slot (BitsPointer)
|
bv.Set(int32(off / int64(Widthptr))) // pointer in first slot (BitsPointer)
|
||||||
|
|
||||||
|
|
@ -473,7 +474,7 @@ func onebitwalktype1(t *types.Type, off int64, bv bvec) {
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Fatalf("onebitwalktype1: unexpected type, %v", t)
|
base.Fatalf("onebitwalktype1: unexpected type, %v", t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -509,7 +510,7 @@ func allUnsafe(f *ssa.Func) bool {
|
||||||
// go:nosplit functions are similar. Since safe points used to
|
// go:nosplit functions are similar. Since safe points used to
|
||||||
// be coupled with stack checks, go:nosplit often actually
|
// be coupled with stack checks, go:nosplit often actually
|
||||||
// means "no safe points in this function".
|
// means "no safe points in this function".
|
||||||
return Flag.CompilingRuntime || f.NoSplit
|
return base.Flag.CompilingRuntime || f.NoSplit
|
||||||
}
|
}
|
||||||
|
|
||||||
// markUnsafePoints finds unsafe points and computes lv.unsafePoints.
|
// markUnsafePoints finds unsafe points and computes lv.unsafePoints.
|
||||||
|
|
@ -791,7 +792,7 @@ func (lv *Liveness) epilogue() {
|
||||||
if n.Class() == PPARAMOUT {
|
if n.Class() == PPARAMOUT {
|
||||||
if n.Name.IsOutputParamHeapAddr() {
|
if n.Name.IsOutputParamHeapAddr() {
|
||||||
// Just to be paranoid. Heap addresses are PAUTOs.
|
// Just to be paranoid. Heap addresses are PAUTOs.
|
||||||
Fatalf("variable %v both output param and heap output param", n)
|
base.Fatalf("variable %v both output param and heap output param", n)
|
||||||
}
|
}
|
||||||
if n.Name.Param.Heapaddr != nil {
|
if n.Name.Param.Heapaddr != nil {
|
||||||
// If this variable moved to the heap, then
|
// If this variable moved to the heap, then
|
||||||
|
|
@ -816,7 +817,7 @@ func (lv *Liveness) epilogue() {
|
||||||
livedefer.Set(int32(i))
|
livedefer.Set(int32(i))
|
||||||
// It was already marked as Needzero when created.
|
// It was already marked as Needzero when created.
|
||||||
if !n.Name.Needzero() {
|
if !n.Name.Needzero() {
|
||||||
Fatalf("all pointer-containing defer arg slots should have Needzero set")
|
base.Fatalf("all pointer-containing defer arg slots should have Needzero set")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -878,7 +879,7 @@ func (lv *Liveness) epilogue() {
|
||||||
|
|
||||||
if b == lv.f.Entry {
|
if b == lv.f.Entry {
|
||||||
if index != 0 {
|
if index != 0 {
|
||||||
Fatalf("bad index for entry point: %v", index)
|
base.Fatalf("bad index for entry point: %v", index)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check to make sure only input variables are live.
|
// Check to make sure only input variables are live.
|
||||||
|
|
@ -889,7 +890,7 @@ func (lv *Liveness) epilogue() {
|
||||||
if n.Class() == PPARAM {
|
if n.Class() == PPARAM {
|
||||||
continue // ok
|
continue // ok
|
||||||
}
|
}
|
||||||
Fatalf("bad live variable at entry of %v: %L", lv.fn.Func.Nname, n)
|
base.Fatalf("bad live variable at entry of %v: %L", lv.fn.Func.Nname, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record live variables.
|
// Record live variables.
|
||||||
|
|
@ -966,7 +967,7 @@ func (lv *Liveness) compact(b *ssa.Block) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lv *Liveness) showlive(v *ssa.Value, live bvec) {
|
func (lv *Liveness) showlive(v *ssa.Value, live bvec) {
|
||||||
if Flag.Live == 0 || lv.fn.funcname() == "init" || strings.HasPrefix(lv.fn.funcname(), ".") {
|
if base.Flag.Live == 0 || lv.fn.funcname() == "init" || strings.HasPrefix(lv.fn.funcname(), ".") {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !(v == nil || v.Op.IsCall()) {
|
if !(v == nil || v.Op.IsCall()) {
|
||||||
|
|
@ -1002,7 +1003,7 @@ func (lv *Liveness) showlive(v *ssa.Value, live bvec) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Warnl(pos, s)
|
base.WarnfAt(pos, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lv *Liveness) printbvec(printed bool, name string, live bvec) bool {
|
func (lv *Liveness) printbvec(printed bool, name string, live bvec) bool {
|
||||||
|
|
@ -1088,7 +1089,7 @@ func (lv *Liveness) printDebug() {
|
||||||
|
|
||||||
if b == lv.f.Entry {
|
if b == lv.f.Entry {
|
||||||
live := lv.stackMaps[0]
|
live := lv.stackMaps[0]
|
||||||
fmt.Printf("(%s) function entry\n", linestr(lv.fn.Func.Nname.Pos))
|
fmt.Printf("(%s) function entry\n", base.FmtPos(lv.fn.Func.Nname.Pos))
|
||||||
fmt.Printf("\tlive=")
|
fmt.Printf("\tlive=")
|
||||||
printed = false
|
printed = false
|
||||||
for j, n := range lv.vars {
|
for j, n := range lv.vars {
|
||||||
|
|
@ -1105,7 +1106,7 @@ func (lv *Liveness) printDebug() {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range b.Values {
|
for _, v := range b.Values {
|
||||||
fmt.Printf("(%s) %v\n", linestr(v.Pos), v.LongString())
|
fmt.Printf("(%s) %v\n", base.FmtPos(v.Pos), v.LongString())
|
||||||
|
|
||||||
pcdata := lv.livenessMap.Get(v)
|
pcdata := lv.livenessMap.Get(v)
|
||||||
|
|
||||||
|
|
@ -1214,7 +1215,7 @@ func (lv *Liveness) emit() (argsSym, liveSym *obj.LSym) {
|
||||||
// These symbols will be added to Ctxt.Data by addGCLocals
|
// These symbols will be added to Ctxt.Data by addGCLocals
|
||||||
// after parallel compilation is done.
|
// after parallel compilation is done.
|
||||||
makeSym := func(tmpSym *obj.LSym) *obj.LSym {
|
makeSym := func(tmpSym *obj.LSym) *obj.LSym {
|
||||||
return Ctxt.LookupInit(fmt.Sprintf("gclocals·%x", md5.Sum(tmpSym.P)), func(lsym *obj.LSym) {
|
return base.Ctxt.LookupInit(fmt.Sprintf("gclocals·%x", md5.Sum(tmpSym.P)), func(lsym *obj.LSym) {
|
||||||
lsym.P = tmpSym.P
|
lsym.P = tmpSym.P
|
||||||
lsym.Set(obj.AttrContentAddressable, true)
|
lsym.Set(obj.AttrContentAddressable, true)
|
||||||
})
|
})
|
||||||
|
|
@ -1235,7 +1236,7 @@ func liveness(e *ssafn, f *ssa.Func, pp *Progs) LivenessMap {
|
||||||
lv.prologue()
|
lv.prologue()
|
||||||
lv.solve()
|
lv.solve()
|
||||||
lv.epilogue()
|
lv.epilogue()
|
||||||
if Flag.Live > 0 {
|
if base.Flag.Live > 0 {
|
||||||
lv.showlive(nil, lv.stackMaps[0])
|
lv.showlive(nil, lv.stackMaps[0])
|
||||||
for _, b := range f.Blocks {
|
for _, b := range f.Blocks {
|
||||||
for _, val := range b.Values {
|
for _, val := range b.Values {
|
||||||
|
|
@ -1245,7 +1246,7 @@ func liveness(e *ssafn, f *ssa.Func, pp *Progs) LivenessMap {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if Flag.Live >= 2 {
|
if base.Flag.Live >= 2 {
|
||||||
lv.printDebug()
|
lv.printDebug()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/src"
|
"cmd/internal/src"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
|
|
@ -47,9 +48,9 @@ var omit_pkgs = []string{
|
||||||
var norace_inst_pkgs = []string{"sync", "sync/atomic"}
|
var norace_inst_pkgs = []string{"sync", "sync/atomic"}
|
||||||
|
|
||||||
func ispkgin(pkgs []string) bool {
|
func ispkgin(pkgs []string) bool {
|
||||||
if Ctxt.Pkgpath != "" {
|
if base.Ctxt.Pkgpath != "" {
|
||||||
for _, p := range pkgs {
|
for _, p := range pkgs {
|
||||||
if Ctxt.Pkgpath == p {
|
if base.Ctxt.Pkgpath == p {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -63,13 +64,13 @@ func instrument(fn *Node) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !Flag.Race || !ispkgin(norace_inst_pkgs) {
|
if !base.Flag.Race || !ispkgin(norace_inst_pkgs) {
|
||||||
fn.Func.SetInstrumentBody(true)
|
fn.Func.SetInstrumentBody(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
if Flag.Race {
|
if base.Flag.Race {
|
||||||
lno := lineno
|
lno := base.Pos
|
||||||
lineno = src.NoXPos
|
base.Pos = src.NoXPos
|
||||||
|
|
||||||
if thearch.LinkArch.Arch.Family != sys.AMD64 {
|
if thearch.LinkArch.Arch.Family != sys.AMD64 {
|
||||||
fn.Func.Enter.Prepend(mkcall("racefuncenterfp", nil, nil))
|
fn.Func.Enter.Prepend(mkcall("racefuncenterfp", nil, nil))
|
||||||
|
|
@ -88,6 +89,6 @@ func instrument(fn *Node) {
|
||||||
fn.Func.Enter.Prepend(mkcall("racefuncenter", nil, nil, nodpc))
|
fn.Func.Enter.Prepend(mkcall("racefuncenter", nil, nil, nodpc))
|
||||||
fn.Func.Exit.Append(mkcall("racefuncexit", nil, nil))
|
fn.Func.Exit.Append(mkcall("racefuncexit", nil, nil))
|
||||||
}
|
}
|
||||||
lineno = lno
|
base.Pos = lno
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
@ -61,7 +62,7 @@ func typecheckrangeExpr(n *Node) {
|
||||||
toomany := false
|
toomany := false
|
||||||
switch t.Etype {
|
switch t.Etype {
|
||||||
default:
|
default:
|
||||||
yyerrorl(n.Pos, "cannot range over %L", n.Right)
|
base.ErrorfAt(n.Pos, "cannot range over %L", n.Right)
|
||||||
return
|
return
|
||||||
|
|
||||||
case TARRAY, TSLICE:
|
case TARRAY, TSLICE:
|
||||||
|
|
@ -74,7 +75,7 @@ func typecheckrangeExpr(n *Node) {
|
||||||
|
|
||||||
case TCHAN:
|
case TCHAN:
|
||||||
if !t.ChanDir().CanRecv() {
|
if !t.ChanDir().CanRecv() {
|
||||||
yyerrorl(n.Pos, "invalid operation: range %v (receive from send-only type %v)", n.Right, n.Right.Type)
|
base.ErrorfAt(n.Pos, "invalid operation: range %v (receive from send-only type %v)", n.Right, n.Right.Type)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -90,7 +91,7 @@ func typecheckrangeExpr(n *Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.List.Len() > 2 || toomany {
|
if n.List.Len() > 2 || toomany {
|
||||||
yyerrorl(n.Pos, "too many variables in range")
|
base.ErrorfAt(n.Pos, "too many variables in range")
|
||||||
}
|
}
|
||||||
|
|
||||||
var v1, v2 *Node
|
var v1, v2 *Node
|
||||||
|
|
@ -117,7 +118,7 @@ func typecheckrangeExpr(n *Node) {
|
||||||
v1.Type = t1
|
v1.Type = t1
|
||||||
} else if v1.Type != nil {
|
} else if v1.Type != nil {
|
||||||
if op, why := assignop(t1, v1.Type); op == OXXX {
|
if op, why := assignop(t1, v1.Type); op == OXXX {
|
||||||
yyerrorl(n.Pos, "cannot assign type %v to %L in range%s", t1, v1, why)
|
base.ErrorfAt(n.Pos, "cannot assign type %v to %L in range%s", t1, v1, why)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checkassign(n, v1)
|
checkassign(n, v1)
|
||||||
|
|
@ -128,7 +129,7 @@ func typecheckrangeExpr(n *Node) {
|
||||||
v2.Type = t2
|
v2.Type = t2
|
||||||
} else if v2.Type != nil {
|
} else if v2.Type != nil {
|
||||||
if op, why := assignop(t2, v2.Type); op == OXXX {
|
if op, why := assignop(t2, v2.Type); op == OXXX {
|
||||||
yyerrorl(n.Pos, "cannot assign type %v to %L in range%s", t2, v2, why)
|
base.ErrorfAt(n.Pos, "cannot assign type %v to %L in range%s", t2, v2, why)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checkassign(n, v2)
|
checkassign(n, v2)
|
||||||
|
|
@ -160,7 +161,7 @@ func walkrange(n *Node) *Node {
|
||||||
m := n.Right
|
m := n.Right
|
||||||
lno := setlineno(m)
|
lno := setlineno(m)
|
||||||
n = mapClear(m)
|
n = mapClear(m)
|
||||||
lineno = lno
|
base.Pos = lno
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,7 +197,7 @@ func walkrange(n *Node) *Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
if v1 == nil && v2 != nil {
|
if v1 == nil && v2 != nil {
|
||||||
Fatalf("walkrange: v2 != nil while v1 == nil")
|
base.Fatalf("walkrange: v2 != nil while v1 == nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
// n.List has no meaning anymore, clear it
|
// n.List has no meaning anymore, clear it
|
||||||
|
|
@ -211,11 +212,11 @@ func walkrange(n *Node) *Node {
|
||||||
var init []*Node
|
var init []*Node
|
||||||
switch t.Etype {
|
switch t.Etype {
|
||||||
default:
|
default:
|
||||||
Fatalf("walkrange")
|
base.Fatalf("walkrange")
|
||||||
|
|
||||||
case TARRAY, TSLICE:
|
case TARRAY, TSLICE:
|
||||||
if arrayClear(n, v1, v2, a) {
|
if arrayClear(n, v1, v2, a) {
|
||||||
lineno = lno
|
base.Pos = lno
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -454,7 +455,7 @@ func walkrange(n *Node) *Node {
|
||||||
|
|
||||||
n = walkstmt(n)
|
n = walkstmt(n)
|
||||||
|
|
||||||
lineno = lno
|
base.Pos = lno
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -466,7 +467,7 @@ func walkrange(n *Node) *Node {
|
||||||
//
|
//
|
||||||
// where == for keys of map m is reflexive.
|
// where == for keys of map m is reflexive.
|
||||||
func isMapClear(n *Node) bool {
|
func isMapClear(n *Node) bool {
|
||||||
if Flag.N != 0 || instrumenting {
|
if base.Flag.N != 0 || instrumenting {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -533,7 +534,7 @@ func mapClear(m *Node) *Node {
|
||||||
//
|
//
|
||||||
// Parameters are as in walkrange: "for v1, v2 = range a".
|
// Parameters are as in walkrange: "for v1, v2 = range a".
|
||||||
func arrayClear(n, v1, v2, a *Node) bool {
|
func arrayClear(n, v1, v2, a *Node) bool {
|
||||||
if Flag.N != 0 || instrumenting {
|
if base.Flag.N != 0 || instrumenting {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/gcprog"
|
"cmd/internal/gcprog"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
|
|
@ -131,52 +132,52 @@ func bmap(t *types.Type) *types.Type {
|
||||||
|
|
||||||
// Check invariants that map code depends on.
|
// Check invariants that map code depends on.
|
||||||
if !IsComparable(t.Key()) {
|
if !IsComparable(t.Key()) {
|
||||||
Fatalf("unsupported map key type for %v", t)
|
base.Fatalf("unsupported map key type for %v", t)
|
||||||
}
|
}
|
||||||
if BUCKETSIZE < 8 {
|
if BUCKETSIZE < 8 {
|
||||||
Fatalf("bucket size too small for proper alignment")
|
base.Fatalf("bucket size too small for proper alignment")
|
||||||
}
|
}
|
||||||
if keytype.Align > BUCKETSIZE {
|
if keytype.Align > BUCKETSIZE {
|
||||||
Fatalf("key align too big for %v", t)
|
base.Fatalf("key align too big for %v", t)
|
||||||
}
|
}
|
||||||
if elemtype.Align > BUCKETSIZE {
|
if elemtype.Align > BUCKETSIZE {
|
||||||
Fatalf("elem align too big for %v", t)
|
base.Fatalf("elem align too big for %v", t)
|
||||||
}
|
}
|
||||||
if keytype.Width > MAXKEYSIZE {
|
if keytype.Width > MAXKEYSIZE {
|
||||||
Fatalf("key size to large for %v", t)
|
base.Fatalf("key size to large for %v", t)
|
||||||
}
|
}
|
||||||
if elemtype.Width > MAXELEMSIZE {
|
if elemtype.Width > MAXELEMSIZE {
|
||||||
Fatalf("elem size to large for %v", t)
|
base.Fatalf("elem size to large for %v", t)
|
||||||
}
|
}
|
||||||
if t.Key().Width > MAXKEYSIZE && !keytype.IsPtr() {
|
if t.Key().Width > MAXKEYSIZE && !keytype.IsPtr() {
|
||||||
Fatalf("key indirect incorrect for %v", t)
|
base.Fatalf("key indirect incorrect for %v", t)
|
||||||
}
|
}
|
||||||
if t.Elem().Width > MAXELEMSIZE && !elemtype.IsPtr() {
|
if t.Elem().Width > MAXELEMSIZE && !elemtype.IsPtr() {
|
||||||
Fatalf("elem indirect incorrect for %v", t)
|
base.Fatalf("elem indirect incorrect for %v", t)
|
||||||
}
|
}
|
||||||
if keytype.Width%int64(keytype.Align) != 0 {
|
if keytype.Width%int64(keytype.Align) != 0 {
|
||||||
Fatalf("key size not a multiple of key align for %v", t)
|
base.Fatalf("key size not a multiple of key align for %v", t)
|
||||||
}
|
}
|
||||||
if elemtype.Width%int64(elemtype.Align) != 0 {
|
if elemtype.Width%int64(elemtype.Align) != 0 {
|
||||||
Fatalf("elem size not a multiple of elem align for %v", t)
|
base.Fatalf("elem size not a multiple of elem align for %v", t)
|
||||||
}
|
}
|
||||||
if bucket.Align%keytype.Align != 0 {
|
if bucket.Align%keytype.Align != 0 {
|
||||||
Fatalf("bucket align not multiple of key align %v", t)
|
base.Fatalf("bucket align not multiple of key align %v", t)
|
||||||
}
|
}
|
||||||
if bucket.Align%elemtype.Align != 0 {
|
if bucket.Align%elemtype.Align != 0 {
|
||||||
Fatalf("bucket align not multiple of elem align %v", t)
|
base.Fatalf("bucket align not multiple of elem align %v", t)
|
||||||
}
|
}
|
||||||
if keys.Offset%int64(keytype.Align) != 0 {
|
if keys.Offset%int64(keytype.Align) != 0 {
|
||||||
Fatalf("bad alignment of keys in bmap for %v", t)
|
base.Fatalf("bad alignment of keys in bmap for %v", t)
|
||||||
}
|
}
|
||||||
if elems.Offset%int64(elemtype.Align) != 0 {
|
if elems.Offset%int64(elemtype.Align) != 0 {
|
||||||
Fatalf("bad alignment of elems in bmap for %v", t)
|
base.Fatalf("bad alignment of elems in bmap for %v", t)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Double-check that overflow field is final memory in struct,
|
// Double-check that overflow field is final memory in struct,
|
||||||
// with no padding at end.
|
// with no padding at end.
|
||||||
if overflow.Offset != bucket.Width-int64(Widthptr) {
|
if overflow.Offset != bucket.Width-int64(Widthptr) {
|
||||||
Fatalf("bad offset of overflow in bmap for %v", t)
|
base.Fatalf("bad offset of overflow in bmap for %v", t)
|
||||||
}
|
}
|
||||||
|
|
||||||
t.MapType().Bucket = bucket
|
t.MapType().Bucket = bucket
|
||||||
|
|
@ -227,7 +228,7 @@ func hmap(t *types.Type) *types.Type {
|
||||||
// The size of hmap should be 48 bytes on 64 bit
|
// The size of hmap should be 48 bytes on 64 bit
|
||||||
// and 28 bytes on 32 bit platforms.
|
// and 28 bytes on 32 bit platforms.
|
||||||
if size := int64(8 + 5*Widthptr); hmap.Width != size {
|
if size := int64(8 + 5*Widthptr); hmap.Width != size {
|
||||||
Fatalf("hmap size not correct: got %d, want %d", hmap.Width, size)
|
base.Fatalf("hmap size not correct: got %d, want %d", hmap.Width, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
t.MapType().Hmap = hmap
|
t.MapType().Hmap = hmap
|
||||||
|
|
@ -288,7 +289,7 @@ func hiter(t *types.Type) *types.Type {
|
||||||
hiter.SetFields(fields)
|
hiter.SetFields(fields)
|
||||||
dowidth(hiter)
|
dowidth(hiter)
|
||||||
if hiter.Width != int64(12*Widthptr) {
|
if hiter.Width != int64(12*Widthptr) {
|
||||||
Fatalf("hash_iter size not correct %d %d", hiter.Width, 12*Widthptr)
|
base.Fatalf("hash_iter size not correct %d %d", hiter.Width, 12*Widthptr)
|
||||||
}
|
}
|
||||||
t.MapType().Hiter = hiter
|
t.MapType().Hiter = hiter
|
||||||
hiter.StructType().Map = t
|
hiter.StructType().Map = t
|
||||||
|
|
@ -391,10 +392,10 @@ func methods(t *types.Type) []*Sig {
|
||||||
var ms []*Sig
|
var ms []*Sig
|
||||||
for _, f := range mt.AllMethods().Slice() {
|
for _, f := range mt.AllMethods().Slice() {
|
||||||
if !f.IsMethod() {
|
if !f.IsMethod() {
|
||||||
Fatalf("non-method on %v method %v %v\n", mt, f.Sym, f)
|
base.Fatalf("non-method on %v method %v %v\n", mt, f.Sym, f)
|
||||||
}
|
}
|
||||||
if f.Type.Recv() == nil {
|
if f.Type.Recv() == nil {
|
||||||
Fatalf("receiver with no type on %v method %v %v\n", mt, f.Sym, f)
|
base.Fatalf("receiver with no type on %v method %v %v\n", mt, f.Sym, f)
|
||||||
}
|
}
|
||||||
if f.Nointerface() {
|
if f.Nointerface() {
|
||||||
continue
|
continue
|
||||||
|
|
@ -450,12 +451,12 @@ func imethods(t *types.Type) []*Sig {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if f.Sym.IsBlank() {
|
if f.Sym.IsBlank() {
|
||||||
Fatalf("unexpected blank symbol in interface method set")
|
base.Fatalf("unexpected blank symbol in interface method set")
|
||||||
}
|
}
|
||||||
if n := len(methods); n > 0 {
|
if n := len(methods); n > 0 {
|
||||||
last := methods[n-1]
|
last := methods[n-1]
|
||||||
if !last.name.Less(f.Sym) {
|
if !last.name.Less(f.Sym) {
|
||||||
Fatalf("sigcmp vs sortinter %v %v", last.name, f.Sym)
|
base.Fatalf("sigcmp vs sortinter %v %v", last.name, f.Sym)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -488,17 +489,17 @@ func dimportpath(p *types.Pkg) {
|
||||||
// If we are compiling the runtime package, there are two runtime packages around
|
// If we are compiling the runtime package, there are two runtime packages around
|
||||||
// -- localpkg and Runtimepkg. We don't want to produce import path symbols for
|
// -- localpkg and Runtimepkg. We don't want to produce import path symbols for
|
||||||
// both of them, so just produce one for localpkg.
|
// both of them, so just produce one for localpkg.
|
||||||
if Ctxt.Pkgpath == "runtime" && p == Runtimepkg {
|
if base.Ctxt.Pkgpath == "runtime" && p == Runtimepkg {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
str := p.Path
|
str := p.Path
|
||||||
if p == localpkg {
|
if p == localpkg {
|
||||||
// Note: myimportpath != "", or else dgopkgpath won't call dimportpath.
|
// Note: myimportpath != "", or else dgopkgpath won't call dimportpath.
|
||||||
str = Ctxt.Pkgpath
|
str = base.Ctxt.Pkgpath
|
||||||
}
|
}
|
||||||
|
|
||||||
s := 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, str, "", nil, false)
|
||||||
ggloblsym(s, int32(ot), obj.DUPOK|obj.RODATA)
|
ggloblsym(s, int32(ot), obj.DUPOK|obj.RODATA)
|
||||||
s.Set(obj.AttrContentAddressable, true)
|
s.Set(obj.AttrContentAddressable, true)
|
||||||
|
|
@ -510,13 +511,13 @@ func dgopkgpath(s *obj.LSym, ot int, pkg *types.Pkg) int {
|
||||||
return duintptr(s, ot, 0)
|
return duintptr(s, ot, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if pkg == localpkg && Ctxt.Pkgpath == "" {
|
if pkg == localpkg && base.Ctxt.Pkgpath == "" {
|
||||||
// If we don't know the full import path of the package being compiled
|
// If we don't know the full import path of the package being compiled
|
||||||
// (i.e. -p was not passed on the compiler command line), emit a reference to
|
// (i.e. -p was not passed on the compiler command line), emit a reference to
|
||||||
// type..importpath.""., which the linker will rewrite using the correct import path.
|
// type..importpath.""., which the linker will rewrite using the correct import path.
|
||||||
// Every package that imports this one directly defines the symbol.
|
// Every package that imports this one directly defines the symbol.
|
||||||
// See also https://groups.google.com/forum/#!topic/golang-dev/myb9s53HxGQ.
|
// See also https://groups.google.com/forum/#!topic/golang-dev/myb9s53HxGQ.
|
||||||
ns := Ctxt.Lookup(`type..importpath."".`)
|
ns := base.Ctxt.Lookup(`type..importpath."".`)
|
||||||
return dsymptr(s, ot, ns, 0)
|
return dsymptr(s, ot, ns, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -529,13 +530,13 @@ func dgopkgpathOff(s *obj.LSym, ot int, pkg *types.Pkg) int {
|
||||||
if pkg == nil {
|
if pkg == nil {
|
||||||
return duint32(s, ot, 0)
|
return duint32(s, ot, 0)
|
||||||
}
|
}
|
||||||
if pkg == localpkg && Ctxt.Pkgpath == "" {
|
if pkg == localpkg && base.Ctxt.Pkgpath == "" {
|
||||||
// If we don't know the full import path of the package being compiled
|
// If we don't know the full import path of the package being compiled
|
||||||
// (i.e. -p was not passed on the compiler command line), emit a reference to
|
// (i.e. -p was not passed on the compiler command line), emit a reference to
|
||||||
// type..importpath.""., which the linker will rewrite using the correct import path.
|
// type..importpath.""., which the linker will rewrite using the correct import path.
|
||||||
// Every package that imports this one directly defines the symbol.
|
// Every package that imports this one directly defines the symbol.
|
||||||
// See also https://groups.google.com/forum/#!topic/golang-dev/myb9s53HxGQ.
|
// See also https://groups.google.com/forum/#!topic/golang-dev/myb9s53HxGQ.
|
||||||
ns := Ctxt.Lookup(`type..importpath."".`)
|
ns := base.Ctxt.Lookup(`type..importpath."".`)
|
||||||
return dsymptrOff(s, ot, ns)
|
return dsymptrOff(s, ot, ns)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -546,7 +547,7 @@ func dgopkgpathOff(s *obj.LSym, ot int, pkg *types.Pkg) int {
|
||||||
// dnameField dumps a reflect.name for a struct field.
|
// dnameField dumps a reflect.name for a struct field.
|
||||||
func dnameField(lsym *obj.LSym, ot int, spkg *types.Pkg, ft *types.Field) int {
|
func dnameField(lsym *obj.LSym, ot int, spkg *types.Pkg, ft *types.Field) int {
|
||||||
if !types.IsExported(ft.Sym.Name) && ft.Sym.Pkg != spkg {
|
if !types.IsExported(ft.Sym.Name) && ft.Sym.Pkg != spkg {
|
||||||
Fatalf("package mismatch for %v", ft.Sym)
|
base.Fatalf("package mismatch for %v", ft.Sym)
|
||||||
}
|
}
|
||||||
nsym := dname(ft.Sym.Name, ft.Note, nil, types.IsExported(ft.Sym.Name))
|
nsym := dname(ft.Sym.Name, ft.Note, nil, types.IsExported(ft.Sym.Name))
|
||||||
return dsymptr(lsym, ot, nsym, 0)
|
return dsymptr(lsym, ot, nsym, 0)
|
||||||
|
|
@ -555,10 +556,10 @@ func dnameField(lsym *obj.LSym, ot int, spkg *types.Pkg, ft *types.Field) int {
|
||||||
// dnameData writes the contents of a reflect.name into s at offset ot.
|
// dnameData writes the contents of a reflect.name into s at offset ot.
|
||||||
func dnameData(s *obj.LSym, ot int, name, tag string, pkg *types.Pkg, exported bool) int {
|
func dnameData(s *obj.LSym, ot int, name, tag string, pkg *types.Pkg, exported bool) int {
|
||||||
if len(name) > 1<<16-1 {
|
if len(name) > 1<<16-1 {
|
||||||
Fatalf("name too long: %s", name)
|
base.Fatalf("name too long: %s", name)
|
||||||
}
|
}
|
||||||
if len(tag) > 1<<16-1 {
|
if len(tag) > 1<<16-1 {
|
||||||
Fatalf("tag too long: %s", tag)
|
base.Fatalf("tag too long: %s", tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode name and tag. See reflect/type.go for details.
|
// Encode name and tag. See reflect/type.go for details.
|
||||||
|
|
@ -586,7 +587,7 @@ func dnameData(s *obj.LSym, ot int, name, tag string, pkg *types.Pkg, exported b
|
||||||
copy(tb[2:], tag)
|
copy(tb[2:], tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
ot = int(s.WriteBytes(Ctxt, int64(ot), b))
|
ot = int(s.WriteBytes(base.Ctxt, int64(ot), b))
|
||||||
|
|
||||||
if pkg != nil {
|
if pkg != nil {
|
||||||
ot = dgopkgpathOff(s, ot, pkg)
|
ot = dgopkgpathOff(s, ot, pkg)
|
||||||
|
|
@ -623,7 +624,7 @@ func dname(name, tag string, pkg *types.Pkg, exported bool) *obj.LSym {
|
||||||
sname = fmt.Sprintf(`%s"".%d`, sname, dnameCount)
|
sname = fmt.Sprintf(`%s"".%d`, sname, dnameCount)
|
||||||
dnameCount++
|
dnameCount++
|
||||||
}
|
}
|
||||||
s := Ctxt.Lookup(sname)
|
s := base.Ctxt.Lookup(sname)
|
||||||
if len(s.P) > 0 {
|
if len(s.P) > 0 {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
@ -643,7 +644,7 @@ func dextratype(lsym *obj.LSym, ot int, t *types.Type, dataAdd int) int {
|
||||||
}
|
}
|
||||||
noff := int(Rnd(int64(ot), int64(Widthptr)))
|
noff := int(Rnd(int64(ot), int64(Widthptr)))
|
||||||
if noff != ot {
|
if noff != ot {
|
||||||
Fatalf("unexpected alignment in dextratype for %v", t)
|
base.Fatalf("unexpected alignment in dextratype for %v", t)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, a := range m {
|
for _, a := range m {
|
||||||
|
|
@ -655,11 +656,11 @@ func dextratype(lsym *obj.LSym, ot int, t *types.Type, dataAdd int) int {
|
||||||
dataAdd += uncommonSize(t)
|
dataAdd += uncommonSize(t)
|
||||||
mcount := len(m)
|
mcount := len(m)
|
||||||
if mcount != int(uint16(mcount)) {
|
if mcount != int(uint16(mcount)) {
|
||||||
Fatalf("too many methods on %v: %d", t, mcount)
|
base.Fatalf("too many methods on %v: %d", t, mcount)
|
||||||
}
|
}
|
||||||
xcount := sort.Search(mcount, func(i int) bool { return !types.IsExported(m[i].name.Name) })
|
xcount := sort.Search(mcount, func(i int) bool { return !types.IsExported(m[i].name.Name) })
|
||||||
if dataAdd != int(uint32(dataAdd)) {
|
if dataAdd != int(uint32(dataAdd)) {
|
||||||
Fatalf("methods are too far away on %v: %d", t, dataAdd)
|
base.Fatalf("methods are too far away on %v: %d", t, dataAdd)
|
||||||
}
|
}
|
||||||
|
|
||||||
ot = duint16(lsym, ot, uint16(mcount))
|
ot = duint16(lsym, ot, uint16(mcount))
|
||||||
|
|
@ -788,7 +789,7 @@ func typeptrdata(t *types.Type) int64 {
|
||||||
return lastPtrField.Offset + typeptrdata(lastPtrField.Type)
|
return lastPtrField.Offset + typeptrdata(lastPtrField.Type)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Fatalf("typeptrdata: unexpected type, %v", t)
|
base.Fatalf("typeptrdata: unexpected type, %v", t)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -888,7 +889,7 @@ func dcommontype(lsym *obj.LSym, t *types.Type) int {
|
||||||
i = 1
|
i = 1
|
||||||
}
|
}
|
||||||
if i&(i-1) != 0 {
|
if i&(i-1) != 0 {
|
||||||
Fatalf("invalid alignment %d for %v", t.Align, t)
|
base.Fatalf("invalid alignment %d for %v", t.Align, t)
|
||||||
}
|
}
|
||||||
ot = duint8(lsym, ot, t.Align) // align
|
ot = duint8(lsym, ot, t.Align) // align
|
||||||
ot = duint8(lsym, ot, t.Align) // fieldAlign
|
ot = duint8(lsym, ot, t.Align) // fieldAlign
|
||||||
|
|
@ -979,7 +980,7 @@ func typesymprefix(prefix string, t *types.Type) *types.Sym {
|
||||||
|
|
||||||
func typenamesym(t *types.Type) *types.Sym {
|
func typenamesym(t *types.Type) *types.Sym {
|
||||||
if t == nil || (t.IsPtr() && t.Elem() == nil) || t.IsUntyped() {
|
if t == nil || (t.IsPtr() && t.Elem() == nil) || t.IsUntyped() {
|
||||||
Fatalf("typenamesym %v", t)
|
base.Fatalf("typenamesym %v", t)
|
||||||
}
|
}
|
||||||
s := typesym(t)
|
s := typesym(t)
|
||||||
signatmu.Lock()
|
signatmu.Lock()
|
||||||
|
|
@ -1006,7 +1007,7 @@ func typename(t *types.Type) *Node {
|
||||||
|
|
||||||
func itabname(t, itype *types.Type) *Node {
|
func itabname(t, itype *types.Type) *Node {
|
||||||
if t == nil || (t.IsPtr() && t.Elem() == nil) || t.IsUntyped() || !itype.IsInterface() || itype.IsEmptyInterface() {
|
if t == nil || (t.IsPtr() && t.Elem() == nil) || t.IsUntyped() || !itype.IsInterface() || itype.IsEmptyInterface() {
|
||||||
Fatalf("itabname(%v, %v)", t, itype)
|
base.Fatalf("itabname(%v, %v)", t, itype)
|
||||||
}
|
}
|
||||||
s := itabpkg.Lookup(t.ShortString() + "," + itype.ShortString())
|
s := itabpkg.Lookup(t.ShortString() + "," + itype.ShortString())
|
||||||
if s.Def == nil {
|
if s.Def == nil {
|
||||||
|
|
@ -1065,7 +1066,7 @@ func isreflexive(t *types.Type) bool {
|
||||||
return true
|
return true
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Fatalf("bad type for map key: %v", t)
|
base.Fatalf("bad type for map key: %v", t)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1095,7 +1096,7 @@ func needkeyupdate(t *types.Type) bool {
|
||||||
return false
|
return false
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Fatalf("bad type for map key: %v", t)
|
base.Fatalf("bad type for map key: %v", t)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1135,7 +1136,7 @@ func formalType(t *types.Type) *types.Type {
|
||||||
func dtypesym(t *types.Type) *obj.LSym {
|
func dtypesym(t *types.Type) *obj.LSym {
|
||||||
t = formalType(t)
|
t = formalType(t)
|
||||||
if t.IsUntyped() {
|
if t.IsUntyped() {
|
||||||
Fatalf("dtypesym %v", t)
|
base.Fatalf("dtypesym %v", t)
|
||||||
}
|
}
|
||||||
|
|
||||||
s := typesym(t)
|
s := typesym(t)
|
||||||
|
|
@ -1158,7 +1159,7 @@ func dtypesym(t *types.Type) *obj.LSym {
|
||||||
dupok = obj.DUPOK
|
dupok = obj.DUPOK
|
||||||
}
|
}
|
||||||
|
|
||||||
if Ctxt.Pkgpath != "runtime" || (tbase != types.Types[tbase.Etype] && tbase != types.Bytetype && tbase != types.Runetype && tbase != types.Errortype) { // int, float, etc
|
if base.Ctxt.Pkgpath != "runtime" || (tbase != types.Types[tbase.Etype] && tbase != types.Bytetype && tbase != types.Runetype && tbase != types.Errortype) { // int, float, etc
|
||||||
// named types from other files are defined only by those files
|
// named types from other files are defined only by those files
|
||||||
if tbase.Sym != nil && tbase.Sym.Pkg != localpkg {
|
if tbase.Sym != nil && tbase.Sym.Pkg != localpkg {
|
||||||
if i, ok := typeSymIdx[tbase]; ok {
|
if i, ok := typeSymIdx[tbase]; ok {
|
||||||
|
|
@ -1377,7 +1378,7 @@ func dtypesym(t *types.Type) *obj.LSym {
|
||||||
ot = dsymptr(lsym, ot, dtypesym(f.Type), 0)
|
ot = dsymptr(lsym, ot, dtypesym(f.Type), 0)
|
||||||
offsetAnon := uint64(f.Offset) << 1
|
offsetAnon := uint64(f.Offset) << 1
|
||||||
if offsetAnon>>1 != uint64(f.Offset) {
|
if offsetAnon>>1 != uint64(f.Offset) {
|
||||||
Fatalf("%v: bad field offset for %s", t, f.Sym.Name)
|
base.Fatalf("%v: bad field offset for %s", t, f.Sym.Name)
|
||||||
}
|
}
|
||||||
if f.Embedded != 0 {
|
if f.Embedded != 0 {
|
||||||
offsetAnon |= 1
|
offsetAnon |= 1
|
||||||
|
|
@ -1394,7 +1395,7 @@ func dtypesym(t *types.Type) *obj.LSym {
|
||||||
//
|
//
|
||||||
// When buildmode=shared, all types are in typelinks so the
|
// When buildmode=shared, all types are in typelinks so the
|
||||||
// runtime can deduplicate type pointers.
|
// runtime can deduplicate type pointers.
|
||||||
keep := Ctxt.Flag_dynlink
|
keep := base.Ctxt.Flag_dynlink
|
||||||
if !keep && t.Sym == nil {
|
if !keep && t.Sym == nil {
|
||||||
// For an unnamed type, we only need the link if the type can
|
// For an unnamed type, we only need the link if the type can
|
||||||
// be created at run time by reflect.PtrTo and similar
|
// be created at run time by reflect.PtrTo and similar
|
||||||
|
|
@ -1471,7 +1472,7 @@ func genfun(t, it *types.Type) []*obj.LSym {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(sigs) != 0 {
|
if len(sigs) != 0 {
|
||||||
Fatalf("incomplete itab")
|
base.Fatalf("incomplete itab")
|
||||||
}
|
}
|
||||||
|
|
||||||
return out
|
return out
|
||||||
|
|
@ -1572,7 +1573,7 @@ func dumptabs() {
|
||||||
// process ptabs
|
// process ptabs
|
||||||
if localpkg.Name == "main" && len(ptabs) > 0 {
|
if localpkg.Name == "main" && len(ptabs) > 0 {
|
||||||
ot := 0
|
ot := 0
|
||||||
s := Ctxt.Lookup("go.plugin.tabs")
|
s := base.Ctxt.Lookup("go.plugin.tabs")
|
||||||
for _, p := range ptabs {
|
for _, p := range ptabs {
|
||||||
// Dump ptab symbol into go.pluginsym package.
|
// Dump ptab symbol into go.pluginsym package.
|
||||||
//
|
//
|
||||||
|
|
@ -1591,7 +1592,7 @@ func dumptabs() {
|
||||||
ggloblsym(s, int32(ot), int16(obj.RODATA))
|
ggloblsym(s, int32(ot), int16(obj.RODATA))
|
||||||
|
|
||||||
ot = 0
|
ot = 0
|
||||||
s = Ctxt.Lookup("go.plugin.exports")
|
s = base.Ctxt.Lookup("go.plugin.exports")
|
||||||
for _, p := range ptabs {
|
for _, p := range ptabs {
|
||||||
ot = dsymptr(s, ot, p.s.Linksym(), 0)
|
ot = dsymptr(s, ot, p.s.Linksym(), 0)
|
||||||
}
|
}
|
||||||
|
|
@ -1613,7 +1614,7 @@ func dumpbasictypes() {
|
||||||
// so this is as good as any.
|
// so this is as good as any.
|
||||||
// another possible choice would be package main,
|
// another possible choice would be package main,
|
||||||
// but using runtime means fewer copies in object files.
|
// but using runtime means fewer copies in object files.
|
||||||
if Ctxt.Pkgpath == "runtime" {
|
if base.Ctxt.Pkgpath == "runtime" {
|
||||||
for i := types.EType(1); i <= TBOOL; i++ {
|
for i := types.EType(1); i <= TBOOL; i++ {
|
||||||
dtypesym(types.NewPtr(types.Types[i]))
|
dtypesym(types.NewPtr(types.Types[i]))
|
||||||
}
|
}
|
||||||
|
|
@ -1629,10 +1630,10 @@ func dumpbasictypes() {
|
||||||
// add paths for runtime and main, which 6l imports implicitly.
|
// add paths for runtime and main, which 6l imports implicitly.
|
||||||
dimportpath(Runtimepkg)
|
dimportpath(Runtimepkg)
|
||||||
|
|
||||||
if Flag.Race {
|
if base.Flag.Race {
|
||||||
dimportpath(racepkg)
|
dimportpath(racepkg)
|
||||||
}
|
}
|
||||||
if Flag.MSan {
|
if base.Flag.MSan {
|
||||||
dimportpath(msanpkg)
|
dimportpath(msanpkg)
|
||||||
}
|
}
|
||||||
dimportpath(types.NewPkg("main", ""))
|
dimportpath(types.NewPkg("main", ""))
|
||||||
|
|
@ -1767,7 +1768,7 @@ func fillptrmask(t *types.Type, ptrmask []byte) {
|
||||||
func dgcprog(t *types.Type) (*obj.LSym, int64) {
|
func dgcprog(t *types.Type) (*obj.LSym, int64) {
|
||||||
dowidth(t)
|
dowidth(t)
|
||||||
if t.Width == BADWIDTH {
|
if t.Width == BADWIDTH {
|
||||||
Fatalf("dgcprog: %v badwidth", t)
|
base.Fatalf("dgcprog: %v badwidth", t)
|
||||||
}
|
}
|
||||||
lsym := typesymprefix(".gcprog", t).Linksym()
|
lsym := typesymprefix(".gcprog", t).Linksym()
|
||||||
var p GCProg
|
var p GCProg
|
||||||
|
|
@ -1776,7 +1777,7 @@ func dgcprog(t *types.Type) (*obj.LSym, int64) {
|
||||||
offset := p.w.BitIndex() * int64(Widthptr)
|
offset := p.w.BitIndex() * int64(Widthptr)
|
||||||
p.end()
|
p.end()
|
||||||
if ptrdata := typeptrdata(t); offset < ptrdata || offset > t.Width {
|
if ptrdata := typeptrdata(t); offset < ptrdata || offset > t.Width {
|
||||||
Fatalf("dgcprog: %v: offset=%d but ptrdata=%d size=%d", t, offset, ptrdata, t.Width)
|
base.Fatalf("dgcprog: %v: offset=%d but ptrdata=%d size=%d", t, offset, ptrdata, t.Width)
|
||||||
}
|
}
|
||||||
return lsym, offset
|
return lsym, offset
|
||||||
}
|
}
|
||||||
|
|
@ -1791,7 +1792,7 @@ func (p *GCProg) init(lsym *obj.LSym) {
|
||||||
p.lsym = lsym
|
p.lsym = lsym
|
||||||
p.symoff = 4 // first 4 bytes hold program length
|
p.symoff = 4 // first 4 bytes hold program length
|
||||||
p.w.Init(p.writeByte)
|
p.w.Init(p.writeByte)
|
||||||
if Debug.GCProg > 0 {
|
if base.Debug.GCProg > 0 {
|
||||||
fmt.Fprintf(os.Stderr, "compile: start GCProg for %v\n", lsym)
|
fmt.Fprintf(os.Stderr, "compile: start GCProg for %v\n", lsym)
|
||||||
p.w.Debug(os.Stderr)
|
p.w.Debug(os.Stderr)
|
||||||
}
|
}
|
||||||
|
|
@ -1805,7 +1806,7 @@ func (p *GCProg) end() {
|
||||||
p.w.End()
|
p.w.End()
|
||||||
duint32(p.lsym, 0, uint32(p.symoff-4))
|
duint32(p.lsym, 0, uint32(p.symoff-4))
|
||||||
ggloblsym(p.lsym, int32(p.symoff), obj.DUPOK|obj.RODATA|obj.LOCAL)
|
ggloblsym(p.lsym, int32(p.symoff), obj.DUPOK|obj.RODATA|obj.LOCAL)
|
||||||
if Debug.GCProg > 0 {
|
if base.Debug.GCProg > 0 {
|
||||||
fmt.Fprintf(os.Stderr, "compile: end GCProg for %v\n", p.lsym)
|
fmt.Fprintf(os.Stderr, "compile: end GCProg for %v\n", p.lsym)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1821,7 +1822,7 @@ func (p *GCProg) emit(t *types.Type, offset int64) {
|
||||||
}
|
}
|
||||||
switch t.Etype {
|
switch t.Etype {
|
||||||
default:
|
default:
|
||||||
Fatalf("GCProg.emit: unexpected type %v", t)
|
base.Fatalf("GCProg.emit: unexpected type %v", t)
|
||||||
|
|
||||||
case TSTRING:
|
case TSTRING:
|
||||||
p.w.Ptr(offset / int64(Widthptr))
|
p.w.Ptr(offset / int64(Widthptr))
|
||||||
|
|
@ -1836,7 +1837,7 @@ func (p *GCProg) emit(t *types.Type, offset int64) {
|
||||||
case TARRAY:
|
case TARRAY:
|
||||||
if t.NumElem() == 0 {
|
if t.NumElem() == 0 {
|
||||||
// should have been handled by haspointers check above
|
// should have been handled by haspointers check above
|
||||||
Fatalf("GCProg.emit: empty array")
|
base.Fatalf("GCProg.emit: empty array")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flatten array-of-array-of-array to just a big array by multiplying counts.
|
// Flatten array-of-array-of-array to just a big array by multiplying counts.
|
||||||
|
|
@ -1869,7 +1870,7 @@ func (p *GCProg) emit(t *types.Type, offset int64) {
|
||||||
// size bytes of zeros.
|
// size bytes of zeros.
|
||||||
func zeroaddr(size int64) *Node {
|
func zeroaddr(size int64) *Node {
|
||||||
if size >= 1<<31 {
|
if size >= 1<<31 {
|
||||||
Fatalf("map elem too big %d", size)
|
base.Fatalf("map elem too big %d", size)
|
||||||
}
|
}
|
||||||
if zerosize < size {
|
if zerosize < size {
|
||||||
zerosize = size
|
zerosize = size
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/internal/dwarf"
|
"cmd/internal/dwarf"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
"cmd/internal/src"
|
"cmd/internal/src"
|
||||||
|
|
@ -13,7 +14,7 @@ import (
|
||||||
|
|
||||||
// See golang.org/issue/20390.
|
// See golang.org/issue/20390.
|
||||||
func xposBefore(p, q src.XPos) bool {
|
func xposBefore(p, q src.XPos) bool {
|
||||||
return Ctxt.PosTable.Pos(p).Before(Ctxt.PosTable.Pos(q))
|
return base.Ctxt.PosTable.Pos(p).Before(base.Ctxt.PosTable.Pos(q))
|
||||||
}
|
}
|
||||||
|
|
||||||
func findScope(marks []Mark, pos src.XPos) ScopeID {
|
func findScope(marks []Mark, pos src.XPos) ScopeID {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,10 @@
|
||||||
|
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import "cmd/compile/internal/types"
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
|
"cmd/compile/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
// select
|
// select
|
||||||
func typecheckselect(sel *Node) {
|
func typecheckselect(sel *Node) {
|
||||||
|
|
@ -14,18 +17,18 @@ func typecheckselect(sel *Node) {
|
||||||
for _, ncase := range sel.List.Slice() {
|
for _, ncase := range sel.List.Slice() {
|
||||||
if ncase.Op != OCASE {
|
if ncase.Op != OCASE {
|
||||||
setlineno(ncase)
|
setlineno(ncase)
|
||||||
Fatalf("typecheckselect %v", ncase.Op)
|
base.Fatalf("typecheckselect %v", ncase.Op)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ncase.List.Len() == 0 {
|
if ncase.List.Len() == 0 {
|
||||||
// default
|
// default
|
||||||
if def != nil {
|
if def != nil {
|
||||||
yyerrorl(ncase.Pos, "multiple defaults in select (first at %v)", def.Line())
|
base.ErrorfAt(ncase.Pos, "multiple defaults in select (first at %v)", def.Line())
|
||||||
} else {
|
} else {
|
||||||
def = ncase
|
def = ncase
|
||||||
}
|
}
|
||||||
} else if ncase.List.Len() > 1 {
|
} else if ncase.List.Len() > 1 {
|
||||||
yyerrorl(ncase.Pos, "select cases cannot be lists")
|
base.ErrorfAt(ncase.Pos, "select cases cannot be lists")
|
||||||
} else {
|
} else {
|
||||||
ncase.List.SetFirst(typecheck(ncase.List.First(), ctxStmt))
|
ncase.List.SetFirst(typecheck(ncase.List.First(), ctxStmt))
|
||||||
n := ncase.List.First()
|
n := ncase.List.First()
|
||||||
|
|
@ -41,7 +44,7 @@ func typecheckselect(sel *Node) {
|
||||||
// on the same line). This matches the approach before 1.10.
|
// on the same line). This matches the approach before 1.10.
|
||||||
pos = ncase.Pos
|
pos = ncase.Pos
|
||||||
}
|
}
|
||||||
yyerrorl(pos, "select case must be receive, send or assign recv")
|
base.ErrorfAt(pos, "select case must be receive, send or assign recv")
|
||||||
|
|
||||||
// convert x = <-c into OSELRECV(x, <-c).
|
// convert x = <-c into OSELRECV(x, <-c).
|
||||||
// remove implicit conversions; the eventual assignment
|
// remove implicit conversions; the eventual assignment
|
||||||
|
|
@ -52,7 +55,7 @@ func typecheckselect(sel *Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Right.Op != ORECV {
|
if n.Right.Op != ORECV {
|
||||||
yyerrorl(n.Pos, "select assignment must have receive on right hand side")
|
base.ErrorfAt(n.Pos, "select assignment must have receive on right hand side")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,7 +64,7 @@ func typecheckselect(sel *Node) {
|
||||||
// convert x, ok = <-c into OSELRECV2(x, <-c) with ntest=ok
|
// convert x, ok = <-c into OSELRECV2(x, <-c) with ntest=ok
|
||||||
case OAS2RECV:
|
case OAS2RECV:
|
||||||
if n.Right.Op != ORECV {
|
if n.Right.Op != ORECV {
|
||||||
yyerrorl(n.Pos, "select assignment must have receive on right hand side")
|
base.ErrorfAt(n.Pos, "select assignment must have receive on right hand side")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -84,13 +87,13 @@ func typecheckselect(sel *Node) {
|
||||||
typecheckslice(ncase.Nbody.Slice(), ctxStmt)
|
typecheckslice(ncase.Nbody.Slice(), ctxStmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
lineno = lno
|
base.Pos = lno
|
||||||
}
|
}
|
||||||
|
|
||||||
func walkselect(sel *Node) {
|
func walkselect(sel *Node) {
|
||||||
lno := setlineno(sel)
|
lno := setlineno(sel)
|
||||||
if sel.Nbody.Len() != 0 {
|
if sel.Nbody.Len() != 0 {
|
||||||
Fatalf("double walkselect")
|
base.Fatalf("double walkselect")
|
||||||
}
|
}
|
||||||
|
|
||||||
init := sel.Ninit.Slice()
|
init := sel.Ninit.Slice()
|
||||||
|
|
@ -102,12 +105,12 @@ func walkselect(sel *Node) {
|
||||||
sel.Nbody.Set(init)
|
sel.Nbody.Set(init)
|
||||||
walkstmtlist(sel.Nbody.Slice())
|
walkstmtlist(sel.Nbody.Slice())
|
||||||
|
|
||||||
lineno = lno
|
base.Pos = lno
|
||||||
}
|
}
|
||||||
|
|
||||||
func walkselectcases(cases *Nodes) []*Node {
|
func walkselectcases(cases *Nodes) []*Node {
|
||||||
ncas := cases.Len()
|
ncas := cases.Len()
|
||||||
sellineno := lineno
|
sellineno := base.Pos
|
||||||
|
|
||||||
// optimization: zero-case select
|
// optimization: zero-case select
|
||||||
if ncas == 0 {
|
if ncas == 0 {
|
||||||
|
|
@ -125,7 +128,7 @@ func walkselectcases(cases *Nodes) []*Node {
|
||||||
n.Ninit.Set(nil)
|
n.Ninit.Set(nil)
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
default:
|
default:
|
||||||
Fatalf("select %v", n.Op)
|
base.Fatalf("select %v", n.Op)
|
||||||
|
|
||||||
case OSEND:
|
case OSEND:
|
||||||
// already ok
|
// already ok
|
||||||
|
|
@ -202,7 +205,7 @@ func walkselectcases(cases *Nodes) []*Node {
|
||||||
r.Ninit.Set(cas.Ninit.Slice())
|
r.Ninit.Set(cas.Ninit.Slice())
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
default:
|
default:
|
||||||
Fatalf("select %v", n.Op)
|
base.Fatalf("select %v", n.Op)
|
||||||
|
|
||||||
case OSEND:
|
case OSEND:
|
||||||
// if selectnbsend(c, v) { body } else { default body }
|
// if selectnbsend(c, v) { body } else { default body }
|
||||||
|
|
@ -245,7 +248,7 @@ func walkselectcases(cases *Nodes) []*Node {
|
||||||
var init []*Node
|
var init []*Node
|
||||||
|
|
||||||
// generate sel-struct
|
// generate sel-struct
|
||||||
lineno = sellineno
|
base.Pos = sellineno
|
||||||
selv := temp(types.NewArray(scasetype(), int64(ncas)))
|
selv := temp(types.NewArray(scasetype(), int64(ncas)))
|
||||||
r := nod(OAS, selv, nil)
|
r := nod(OAS, selv, nil)
|
||||||
r = typecheck(r, ctxStmt)
|
r = typecheck(r, ctxStmt)
|
||||||
|
|
@ -255,7 +258,7 @@ func walkselectcases(cases *Nodes) []*Node {
|
||||||
order := temp(types.NewArray(types.Types[TUINT16], 2*int64(ncas)))
|
order := temp(types.NewArray(types.Types[TUINT16], 2*int64(ncas)))
|
||||||
|
|
||||||
var pc0, pcs *Node
|
var pc0, pcs *Node
|
||||||
if Flag.Race {
|
if base.Flag.Race {
|
||||||
pcs = temp(types.NewArray(types.Types[TUINTPTR], int64(ncas)))
|
pcs = temp(types.NewArray(types.Types[TUINTPTR], int64(ncas)))
|
||||||
pc0 = typecheck(nod(OADDR, nod(OINDEX, pcs, nodintconst(0)), nil), ctxExpr)
|
pc0 = typecheck(nod(OADDR, nod(OINDEX, pcs, nodintconst(0)), nil), ctxExpr)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -278,7 +281,7 @@ func walkselectcases(cases *Nodes) []*Node {
|
||||||
var c, elem *Node
|
var c, elem *Node
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
default:
|
default:
|
||||||
Fatalf("select %v", n.Op)
|
base.Fatalf("select %v", n.Op)
|
||||||
case OSEND:
|
case OSEND:
|
||||||
i = nsends
|
i = nsends
|
||||||
nsends++
|
nsends++
|
||||||
|
|
@ -308,17 +311,17 @@ func walkselectcases(cases *Nodes) []*Node {
|
||||||
|
|
||||||
// TODO(mdempsky): There should be a cleaner way to
|
// TODO(mdempsky): There should be a cleaner way to
|
||||||
// handle this.
|
// handle this.
|
||||||
if Flag.Race {
|
if base.Flag.Race {
|
||||||
r = mkcall("selectsetpc", nil, nil, nod(OADDR, nod(OINDEX, pcs, nodintconst(int64(i))), nil))
|
r = mkcall("selectsetpc", nil, nil, nod(OADDR, nod(OINDEX, pcs, nodintconst(int64(i))), nil))
|
||||||
init = append(init, r)
|
init = append(init, r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if nsends+nrecvs != ncas {
|
if nsends+nrecvs != ncas {
|
||||||
Fatalf("walkselectcases: miscount: %v + %v != %v", nsends, nrecvs, ncas)
|
base.Fatalf("walkselectcases: miscount: %v + %v != %v", nsends, nrecvs, ncas)
|
||||||
}
|
}
|
||||||
|
|
||||||
// run the select
|
// run the select
|
||||||
lineno = sellineno
|
base.Pos = sellineno
|
||||||
chosen := temp(types.Types[TINT])
|
chosen := temp(types.Types[TINT])
|
||||||
recvOK := temp(types.Types[TBOOL])
|
recvOK := temp(types.Types[TBOOL])
|
||||||
r = nod(OAS2, nil, nil)
|
r = nod(OAS2, nil, nil)
|
||||||
|
|
@ -331,7 +334,7 @@ func walkselectcases(cases *Nodes) []*Node {
|
||||||
// selv and order are no longer alive after selectgo.
|
// selv and order are no longer alive after selectgo.
|
||||||
init = append(init, nod(OVARKILL, selv, nil))
|
init = append(init, nod(OVARKILL, selv, nil))
|
||||||
init = append(init, nod(OVARKILL, order, nil))
|
init = append(init, nod(OVARKILL, order, nil))
|
||||||
if Flag.Race {
|
if base.Flag.Race {
|
||||||
init = append(init, nod(OVARKILL, pcs, nil))
|
init = append(init, nod(OVARKILL, pcs, nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
@ -40,7 +41,7 @@ func (s *InitSchedule) append(n *Node) {
|
||||||
// staticInit adds an initialization statement n to the schedule.
|
// staticInit adds an initialization statement n to the schedule.
|
||||||
func (s *InitSchedule) staticInit(n *Node) {
|
func (s *InitSchedule) staticInit(n *Node) {
|
||||||
if !s.tryStaticInit(n) {
|
if !s.tryStaticInit(n) {
|
||||||
if Flag.Percent != 0 {
|
if base.Flag.Percent != 0 {
|
||||||
Dump("nonstatic", n)
|
Dump("nonstatic", n)
|
||||||
}
|
}
|
||||||
s.append(n)
|
s.append(n)
|
||||||
|
|
@ -62,7 +63,7 @@ func (s *InitSchedule) tryStaticInit(n *Node) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
lno := setlineno(n)
|
lno := setlineno(n)
|
||||||
defer func() { lineno = lno }()
|
defer func() { base.Pos = lno }()
|
||||||
return s.staticassign(n.Left, n.Right)
|
return s.staticassign(n.Left, n.Right)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -256,8 +257,8 @@ func (s *InitSchedule) staticassign(l *Node, r *Node) bool {
|
||||||
|
|
||||||
case OCLOSURE:
|
case OCLOSURE:
|
||||||
if hasemptycvars(r) {
|
if hasemptycvars(r) {
|
||||||
if Debug.Closure > 0 {
|
if base.Debug.Closure > 0 {
|
||||||
Warnl(r.Pos, "closure converted to global")
|
base.WarnfAt(r.Pos, "closure converted to global")
|
||||||
}
|
}
|
||||||
// Closures with no captured variables are globals,
|
// Closures with no captured variables are globals,
|
||||||
// so the assignment can be done at link time.
|
// so the assignment can be done at link time.
|
||||||
|
|
@ -462,7 +463,7 @@ func isStaticCompositeLiteral(n *Node) bool {
|
||||||
case OSTRUCTLIT:
|
case OSTRUCTLIT:
|
||||||
for _, r := range n.List.Slice() {
|
for _, r := range n.List.Slice() {
|
||||||
if r.Op != OSTRUCTKEY {
|
if r.Op != OSTRUCTKEY {
|
||||||
Fatalf("isStaticCompositeLiteral: rhs not OSTRUCTKEY: %v", r)
|
base.Fatalf("isStaticCompositeLiteral: rhs not OSTRUCTKEY: %v", r)
|
||||||
}
|
}
|
||||||
if !isStaticCompositeLiteral(r.Left) {
|
if !isStaticCompositeLiteral(r.Left) {
|
||||||
return false
|
return false
|
||||||
|
|
@ -517,7 +518,7 @@ func fixedlit(ctxt initContext, kind initKind, n *Node, var_ *Node, init *Nodes)
|
||||||
if r.Op == OKEY {
|
if r.Op == OKEY {
|
||||||
k = indexconst(r.Left)
|
k = indexconst(r.Left)
|
||||||
if k < 0 {
|
if k < 0 {
|
||||||
Fatalf("fixedlit: invalid index %v", r.Left)
|
base.Fatalf("fixedlit: invalid index %v", r.Left)
|
||||||
}
|
}
|
||||||
r = r.Right
|
r = r.Right
|
||||||
}
|
}
|
||||||
|
|
@ -531,7 +532,7 @@ func fixedlit(ctxt initContext, kind initKind, n *Node, var_ *Node, init *Nodes)
|
||||||
case OSTRUCTLIT:
|
case OSTRUCTLIT:
|
||||||
splitnode = func(r *Node) (*Node, *Node) {
|
splitnode = func(r *Node) (*Node, *Node) {
|
||||||
if r.Op != OSTRUCTKEY {
|
if r.Op != OSTRUCTKEY {
|
||||||
Fatalf("fixedlit: rhs not OSTRUCTKEY: %v", r)
|
base.Fatalf("fixedlit: rhs not OSTRUCTKEY: %v", r)
|
||||||
}
|
}
|
||||||
if r.Sym.IsBlank() || isBlank {
|
if r.Sym.IsBlank() || isBlank {
|
||||||
return nblank, r.Left
|
return nblank, r.Left
|
||||||
|
|
@ -540,7 +541,7 @@ func fixedlit(ctxt initContext, kind initKind, n *Node, var_ *Node, init *Nodes)
|
||||||
return nodSym(ODOT, var_, r.Sym), r.Left
|
return nodSym(ODOT, var_, r.Sym), r.Left
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
Fatalf("fixedlit bad op: %v", n.Op)
|
base.Fatalf("fixedlit bad op: %v", n.Op)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, r := range n.List.Slice() {
|
for _, r := range n.List.Slice() {
|
||||||
|
|
@ -578,7 +579,7 @@ func fixedlit(ctxt initContext, kind initKind, n *Node, var_ *Node, init *Nodes)
|
||||||
a = walkstmt(a)
|
a = walkstmt(a)
|
||||||
init.Append(a)
|
init.Append(a)
|
||||||
default:
|
default:
|
||||||
Fatalf("fixedlit: bad kind %d", kind)
|
base.Fatalf("fixedlit: bad kind %d", kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -610,7 +611,7 @@ func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) {
|
||||||
var_ = typecheck(var_, ctxExpr|ctxAssign)
|
var_ = typecheck(var_, ctxExpr|ctxAssign)
|
||||||
nam := stataddr(var_)
|
nam := stataddr(var_)
|
||||||
if nam == nil || nam.Class() != PEXTERN {
|
if nam == nil || nam.Class() != PEXTERN {
|
||||||
Fatalf("slicelit: %v", var_)
|
base.Fatalf("slicelit: %v", var_)
|
||||||
}
|
}
|
||||||
slicesym(nam, vstat, t.NumElem())
|
slicesym(nam, vstat, t.NumElem())
|
||||||
return
|
return
|
||||||
|
|
@ -709,7 +710,7 @@ func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) {
|
||||||
if value.Op == OKEY {
|
if value.Op == OKEY {
|
||||||
index = indexconst(value.Left)
|
index = indexconst(value.Left)
|
||||||
if index < 0 {
|
if index < 0 {
|
||||||
Fatalf("slicelit: invalid index %v", value.Left)
|
base.Fatalf("slicelit: invalid index %v", value.Left)
|
||||||
}
|
}
|
||||||
value = value.Right
|
value = value.Right
|
||||||
}
|
}
|
||||||
|
|
@ -770,7 +771,7 @@ func maplit(n *Node, m *Node, init *Nodes) {
|
||||||
// All remaining entries are static. Double-check that.
|
// All remaining entries are static. Double-check that.
|
||||||
for _, r := range entries {
|
for _, r := range entries {
|
||||||
if !isStaticCompositeLiteral(r.Left) || !isStaticCompositeLiteral(r.Right) {
|
if !isStaticCompositeLiteral(r.Left) || !isStaticCompositeLiteral(r.Right) {
|
||||||
Fatalf("maplit: entry is not a literal: %v", r)
|
base.Fatalf("maplit: entry is not a literal: %v", r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -868,7 +869,7 @@ func anylit(n *Node, var_ *Node, init *Nodes) {
|
||||||
t := n.Type
|
t := n.Type
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
default:
|
default:
|
||||||
Fatalf("anylit: not lit, op=%v node=%v", n.Op, n)
|
base.Fatalf("anylit: not lit, op=%v node=%v", n.Op, n)
|
||||||
|
|
||||||
case ONAME, OMETHEXPR:
|
case ONAME, OMETHEXPR:
|
||||||
a := nod(OAS, var_, n)
|
a := nod(OAS, var_, n)
|
||||||
|
|
@ -877,7 +878,7 @@ func anylit(n *Node, var_ *Node, init *Nodes) {
|
||||||
|
|
||||||
case OPTRLIT:
|
case OPTRLIT:
|
||||||
if !t.IsPtr() {
|
if !t.IsPtr() {
|
||||||
Fatalf("anylit: not ptr")
|
base.Fatalf("anylit: not ptr")
|
||||||
}
|
}
|
||||||
|
|
||||||
var r *Node
|
var r *Node
|
||||||
|
|
@ -905,7 +906,7 @@ func anylit(n *Node, var_ *Node, init *Nodes) {
|
||||||
|
|
||||||
case OSTRUCTLIT, OARRAYLIT:
|
case OSTRUCTLIT, OARRAYLIT:
|
||||||
if !t.IsStruct() && !t.IsArray() {
|
if !t.IsStruct() && !t.IsArray() {
|
||||||
Fatalf("anylit: not struct/array")
|
base.Fatalf("anylit: not struct/array")
|
||||||
}
|
}
|
||||||
|
|
||||||
if var_.isSimpleName() && n.List.Len() > 4 {
|
if var_.isSimpleName() && n.List.Len() > 4 {
|
||||||
|
|
@ -951,7 +952,7 @@ func anylit(n *Node, var_ *Node, init *Nodes) {
|
||||||
|
|
||||||
case OMAPLIT:
|
case OMAPLIT:
|
||||||
if !t.IsMap() {
|
if !t.IsMap() {
|
||||||
Fatalf("anylit: not map")
|
base.Fatalf("anylit: not map")
|
||||||
}
|
}
|
||||||
maplit(n, var_, init)
|
maplit(n, var_, init)
|
||||||
}
|
}
|
||||||
|
|
@ -1052,7 +1053,7 @@ func (s *InitSchedule) initplan(n *Node) {
|
||||||
s.initplans[n] = p
|
s.initplans[n] = p
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
default:
|
default:
|
||||||
Fatalf("initplan")
|
base.Fatalf("initplan")
|
||||||
|
|
||||||
case OARRAYLIT, OSLICELIT:
|
case OARRAYLIT, OSLICELIT:
|
||||||
var k int64
|
var k int64
|
||||||
|
|
@ -1060,7 +1061,7 @@ func (s *InitSchedule) initplan(n *Node) {
|
||||||
if a.Op == OKEY {
|
if a.Op == OKEY {
|
||||||
k = indexconst(a.Left)
|
k = indexconst(a.Left)
|
||||||
if k < 0 {
|
if k < 0 {
|
||||||
Fatalf("initplan arraylit: invalid index %v", a.Left)
|
base.Fatalf("initplan arraylit: invalid index %v", a.Left)
|
||||||
}
|
}
|
||||||
a = a.Right
|
a = a.Right
|
||||||
}
|
}
|
||||||
|
|
@ -1071,7 +1072,7 @@ func (s *InitSchedule) initplan(n *Node) {
|
||||||
case OSTRUCTLIT:
|
case OSTRUCTLIT:
|
||||||
for _, a := range n.List.Slice() {
|
for _, a := range n.List.Slice() {
|
||||||
if a.Op != OSTRUCTKEY {
|
if a.Op != OSTRUCTKEY {
|
||||||
Fatalf("initplan structlit")
|
base.Fatalf("initplan structlit")
|
||||||
}
|
}
|
||||||
if a.Sym.IsBlank() {
|
if a.Sym.IsBlank() {
|
||||||
continue
|
continue
|
||||||
|
|
@ -1082,7 +1083,7 @@ func (s *InitSchedule) initplan(n *Node) {
|
||||||
case OMAPLIT:
|
case OMAPLIT:
|
||||||
for _, a := range n.List.Slice() {
|
for _, a := range n.List.Slice() {
|
||||||
if a.Op != OKEY {
|
if a.Op != OKEY {
|
||||||
Fatalf("initplan maplit")
|
base.Fatalf("initplan maplit")
|
||||||
}
|
}
|
||||||
s.addvalue(p, -1, a.Right)
|
s.addvalue(p, -1, a.Right)
|
||||||
}
|
}
|
||||||
|
|
@ -1155,12 +1156,12 @@ func isvaluelit(n *Node) bool {
|
||||||
|
|
||||||
func genAsStatic(as *Node) {
|
func genAsStatic(as *Node) {
|
||||||
if as.Left.Type == nil {
|
if as.Left.Type == nil {
|
||||||
Fatalf("genAsStatic as.Left not typechecked")
|
base.Fatalf("genAsStatic as.Left not typechecked")
|
||||||
}
|
}
|
||||||
|
|
||||||
nam := stataddr(as.Left)
|
nam := stataddr(as.Left)
|
||||||
if nam == nil || (nam.Class() != PEXTERN && as.Left != nblank) {
|
if nam == nil || (nam.Class() != PEXTERN && as.Left != nblank) {
|
||||||
Fatalf("genAsStatic: lhs %v", as.Left)
|
base.Fatalf("genAsStatic: lhs %v", as.Left)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
|
|
@ -1169,6 +1170,6 @@ func genAsStatic(as *Node) {
|
||||||
case (as.Right.Op == ONAME || as.Right.Op == OMETHEXPR) && as.Right.Class() == PFUNC:
|
case (as.Right.Op == ONAME || as.Right.Op == OMETHEXPR) && as.Right.Class() == PFUNC:
|
||||||
pfuncsym(nam, as.Right)
|
pfuncsym(nam, as.Right)
|
||||||
default:
|
default:
|
||||||
Fatalf("genAsStatic: rhs %v", as.Right)
|
base.Fatalf("genAsStatic: rhs %v", as.Right)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import (
|
||||||
|
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/ssa"
|
"cmd/compile/internal/ssa"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
|
|
@ -60,10 +61,10 @@ func initssaconfig() {
|
||||||
_ = types.NewPtr(types.Types[TINT64]) // *int64
|
_ = types.NewPtr(types.Types[TINT64]) // *int64
|
||||||
_ = types.NewPtr(types.Errortype) // *error
|
_ = types.NewPtr(types.Errortype) // *error
|
||||||
types.NewPtrCacheEnabled = false
|
types.NewPtrCacheEnabled = false
|
||||||
ssaConfig = ssa.NewConfig(thearch.LinkArch.Name, *types_, Ctxt, Flag.N == 0)
|
ssaConfig = ssa.NewConfig(thearch.LinkArch.Name, *types_, base.Ctxt, base.Flag.N == 0)
|
||||||
ssaConfig.SoftFloat = thearch.SoftFloat
|
ssaConfig.SoftFloat = thearch.SoftFloat
|
||||||
ssaConfig.Race = Flag.Race
|
ssaConfig.Race = base.Flag.Race
|
||||||
ssaCaches = make([]ssa.Cache, Flag.LowerC)
|
ssaCaches = make([]ssa.Cache, base.Flag.LowerC)
|
||||||
|
|
||||||
// Set up some runtime functions we'll need to call.
|
// Set up some runtime functions we'll need to call.
|
||||||
assertE2I = sysfunc("assertE2I")
|
assertE2I = sysfunc("assertE2I")
|
||||||
|
|
@ -240,7 +241,7 @@ func dvarint(x *obj.LSym, off int, v int64) int {
|
||||||
// - Size of the argument
|
// - Size of the argument
|
||||||
// - Offset of where argument should be placed in the args frame when making call
|
// - Offset of where argument should be placed in the args frame when making call
|
||||||
func (s *state) emitOpenDeferInfo() {
|
func (s *state) emitOpenDeferInfo() {
|
||||||
x := Ctxt.Lookup(s.curfn.Func.lsym.Name + ".opendefer")
|
x := base.Ctxt.Lookup(s.curfn.Func.lsym.Name + ".opendefer")
|
||||||
s.curfn.Func.lsym.Func().OpenCodedDeferInfo = x
|
s.curfn.Func.lsym.Func().OpenCodedDeferInfo = x
|
||||||
off := 0
|
off := 0
|
||||||
|
|
||||||
|
|
@ -291,7 +292,7 @@ func buildssa(fn *Node, worker int) *ssa.Func {
|
||||||
name := fn.funcname()
|
name := fn.funcname()
|
||||||
printssa := false
|
printssa := false
|
||||||
if ssaDump != "" { // match either a simple name e.g. "(*Reader).Reset", or a package.name e.g. "compress/gzip.(*Reader).Reset"
|
if ssaDump != "" { // match either a simple name e.g. "(*Reader).Reset", or a package.name e.g. "compress/gzip.(*Reader).Reset"
|
||||||
printssa = name == ssaDump || Ctxt.Pkgpath+"."+name == ssaDump
|
printssa = name == ssaDump || base.Ctxt.Pkgpath+"."+name == ssaDump
|
||||||
}
|
}
|
||||||
var astBuf *bytes.Buffer
|
var astBuf *bytes.Buffer
|
||||||
if printssa {
|
if printssa {
|
||||||
|
|
@ -342,7 +343,7 @@ func buildssa(fn *Node, worker int) *ssa.Func {
|
||||||
if printssa {
|
if printssa {
|
||||||
ssaDF := ssaDumpFile
|
ssaDF := ssaDumpFile
|
||||||
if ssaDir != "" {
|
if ssaDir != "" {
|
||||||
ssaDF = filepath.Join(ssaDir, Ctxt.Pkgpath+"."+name+".html")
|
ssaDF = filepath.Join(ssaDir, base.Ctxt.Pkgpath+"."+name+".html")
|
||||||
ssaD := filepath.Dir(ssaDF)
|
ssaD := filepath.Dir(ssaDF)
|
||||||
os.MkdirAll(ssaD, 0755)
|
os.MkdirAll(ssaD, 0755)
|
||||||
}
|
}
|
||||||
|
|
@ -358,9 +359,9 @@ func buildssa(fn *Node, worker int) *ssa.Func {
|
||||||
s.fwdVars = map[*Node]*ssa.Value{}
|
s.fwdVars = map[*Node]*ssa.Value{}
|
||||||
s.startmem = s.entryNewValue0(ssa.OpInitMem, types.TypeMem)
|
s.startmem = s.entryNewValue0(ssa.OpInitMem, types.TypeMem)
|
||||||
|
|
||||||
s.hasOpenDefers = Flag.N == 0 && s.hasdefer && !s.curfn.Func.OpenCodedDeferDisallowed()
|
s.hasOpenDefers = base.Flag.N == 0 && s.hasdefer && !s.curfn.Func.OpenCodedDeferDisallowed()
|
||||||
switch {
|
switch {
|
||||||
case s.hasOpenDefers && (Ctxt.Flag_shared || Ctxt.Flag_dynlink) && thearch.LinkArch.Name == "386":
|
case s.hasOpenDefers && (base.Ctxt.Flag_shared || base.Ctxt.Flag_dynlink) && thearch.LinkArch.Name == "386":
|
||||||
// Don't support open-coded defers for 386 ONLY when using shared
|
// Don't support open-coded defers for 386 ONLY when using shared
|
||||||
// libraries, because there is extra code (added by rewriteToUseGot())
|
// libraries, because there is extra code (added by rewriteToUseGot())
|
||||||
// preceding the deferreturn/ret code that is generated by gencallret()
|
// preceding the deferreturn/ret code that is generated by gencallret()
|
||||||
|
|
@ -478,7 +479,7 @@ func buildssa(fn *Node, worker int) *ssa.Func {
|
||||||
|
|
||||||
func dumpSourcesColumn(writer *ssa.HTMLWriter, fn *Node) {
|
func dumpSourcesColumn(writer *ssa.HTMLWriter, fn *Node) {
|
||||||
// Read sources of target function fn.
|
// Read sources of target function fn.
|
||||||
fname := Ctxt.PosTable.Pos(fn.Pos).Filename()
|
fname := base.Ctxt.PosTable.Pos(fn.Pos).Filename()
|
||||||
targetFn, err := readFuncLines(fname, fn.Pos.Line(), fn.Func.Endlineno.Line())
|
targetFn, err := readFuncLines(fname, fn.Pos.Line(), fn.Func.Endlineno.Line())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writer.Logf("cannot read sources for function %v: %v", fn, err)
|
writer.Logf("cannot read sources for function %v: %v", fn, err)
|
||||||
|
|
@ -494,7 +495,7 @@ func dumpSourcesColumn(writer *ssa.HTMLWriter, fn *Node) {
|
||||||
} else {
|
} else {
|
||||||
elno = fi.Name.Defn.Func.Endlineno
|
elno = fi.Name.Defn.Func.Endlineno
|
||||||
}
|
}
|
||||||
fname := Ctxt.PosTable.Pos(fi.Pos).Filename()
|
fname := base.Ctxt.PosTable.Pos(fi.Pos).Filename()
|
||||||
fnLines, err := readFuncLines(fname, fi.Pos.Line(), elno.Line())
|
fnLines, err := readFuncLines(fname, fi.Pos.Line(), elno.Line())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writer.Logf("cannot read sources for inlined function %v: %v", fi, err)
|
writer.Logf("cannot read sources for inlined function %v: %v", fi, err)
|
||||||
|
|
@ -752,8 +753,8 @@ func (s *state) pushLine(line src.XPos) {
|
||||||
// the frontend may emit node with line number missing,
|
// the frontend may emit node with line number missing,
|
||||||
// use the parent line number in this case.
|
// use the parent line number in this case.
|
||||||
line = s.peekPos()
|
line = s.peekPos()
|
||||||
if Flag.K != 0 {
|
if base.Flag.K != 0 {
|
||||||
Warn("buildssa: unknown position (line 0)")
|
base.Warn("buildssa: unknown position (line 0)")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
s.lastPos = line
|
s.lastPos = line
|
||||||
|
|
@ -988,13 +989,13 @@ func (s *state) instrument(t *types.Type, addr *ssa.Value, wr bool) {
|
||||||
var fn *obj.LSym
|
var fn *obj.LSym
|
||||||
needWidth := false
|
needWidth := false
|
||||||
|
|
||||||
if Flag.MSan {
|
if base.Flag.MSan {
|
||||||
fn = msanread
|
fn = msanread
|
||||||
if wr {
|
if wr {
|
||||||
fn = msanwrite
|
fn = msanwrite
|
||||||
}
|
}
|
||||||
needWidth = true
|
needWidth = true
|
||||||
} else if Flag.Race && t.NumComponents(types.CountBlankFields) > 1 {
|
} else if base.Flag.Race && t.NumComponents(types.CountBlankFields) > 1 {
|
||||||
// for composite objects we have to write every address
|
// for composite objects we have to write every address
|
||||||
// because a write might happen to any subobject.
|
// because a write might happen to any subobject.
|
||||||
// composites with only one element don't have subobjects, though.
|
// composites with only one element don't have subobjects, though.
|
||||||
|
|
@ -1003,7 +1004,7 @@ func (s *state) instrument(t *types.Type, addr *ssa.Value, wr bool) {
|
||||||
fn = racewriterange
|
fn = racewriterange
|
||||||
}
|
}
|
||||||
needWidth = true
|
needWidth = true
|
||||||
} else if Flag.Race {
|
} else if base.Flag.Race {
|
||||||
// for non-composite objects we can write just the start
|
// for non-composite objects we can write just the start
|
||||||
// address, as any write must write the first byte.
|
// address, as any write must write the first byte.
|
||||||
fn = raceread
|
fn = raceread
|
||||||
|
|
@ -1090,7 +1091,7 @@ func (s *state) stmt(n *Node) {
|
||||||
case OCALLMETH, OCALLINTER:
|
case OCALLMETH, OCALLINTER:
|
||||||
s.callResult(n, callNormal)
|
s.callResult(n, callNormal)
|
||||||
if n.Op == OCALLFUNC && n.Left.Op == ONAME && n.Left.Class() == PFUNC {
|
if n.Op == OCALLFUNC && n.Left.Op == ONAME && n.Left.Class() == PFUNC {
|
||||||
if fn := n.Left.Sym.Name; Flag.CompilingRuntime && fn == "throw" ||
|
if fn := n.Left.Sym.Name; base.Flag.CompilingRuntime && fn == "throw" ||
|
||||||
n.Left.Sym.Pkg == Runtimepkg && (fn == "throwinit" || fn == "gopanic" || fn == "panicwrap" || fn == "block" || fn == "panicmakeslicelen" || fn == "panicmakeslicecap") {
|
n.Left.Sym.Pkg == Runtimepkg && (fn == "throwinit" || fn == "gopanic" || fn == "panicwrap" || fn == "block" || fn == "panicmakeslicelen" || fn == "panicmakeslicecap") {
|
||||||
m := s.mem()
|
m := s.mem()
|
||||||
b := s.endBlock()
|
b := s.endBlock()
|
||||||
|
|
@ -1102,7 +1103,7 @@ func (s *state) stmt(n *Node) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case ODEFER:
|
case ODEFER:
|
||||||
if Debug.Defer > 0 {
|
if base.Debug.Defer > 0 {
|
||||||
var defertype string
|
var defertype string
|
||||||
if s.hasOpenDefers {
|
if s.hasOpenDefers {
|
||||||
defertype = "open-coded"
|
defertype = "open-coded"
|
||||||
|
|
@ -1111,7 +1112,7 @@ func (s *state) stmt(n *Node) {
|
||||||
} else {
|
} else {
|
||||||
defertype = "heap-allocated"
|
defertype = "heap-allocated"
|
||||||
}
|
}
|
||||||
Warnl(n.Pos, "%s defer", defertype)
|
base.WarnfAt(n.Pos, "%s defer", defertype)
|
||||||
}
|
}
|
||||||
if s.hasOpenDefers {
|
if s.hasOpenDefers {
|
||||||
s.openDeferRecord(n.Left)
|
s.openDeferRecord(n.Left)
|
||||||
|
|
@ -1225,20 +1226,20 @@ func (s *state) stmt(n *Node) {
|
||||||
// Check whether we're writing the result of an append back to the same slice.
|
// Check whether we're writing the result of an append back to the same slice.
|
||||||
// If so, we handle it specially to avoid write barriers on the fast
|
// If so, we handle it specially to avoid write barriers on the fast
|
||||||
// (non-growth) path.
|
// (non-growth) path.
|
||||||
if !samesafeexpr(n.Left, rhs.List.First()) || Flag.N != 0 {
|
if !samesafeexpr(n.Left, rhs.List.First()) || base.Flag.N != 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// If the slice can be SSA'd, it'll be on the stack,
|
// If the slice can be SSA'd, it'll be on the stack,
|
||||||
// so there will be no write barriers,
|
// so there will be no write barriers,
|
||||||
// so there's no need to attempt to prevent them.
|
// so there's no need to attempt to prevent them.
|
||||||
if s.canSSA(n.Left) {
|
if s.canSSA(n.Left) {
|
||||||
if Debug.Append > 0 { // replicating old diagnostic message
|
if base.Debug.Append > 0 { // replicating old diagnostic message
|
||||||
Warnl(n.Pos, "append: len-only update (in local slice)")
|
base.WarnfAt(n.Pos, "append: len-only update (in local slice)")
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if Debug.Append > 0 {
|
if base.Debug.Append > 0 {
|
||||||
Warnl(n.Pos, "append: len-only update")
|
base.WarnfAt(n.Pos, "append: len-only update")
|
||||||
}
|
}
|
||||||
s.append(rhs, true)
|
s.append(rhs, true)
|
||||||
return
|
return
|
||||||
|
|
@ -1814,7 +1815,7 @@ func floatForComplex(t *types.Type) *types.Type {
|
||||||
case TCOMPLEX128:
|
case TCOMPLEX128:
|
||||||
return types.Types[TFLOAT64]
|
return types.Types[TFLOAT64]
|
||||||
}
|
}
|
||||||
Fatalf("unexpected type: %v", t)
|
base.Fatalf("unexpected type: %v", t)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1825,7 +1826,7 @@ func complexForFloat(t *types.Type) *types.Type {
|
||||||
case TFLOAT64:
|
case TFLOAT64:
|
||||||
return types.Types[TCOMPLEX128]
|
return types.Types[TCOMPLEX128]
|
||||||
}
|
}
|
||||||
Fatalf("unexpected type: %v", t)
|
base.Fatalf("unexpected type: %v", t)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4130,9 +4131,9 @@ func findIntrinsic(sym *types.Sym) intrinsicBuilder {
|
||||||
}
|
}
|
||||||
pkg := sym.Pkg.Path
|
pkg := sym.Pkg.Path
|
||||||
if sym.Pkg == localpkg {
|
if sym.Pkg == localpkg {
|
||||||
pkg = Ctxt.Pkgpath
|
pkg = base.Ctxt.Pkgpath
|
||||||
}
|
}
|
||||||
if Flag.Race && pkg == "sync/atomic" {
|
if base.Flag.Race && pkg == "sync/atomic" {
|
||||||
// The race detector needs to be able to intercept these calls.
|
// The race detector needs to be able to intercept these calls.
|
||||||
// We can't intrinsify them.
|
// We can't intrinsify them.
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -4172,7 +4173,7 @@ func (s *state) intrinsicCall(n *Node) *ssa.Value {
|
||||||
if x.Op == ssa.OpSelect0 || x.Op == ssa.OpSelect1 {
|
if x.Op == ssa.OpSelect0 || x.Op == ssa.OpSelect1 {
|
||||||
x = x.Args[0]
|
x = x.Args[0]
|
||||||
}
|
}
|
||||||
Warnl(n.Pos, "intrinsic substitution for %v with %s", n.Left.Sym.Name, x.LongString())
|
base.WarnfAt(n.Pos, "intrinsic substitution for %v with %s", n.Left.Sym.Name, x.LongString())
|
||||||
}
|
}
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
@ -4240,7 +4241,7 @@ func (s *state) openDeferRecord(n *Node) {
|
||||||
}
|
}
|
||||||
} else if n.Op == OCALLMETH {
|
} else if n.Op == OCALLMETH {
|
||||||
if fn.Op != ODOTMETH {
|
if fn.Op != ODOTMETH {
|
||||||
Fatalf("OCALLMETH: n.Left not an ODOTMETH: %v", fn)
|
base.Fatalf("OCALLMETH: n.Left not an ODOTMETH: %v", fn)
|
||||||
}
|
}
|
||||||
closureVal := s.getMethodClosure(fn)
|
closureVal := s.getMethodClosure(fn)
|
||||||
// We must always store the function value in a stack slot for the
|
// We must always store the function value in a stack slot for the
|
||||||
|
|
@ -4250,7 +4251,7 @@ func (s *state) openDeferRecord(n *Node) {
|
||||||
opendefer.closureNode = closure.Aux.(*Node)
|
opendefer.closureNode = closure.Aux.(*Node)
|
||||||
} else {
|
} else {
|
||||||
if fn.Op != ODOTINTER {
|
if fn.Op != ODOTINTER {
|
||||||
Fatalf("OCALLINTER: n.Left not an ODOTINTER: %v", fn.Op)
|
base.Fatalf("OCALLINTER: n.Left not an ODOTINTER: %v", fn.Op)
|
||||||
}
|
}
|
||||||
closure, rcvr := s.getClosureAndRcvr(fn)
|
closure, rcvr := s.getClosureAndRcvr(fn)
|
||||||
opendefer.closure = s.openDeferSave(nil, closure.Type, closure)
|
opendefer.closure = s.openDeferSave(nil, closure.Type, closure)
|
||||||
|
|
@ -4382,7 +4383,7 @@ func (s *state) openDeferExit() {
|
||||||
// Generate code to call the function call of the defer, using the
|
// Generate code to call the function call of the defer, using the
|
||||||
// closure/receiver/args that were stored in argtmps at the point
|
// closure/receiver/args that were stored in argtmps at the point
|
||||||
// of the defer statement.
|
// of the defer statement.
|
||||||
argStart := Ctxt.FixedFrameSize()
|
argStart := base.Ctxt.FixedFrameSize()
|
||||||
fn := r.n.Left
|
fn := r.n.Left
|
||||||
stksize := fn.Type.ArgWidth()
|
stksize := fn.Type.ArgWidth()
|
||||||
var ACArgs []ssa.Param
|
var ACArgs []ssa.Param
|
||||||
|
|
@ -4499,7 +4500,7 @@ func (s *state) call(n *Node, k callKind, returnResultAddr bool) *ssa.Value {
|
||||||
nf := res.NumFields()
|
nf := res.NumFields()
|
||||||
for i := 0; i < nf; i++ {
|
for i := 0; i < nf; i++ {
|
||||||
fp := res.Field(i)
|
fp := res.Field(i)
|
||||||
ACResults = append(ACResults, ssa.Param{Type: fp.Type, Offset: int32(fp.Offset + Ctxt.FixedFrameSize())})
|
ACResults = append(ACResults, ssa.Param{Type: fp.Type, Offset: int32(fp.Offset + base.Ctxt.FixedFrameSize())})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4604,14 +4605,14 @@ func (s *state) call(n *Node, k callKind, returnResultAddr bool) *ssa.Value {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call runtime.deferprocStack with pointer to _defer record.
|
// Call runtime.deferprocStack with pointer to _defer record.
|
||||||
ACArgs = append(ACArgs, ssa.Param{Type: types.Types[TUINTPTR], Offset: int32(Ctxt.FixedFrameSize())})
|
ACArgs = append(ACArgs, ssa.Param{Type: types.Types[TUINTPTR], Offset: int32(base.Ctxt.FixedFrameSize())})
|
||||||
aux := ssa.StaticAuxCall(deferprocStack, ACArgs, ACResults)
|
aux := ssa.StaticAuxCall(deferprocStack, ACArgs, ACResults)
|
||||||
if testLateExpansion {
|
if testLateExpansion {
|
||||||
callArgs = append(callArgs, addr, s.mem())
|
callArgs = append(callArgs, addr, s.mem())
|
||||||
call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux)
|
call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux)
|
||||||
call.AddArgs(callArgs...)
|
call.AddArgs(callArgs...)
|
||||||
} else {
|
} else {
|
||||||
arg0 := s.constOffPtrSP(types.Types[TUINTPTR], Ctxt.FixedFrameSize())
|
arg0 := s.constOffPtrSP(types.Types[TUINTPTR], base.Ctxt.FixedFrameSize())
|
||||||
s.store(types.Types[TUINTPTR], arg0, addr)
|
s.store(types.Types[TUINTPTR], arg0, addr)
|
||||||
call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, aux, s.mem())
|
call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, aux, s.mem())
|
||||||
}
|
}
|
||||||
|
|
@ -4625,7 +4626,7 @@ func (s *state) call(n *Node, k callKind, returnResultAddr bool) *ssa.Value {
|
||||||
} else {
|
} else {
|
||||||
// Store arguments to stack, including defer/go arguments and receiver for method calls.
|
// Store arguments to stack, including defer/go arguments and receiver for method calls.
|
||||||
// These are written in SP-offset order.
|
// These are written in SP-offset order.
|
||||||
argStart := Ctxt.FixedFrameSize()
|
argStart := base.Ctxt.FixedFrameSize()
|
||||||
// Defer/go args.
|
// Defer/go args.
|
||||||
if k != callNormal {
|
if k != callNormal {
|
||||||
// Write argsize and closure (args to newproc/deferproc).
|
// Write argsize and closure (args to newproc/deferproc).
|
||||||
|
|
@ -4766,13 +4767,13 @@ func (s *state) call(n *Node, k callKind, returnResultAddr bool) *ssa.Value {
|
||||||
if testLateExpansion {
|
if testLateExpansion {
|
||||||
return s.newValue1I(ssa.OpSelectNAddr, pt, 0, call)
|
return s.newValue1I(ssa.OpSelectNAddr, pt, 0, call)
|
||||||
}
|
}
|
||||||
return s.constOffPtrSP(pt, fp.Offset+Ctxt.FixedFrameSize())
|
return s.constOffPtrSP(pt, fp.Offset+base.Ctxt.FixedFrameSize())
|
||||||
}
|
}
|
||||||
|
|
||||||
if testLateExpansion {
|
if testLateExpansion {
|
||||||
return s.newValue1I(ssa.OpSelectN, fp.Type, 0, call)
|
return s.newValue1I(ssa.OpSelectN, fp.Type, 0, call)
|
||||||
}
|
}
|
||||||
return s.load(n.Type, s.constOffPtrSP(types.NewPtr(fp.Type), fp.Offset+Ctxt.FixedFrameSize()))
|
return s.load(n.Type, s.constOffPtrSP(types.NewPtr(fp.Type), fp.Offset+base.Ctxt.FixedFrameSize()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// maybeNilCheckClosure checks if a nil check of a closure is needed in some
|
// maybeNilCheckClosure checks if a nil check of a closure is needed in some
|
||||||
|
|
@ -4930,7 +4931,7 @@ func (s *state) addr(n *Node) *ssa.Value {
|
||||||
// canSSA reports whether n is SSA-able.
|
// canSSA reports whether n is SSA-able.
|
||||||
// n must be an ONAME (or an ODOT sequence with an ONAME base).
|
// n must be an ONAME (or an ODOT sequence with an ONAME base).
|
||||||
func (s *state) canSSA(n *Node) bool {
|
func (s *state) canSSA(n *Node) bool {
|
||||||
if Flag.N != 0 {
|
if base.Flag.N != 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
for n.Op == ODOT || (n.Op == OINDEX && n.Left.Type.IsArray()) {
|
for n.Op == ODOT || (n.Op == OINDEX && n.Left.Type.IsArray()) {
|
||||||
|
|
@ -5026,7 +5027,7 @@ func (s *state) exprPtr(n *Node, bounded bool, lineno src.XPos) *ssa.Value {
|
||||||
// Used only for automatically inserted nil checks,
|
// Used only for automatically inserted nil checks,
|
||||||
// not for user code like 'x != nil'.
|
// not for user code like 'x != nil'.
|
||||||
func (s *state) nilCheck(ptr *ssa.Value) {
|
func (s *state) nilCheck(ptr *ssa.Value) {
|
||||||
if Debug.DisableNil != 0 || s.curfn.Func.NilCheckDisabled() {
|
if base.Debug.DisableNil != 0 || s.curfn.Func.NilCheckDisabled() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.newValue2(ssa.OpNilCheck, types.TypeVoid, ptr, s.mem())
|
s.newValue2(ssa.OpNilCheck, types.TypeVoid, ptr, s.mem())
|
||||||
|
|
@ -5041,7 +5042,7 @@ func (s *state) nilCheck(ptr *ssa.Value) {
|
||||||
func (s *state) boundsCheck(idx, len *ssa.Value, kind ssa.BoundsKind, bounded bool) *ssa.Value {
|
func (s *state) boundsCheck(idx, len *ssa.Value, kind ssa.BoundsKind, bounded bool) *ssa.Value {
|
||||||
idx = s.extendIndex(idx, len, kind, bounded)
|
idx = s.extendIndex(idx, len, kind, bounded)
|
||||||
|
|
||||||
if bounded || Flag.B != 0 {
|
if bounded || base.Flag.B != 0 {
|
||||||
// If bounded or bounds checking is flag-disabled, then no check necessary,
|
// If bounded or bounds checking is flag-disabled, then no check necessary,
|
||||||
// just return the extended index.
|
// just return the extended index.
|
||||||
//
|
//
|
||||||
|
|
@ -5114,7 +5115,7 @@ func (s *state) boundsCheck(idx, len *ssa.Value, kind ssa.BoundsKind, bounded bo
|
||||||
s.startBlock(bNext)
|
s.startBlock(bNext)
|
||||||
|
|
||||||
// In Spectre index mode, apply an appropriate mask to avoid speculative out-of-bounds accesses.
|
// In Spectre index mode, apply an appropriate mask to avoid speculative out-of-bounds accesses.
|
||||||
if Flag.Cfg.SpectreIndex {
|
if base.Flag.Cfg.SpectreIndex {
|
||||||
op := ssa.OpSpectreIndex
|
op := ssa.OpSpectreIndex
|
||||||
if kind != ssa.BoundsIndex && kind != ssa.BoundsIndexU {
|
if kind != ssa.BoundsIndex && kind != ssa.BoundsIndexU {
|
||||||
op = ssa.OpSpectreSliceIndex
|
op = ssa.OpSpectreSliceIndex
|
||||||
|
|
@ -5133,7 +5134,7 @@ func (s *state) check(cmp *ssa.Value, fn *obj.LSym) {
|
||||||
b.Likely = ssa.BranchLikely
|
b.Likely = ssa.BranchLikely
|
||||||
bNext := s.f.NewBlock(ssa.BlockPlain)
|
bNext := s.f.NewBlock(ssa.BlockPlain)
|
||||||
line := s.peekPos()
|
line := s.peekPos()
|
||||||
pos := Ctxt.PosTable.Pos(line)
|
pos := base.Ctxt.PosTable.Pos(line)
|
||||||
fl := funcLine{f: fn, base: pos.Base(), line: pos.Line()}
|
fl := funcLine{f: fn, base: pos.Base(), line: pos.Line()}
|
||||||
bPanic := s.panics[fl]
|
bPanic := s.panics[fl]
|
||||||
if bPanic == nil {
|
if bPanic == nil {
|
||||||
|
|
@ -5172,7 +5173,7 @@ func (s *state) intDivide(n *Node, a, b *ssa.Value) *ssa.Value {
|
||||||
func (s *state) rtcall(fn *obj.LSym, returns bool, results []*types.Type, args ...*ssa.Value) []*ssa.Value {
|
func (s *state) rtcall(fn *obj.LSym, returns bool, results []*types.Type, args ...*ssa.Value) []*ssa.Value {
|
||||||
s.prevCall = nil
|
s.prevCall = nil
|
||||||
// Write args to the stack
|
// Write args to the stack
|
||||||
off := Ctxt.FixedFrameSize()
|
off := base.Ctxt.FixedFrameSize()
|
||||||
testLateExpansion := ssa.LateCallExpansionEnabledWithin(s.f)
|
testLateExpansion := ssa.LateCallExpansionEnabledWithin(s.f)
|
||||||
var ACArgs []ssa.Param
|
var ACArgs []ssa.Param
|
||||||
var ACResults []ssa.Param
|
var ACResults []ssa.Param
|
||||||
|
|
@ -5219,7 +5220,7 @@ func (s *state) rtcall(fn *obj.LSym, returns bool, results []*types.Type, args .
|
||||||
b := s.endBlock()
|
b := s.endBlock()
|
||||||
b.Kind = ssa.BlockExit
|
b.Kind = ssa.BlockExit
|
||||||
b.SetControl(call)
|
b.SetControl(call)
|
||||||
call.AuxInt = off - Ctxt.FixedFrameSize()
|
call.AuxInt = off - base.Ctxt.FixedFrameSize()
|
||||||
if len(results) > 0 {
|
if len(results) > 0 {
|
||||||
s.Fatalf("panic call can't have results")
|
s.Fatalf("panic call can't have results")
|
||||||
}
|
}
|
||||||
|
|
@ -5837,8 +5838,8 @@ func (s *state) dottype(n *Node, commaok bool) (res, resok *ssa.Value) {
|
||||||
if n.Type.IsEmptyInterface() {
|
if n.Type.IsEmptyInterface() {
|
||||||
// Converting to an empty interface.
|
// Converting to an empty interface.
|
||||||
// Input could be an empty or nonempty interface.
|
// Input could be an empty or nonempty interface.
|
||||||
if Debug.TypeAssert > 0 {
|
if base.Debug.TypeAssert > 0 {
|
||||||
Warnl(n.Pos, "type assertion inlined")
|
base.WarnfAt(n.Pos, "type assertion inlined")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get itab/type field from input.
|
// Get itab/type field from input.
|
||||||
|
|
@ -5904,8 +5905,8 @@ func (s *state) dottype(n *Node, commaok bool) (res, resok *ssa.Value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// converting to a nonempty interface needs a runtime call.
|
// converting to a nonempty interface needs a runtime call.
|
||||||
if Debug.TypeAssert > 0 {
|
if base.Debug.TypeAssert > 0 {
|
||||||
Warnl(n.Pos, "type assertion not inlined")
|
base.WarnfAt(n.Pos, "type assertion not inlined")
|
||||||
}
|
}
|
||||||
if n.Left.Type.IsEmptyInterface() {
|
if n.Left.Type.IsEmptyInterface() {
|
||||||
if commaok {
|
if commaok {
|
||||||
|
|
@ -5921,15 +5922,15 @@ func (s *state) dottype(n *Node, commaok bool) (res, resok *ssa.Value) {
|
||||||
return s.rtcall(assertI2I, true, []*types.Type{n.Type}, target, iface)[0], nil
|
return s.rtcall(assertI2I, true, []*types.Type{n.Type}, target, iface)[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if Debug.TypeAssert > 0 {
|
if base.Debug.TypeAssert > 0 {
|
||||||
Warnl(n.Pos, "type assertion inlined")
|
base.WarnfAt(n.Pos, "type assertion inlined")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converting to a concrete type.
|
// Converting to a concrete type.
|
||||||
direct := isdirectiface(n.Type)
|
direct := isdirectiface(n.Type)
|
||||||
itab := s.newValue1(ssa.OpITab, byteptr, iface) // type word of interface
|
itab := s.newValue1(ssa.OpITab, byteptr, iface) // type word of interface
|
||||||
if Debug.TypeAssert > 0 {
|
if base.Debug.TypeAssert > 0 {
|
||||||
Warnl(n.Pos, "type assertion inlined")
|
base.WarnfAt(n.Pos, "type assertion inlined")
|
||||||
}
|
}
|
||||||
var targetITab *ssa.Value
|
var targetITab *ssa.Value
|
||||||
if n.Left.Type.IsEmptyInterface() {
|
if n.Left.Type.IsEmptyInterface() {
|
||||||
|
|
@ -6235,9 +6236,9 @@ func emitStackObjects(e *ssafn, pp *Progs) {
|
||||||
p.To.Name = obj.NAME_EXTERN
|
p.To.Name = obj.NAME_EXTERN
|
||||||
p.To.Sym = x
|
p.To.Sym = x
|
||||||
|
|
||||||
if Flag.Live != 0 {
|
if base.Flag.Live != 0 {
|
||||||
for _, v := range vars {
|
for _, v := range vars {
|
||||||
Warnl(v.Pos, "stack object %v %s", v, v.Type.String())
|
base.WarnfAt(v.Pos, "stack object %v %s", v, v.Type.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -6277,7 +6278,7 @@ func genssa(f *ssa.Func, pp *Progs) {
|
||||||
|
|
||||||
s.ScratchFpMem = e.scratchFpMem
|
s.ScratchFpMem = e.scratchFpMem
|
||||||
|
|
||||||
if Ctxt.Flag_locationlists {
|
if base.Ctxt.Flag_locationlists {
|
||||||
if cap(f.Cache.ValueToProgAfter) < f.NumValues() {
|
if cap(f.Cache.ValueToProgAfter) < f.NumValues() {
|
||||||
f.Cache.ValueToProgAfter = make([]*obj.Prog, f.NumValues())
|
f.Cache.ValueToProgAfter = make([]*obj.Prog, f.NumValues())
|
||||||
}
|
}
|
||||||
|
|
@ -6373,7 +6374,7 @@ func genssa(f *ssa.Func, pp *Progs) {
|
||||||
thearch.SSAGenValue(&s, v)
|
thearch.SSAGenValue(&s, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
if Ctxt.Flag_locationlists {
|
if base.Ctxt.Flag_locationlists {
|
||||||
valueToProgAfter[v.ID] = s.pp.next
|
valueToProgAfter[v.ID] = s.pp.next
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -6397,7 +6398,7 @@ func genssa(f *ssa.Func, pp *Progs) {
|
||||||
}
|
}
|
||||||
// Emit control flow instructions for block
|
// Emit control flow instructions for block
|
||||||
var next *ssa.Block
|
var next *ssa.Block
|
||||||
if i < len(f.Blocks)-1 && Flag.N == 0 {
|
if i < len(f.Blocks)-1 && base.Flag.N == 0 {
|
||||||
// If -N, leave next==nil so every block with successors
|
// If -N, leave next==nil so every block with successors
|
||||||
// ends in a JMP (except call blocks - plive doesn't like
|
// ends in a JMP (except call blocks - plive doesn't like
|
||||||
// select{send,recv} followed by a JMP call). Helps keep
|
// select{send,recv} followed by a JMP call). Helps keep
|
||||||
|
|
@ -6473,8 +6474,8 @@ func genssa(f *ssa.Func, pp *Progs) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if Ctxt.Flag_locationlists {
|
if base.Ctxt.Flag_locationlists {
|
||||||
e.curfn.Func.DebugInfo = ssa.BuildFuncDebug(Ctxt, f, Debug.LocationLists > 1, stackOffset)
|
e.curfn.Func.DebugInfo = ssa.BuildFuncDebug(base.Ctxt, f, base.Debug.LocationLists > 1, stackOffset)
|
||||||
bstart := s.bstart
|
bstart := s.bstart
|
||||||
// Note that at this moment, Prog.Pc is a sequence number; it's
|
// Note that at this moment, Prog.Pc is a sequence number; it's
|
||||||
// not a real PC until after assembly, so this mapping has to
|
// not a real PC until after assembly, so this mapping has to
|
||||||
|
|
@ -6705,7 +6706,7 @@ func (s *state) extendIndex(idx, len *ssa.Value, kind ssa.BoundsKind, bounded bo
|
||||||
} else {
|
} else {
|
||||||
lo = s.newValue1(ssa.OpInt64Lo, types.Types[TUINT], idx)
|
lo = s.newValue1(ssa.OpInt64Lo, types.Types[TUINT], idx)
|
||||||
}
|
}
|
||||||
if bounded || Flag.B != 0 {
|
if bounded || base.Flag.B != 0 {
|
||||||
return lo
|
return lo
|
||||||
}
|
}
|
||||||
bNext := s.f.NewBlock(ssa.BlockPlain)
|
bNext := s.f.NewBlock(ssa.BlockPlain)
|
||||||
|
|
@ -6807,7 +6808,7 @@ func CheckLoweredPhi(v *ssa.Value) {
|
||||||
func CheckLoweredGetClosurePtr(v *ssa.Value) {
|
func CheckLoweredGetClosurePtr(v *ssa.Value) {
|
||||||
entry := v.Block.Func.Entry
|
entry := v.Block.Func.Entry
|
||||||
if entry != v.Block || entry.Values[0] != v {
|
if entry != v.Block || entry.Values[0] != v {
|
||||||
Fatalf("in %s, badly placed LoweredGetClosurePtr: %v %v", v.Block.Func.Name, v.Block, v)
|
base.Fatalf("in %s, badly placed LoweredGetClosurePtr: %v %v", v.Block.Func.Name, v.Block, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -6869,7 +6870,7 @@ func (s *SSAGenState) Call(v *ssa.Value) *obj.Prog {
|
||||||
case sys.ARM, sys.ARM64, sys.MIPS, sys.MIPS64:
|
case sys.ARM, sys.ARM64, sys.MIPS, sys.MIPS64:
|
||||||
p.To.Type = obj.TYPE_MEM
|
p.To.Type = obj.TYPE_MEM
|
||||||
default:
|
default:
|
||||||
Fatalf("unknown indirect call family")
|
base.Fatalf("unknown indirect call family")
|
||||||
}
|
}
|
||||||
p.To.Reg = v.Args[0].Reg()
|
p.To.Reg = v.Args[0].Reg()
|
||||||
}
|
}
|
||||||
|
|
@ -6884,7 +6885,7 @@ func (s *SSAGenState) PrepareCall(v *ssa.Value) {
|
||||||
if !idx.StackMapValid() {
|
if !idx.StackMapValid() {
|
||||||
// See Liveness.hasStackMap.
|
// See Liveness.hasStackMap.
|
||||||
if sym, ok := v.Aux.(*ssa.AuxCall); !ok || !(sym.Fn == typedmemclr || sym.Fn == typedmemmove) {
|
if sym, ok := v.Aux.(*ssa.AuxCall); !ok || !(sym.Fn == typedmemclr || sym.Fn == typedmemmove) {
|
||||||
Fatalf("missing stack map index for %v", v.LongString())
|
base.Fatalf("missing stack map index for %v", v.LongString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -7085,7 +7086,7 @@ func (e *ssafn) CanSSA(t *types.Type) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ssafn) Line(pos src.XPos) string {
|
func (e *ssafn) Line(pos src.XPos) string {
|
||||||
return linestr(pos)
|
return base.FmtPos(pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log logs a message from the compiler.
|
// Log logs a message from the compiler.
|
||||||
|
|
@ -7101,23 +7102,23 @@ func (e *ssafn) Log() bool {
|
||||||
|
|
||||||
// Fatal reports a compiler error and exits.
|
// Fatal reports a compiler error and exits.
|
||||||
func (e *ssafn) Fatalf(pos src.XPos, msg string, args ...interface{}) {
|
func (e *ssafn) Fatalf(pos src.XPos, msg string, args ...interface{}) {
|
||||||
lineno = pos
|
base.Pos = pos
|
||||||
nargs := append([]interface{}{e.curfn.funcname()}, args...)
|
nargs := append([]interface{}{e.curfn.funcname()}, args...)
|
||||||
Fatalf("'%s': "+msg, nargs...)
|
base.Fatalf("'%s': "+msg, nargs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Warnl reports a "warning", which is usually flag-triggered
|
// Warnl reports a "warning", which is usually flag-triggered
|
||||||
// logging output for the benefit of tests.
|
// logging output for the benefit of tests.
|
||||||
func (e *ssafn) Warnl(pos src.XPos, fmt_ string, args ...interface{}) {
|
func (e *ssafn) Warnl(pos src.XPos, fmt_ string, args ...interface{}) {
|
||||||
Warnl(pos, fmt_, args...)
|
base.WarnfAt(pos, fmt_, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ssafn) Debug_checknil() bool {
|
func (e *ssafn) Debug_checknil() bool {
|
||||||
return Debug.Nil != 0
|
return base.Debug.Nil != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ssafn) UseWriteBarrier() bool {
|
func (e *ssafn) UseWriteBarrier() bool {
|
||||||
return Flag.WB
|
return base.Flag.WB
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ssafn) Syslook(name string) *obj.LSym {
|
func (e *ssafn) Syslook(name string) *obj.LSym {
|
||||||
|
|
@ -7142,7 +7143,7 @@ func (e *ssafn) SetWBPos(pos src.XPos) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ssafn) MyImportPath() string {
|
func (e *ssafn) MyImportPath() string {
|
||||||
return Ctxt.Pkgpath
|
return base.Ctxt.Pkgpath
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) Typ() *types.Type {
|
func (n *Node) Typ() *types.Type {
|
||||||
|
|
@ -7157,7 +7158,7 @@ func (n *Node) StorageClass() ssa.StorageClass {
|
||||||
case PAUTO:
|
case PAUTO:
|
||||||
return ssa.ClassAuto
|
return ssa.ClassAuto
|
||||||
default:
|
default:
|
||||||
Fatalf("untranslatable storage class for %v: %s", n, n.Class())
|
base.Fatalf("untranslatable storage class for %v: %s", n, n.Class())
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/src"
|
"cmd/internal/src"
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
|
|
@ -49,8 +50,8 @@ func hasUniquePos(n *Node) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !n.Pos.IsKnown() {
|
if !n.Pos.IsKnown() {
|
||||||
if Flag.K != 0 {
|
if base.Flag.K != 0 {
|
||||||
Warn("setlineno: unknown position (line 0)")
|
base.Warn("setlineno: unknown position (line 0)")
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
@ -59,9 +60,9 @@ func hasUniquePos(n *Node) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func setlineno(n *Node) src.XPos {
|
func setlineno(n *Node) src.XPos {
|
||||||
lno := lineno
|
lno := base.Pos
|
||||||
if n != nil && hasUniquePos(n) {
|
if n != nil && hasUniquePos(n) {
|
||||||
lineno = n.Pos
|
base.Pos = n.Pos
|
||||||
}
|
}
|
||||||
return lno
|
return lno
|
||||||
}
|
}
|
||||||
|
|
@ -87,11 +88,11 @@ func lookupN(prefix string, n int) *types.Sym {
|
||||||
// user labels.
|
// user labels.
|
||||||
func autolabel(prefix string) *types.Sym {
|
func autolabel(prefix string) *types.Sym {
|
||||||
if prefix[0] != '.' {
|
if prefix[0] != '.' {
|
||||||
Fatalf("autolabel prefix must start with '.', have %q", prefix)
|
base.Fatalf("autolabel prefix must start with '.', have %q", prefix)
|
||||||
}
|
}
|
||||||
fn := Curfn
|
fn := Curfn
|
||||||
if Curfn == nil {
|
if Curfn == nil {
|
||||||
Fatalf("autolabel outside function")
|
base.Fatalf("autolabel outside function")
|
||||||
}
|
}
|
||||||
n := fn.Func.Label
|
n := fn.Func.Label
|
||||||
fn.Func.Label++
|
fn.Func.Label++
|
||||||
|
|
@ -112,7 +113,7 @@ func importdot(opkg *types.Pkg, pack *Node) {
|
||||||
s1 := lookup(s.Name)
|
s1 := lookup(s.Name)
|
||||||
if s1.Def != nil {
|
if s1.Def != nil {
|
||||||
pkgerror := fmt.Sprintf("during import %q", opkg.Path)
|
pkgerror := fmt.Sprintf("during import %q", opkg.Path)
|
||||||
redeclare(lineno, s1, pkgerror)
|
redeclare(base.Pos, s1, pkgerror)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -120,7 +121,7 @@ func importdot(opkg *types.Pkg, pack *Node) {
|
||||||
s1.Block = s.Block
|
s1.Block = s.Block
|
||||||
if asNode(s1.Def).Name == nil {
|
if asNode(s1.Def).Name == nil {
|
||||||
Dump("s1def", asNode(s1.Def))
|
Dump("s1def", asNode(s1.Def))
|
||||||
Fatalf("missing Name")
|
base.Fatalf("missing Name")
|
||||||
}
|
}
|
||||||
asNode(s1.Def).Name.Pack = pack
|
asNode(s1.Def).Name.Pack = pack
|
||||||
s1.Origpkg = opkg
|
s1.Origpkg = opkg
|
||||||
|
|
@ -129,12 +130,12 @@ func importdot(opkg *types.Pkg, pack *Node) {
|
||||||
|
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
// can't possibly be used - there were no symbols
|
// can't possibly be used - there were no symbols
|
||||||
yyerrorl(pack.Pos, "imported and not used: %q", opkg.Path)
|
base.ErrorfAt(pack.Pos, "imported and not used: %q", opkg.Path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func nod(op Op, nleft, nright *Node) *Node {
|
func nod(op Op, nleft, nright *Node) *Node {
|
||||||
return nodl(lineno, op, nleft, nright)
|
return nodl(base.Pos, op, nleft, nright)
|
||||||
}
|
}
|
||||||
|
|
||||||
func nodl(pos src.XPos, op Op, nleft, nright *Node) *Node {
|
func nodl(pos src.XPos, op Op, nleft, nright *Node) *Node {
|
||||||
|
|
@ -149,7 +150,7 @@ func nodl(pos src.XPos, op Op, nleft, nright *Node) *Node {
|
||||||
n.Func = &x.f
|
n.Func = &x.f
|
||||||
n.Func.Decl = n
|
n.Func.Decl = n
|
||||||
case ONAME:
|
case ONAME:
|
||||||
Fatalf("use newname instead")
|
base.Fatalf("use newname instead")
|
||||||
case OLABEL, OPACK:
|
case OLABEL, OPACK:
|
||||||
var x struct {
|
var x struct {
|
||||||
n Node
|
n Node
|
||||||
|
|
@ -171,7 +172,7 @@ func nodl(pos src.XPos, op Op, nleft, nright *Node) *Node {
|
||||||
|
|
||||||
// newname returns a new ONAME Node associated with symbol s.
|
// newname returns a new ONAME Node associated with symbol s.
|
||||||
func newname(s *types.Sym) *Node {
|
func newname(s *types.Sym) *Node {
|
||||||
n := newnamel(lineno, s)
|
n := newnamel(base.Pos, s)
|
||||||
n.Name.Curfn = Curfn
|
n.Name.Curfn = Curfn
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
@ -180,7 +181,7 @@ func newname(s *types.Sym) *Node {
|
||||||
// The caller is responsible for setting n.Name.Curfn.
|
// The caller is responsible for setting n.Name.Curfn.
|
||||||
func newnamel(pos src.XPos, s *types.Sym) *Node {
|
func newnamel(pos src.XPos, s *types.Sym) *Node {
|
||||||
if s == nil {
|
if s == nil {
|
||||||
Fatalf("newnamel nil")
|
base.Fatalf("newnamel nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
var x struct {
|
var x struct {
|
||||||
|
|
@ -203,7 +204,7 @@ func newnamel(pos src.XPos, s *types.Sym) *Node {
|
||||||
// nodSym makes a Node with Op op and with the Left field set to left
|
// nodSym makes a Node with Op op and with the Left field set to left
|
||||||
// and the Sym field set to sym. This is for ODOT and friends.
|
// and the Sym field set to sym. This is for ODOT and friends.
|
||||||
func nodSym(op Op, left *Node, sym *types.Sym) *Node {
|
func nodSym(op Op, left *Node, sym *types.Sym) *Node {
|
||||||
return nodlSym(lineno, op, left, sym)
|
return nodlSym(base.Pos, op, left, sym)
|
||||||
}
|
}
|
||||||
|
|
||||||
// nodlSym makes a Node with position Pos, with Op op, and with the Left field set to left
|
// nodlSym makes a Node with position Pos, with Op op, and with the Left field set to left
|
||||||
|
|
@ -290,7 +291,7 @@ func treecopy(n *Node, pos src.XPos) *Node {
|
||||||
}
|
}
|
||||||
if m.Name != nil && n.Op != ODCLFIELD {
|
if m.Name != nil && n.Op != ODCLFIELD {
|
||||||
Dump("treecopy", n)
|
Dump("treecopy", n)
|
||||||
Fatalf("treecopy Name")
|
base.Fatalf("treecopy Name")
|
||||||
}
|
}
|
||||||
return m
|
return m
|
||||||
|
|
||||||
|
|
@ -625,7 +626,7 @@ func assignconvfn(n *Node, t *types.Type, context func() string) *Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.Etype == TBLANK && n.Type.Etype == TNIL {
|
if t.Etype == TBLANK && n.Type.Etype == TNIL {
|
||||||
yyerror("use of untyped nil")
|
base.Errorf("use of untyped nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
n = convlit1(n, t, false, context)
|
n = convlit1(n, t, false, context)
|
||||||
|
|
@ -654,7 +655,7 @@ func assignconvfn(n *Node, t *types.Type, context func() string) *Node {
|
||||||
|
|
||||||
op, why := assignop(n.Type, t)
|
op, why := assignop(n.Type, t)
|
||||||
if op == OXXX {
|
if op == OXXX {
|
||||||
yyerror("cannot use %L as type %v in %s%s", n, t, context(), why)
|
base.Errorf("cannot use %L as type %v in %s%s", n, t, context(), why)
|
||||||
op = OCONV
|
op = OCONV
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -687,7 +688,7 @@ func (n *Node) SliceBounds() (low, high, max *Node) {
|
||||||
s := n.List.Slice()
|
s := n.List.Slice()
|
||||||
return s[0], s[1], s[2]
|
return s[0], s[1], s[2]
|
||||||
}
|
}
|
||||||
Fatalf("SliceBounds op %v: %v", n.Op, n)
|
base.Fatalf("SliceBounds op %v: %v", n.Op, n)
|
||||||
return nil, nil, nil
|
return nil, nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -697,7 +698,7 @@ func (n *Node) SetSliceBounds(low, high, max *Node) {
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
case OSLICE, OSLICEARR, OSLICESTR:
|
case OSLICE, OSLICEARR, OSLICESTR:
|
||||||
if max != nil {
|
if max != nil {
|
||||||
Fatalf("SetSliceBounds %v given three bounds", n.Op)
|
base.Fatalf("SetSliceBounds %v given three bounds", n.Op)
|
||||||
}
|
}
|
||||||
s := n.List.Slice()
|
s := n.List.Slice()
|
||||||
if s == nil {
|
if s == nil {
|
||||||
|
|
@ -724,7 +725,7 @@ func (n *Node) SetSliceBounds(low, high, max *Node) {
|
||||||
s[2] = max
|
s[2] = max
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Fatalf("SetSliceBounds op %v: %v", n.Op, n)
|
base.Fatalf("SetSliceBounds op %v: %v", n.Op, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsSlice3 reports whether o is a slice3 op (OSLICE3, OSLICE3ARR).
|
// IsSlice3 reports whether o is a slice3 op (OSLICE3, OSLICE3ARR).
|
||||||
|
|
@ -736,7 +737,7 @@ func (o Op) IsSlice3() bool {
|
||||||
case OSLICE3, OSLICE3ARR:
|
case OSLICE3, OSLICE3ARR:
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
Fatalf("IsSlice3 op %v", o)
|
base.Fatalf("IsSlice3 op %v", o)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -746,7 +747,7 @@ func (n *Node) backingArrayPtrLen() (ptr, len *Node) {
|
||||||
var init Nodes
|
var init Nodes
|
||||||
c := cheapexpr(n, &init)
|
c := cheapexpr(n, &init)
|
||||||
if c != n || init.Len() != 0 {
|
if c != n || init.Len() != 0 {
|
||||||
Fatalf("backingArrayPtrLen not cheap: %v", n)
|
base.Fatalf("backingArrayPtrLen not cheap: %v", n)
|
||||||
}
|
}
|
||||||
ptr = nod(OSPTR, n, nil)
|
ptr = nod(OSPTR, n, nil)
|
||||||
if n.Type.IsString() {
|
if n.Type.IsString() {
|
||||||
|
|
@ -763,7 +764,7 @@ func (n *Node) backingArrayPtrLen() (ptr, len *Node) {
|
||||||
// associated with the label n, if any.
|
// associated with the label n, if any.
|
||||||
func (n *Node) labeledControl() *Node {
|
func (n *Node) labeledControl() *Node {
|
||||||
if n.Op != OLABEL {
|
if n.Op != OLABEL {
|
||||||
Fatalf("labeledControl %v", n.Op)
|
base.Fatalf("labeledControl %v", n.Op)
|
||||||
}
|
}
|
||||||
ctl := n.Name.Defn
|
ctl := n.Name.Defn
|
||||||
if ctl == nil {
|
if ctl == nil {
|
||||||
|
|
@ -779,7 +780,7 @@ func (n *Node) labeledControl() *Node {
|
||||||
func syslook(name string) *Node {
|
func syslook(name string) *Node {
|
||||||
s := Runtimepkg.Lookup(name)
|
s := Runtimepkg.Lookup(name)
|
||||||
if s == nil || s.Def == nil {
|
if s == nil || s.Def == nil {
|
||||||
Fatalf("syslook: can't find runtime.%s", name)
|
base.Fatalf("syslook: can't find runtime.%s", name)
|
||||||
}
|
}
|
||||||
return asNode(s.Def)
|
return asNode(s.Def)
|
||||||
}
|
}
|
||||||
|
|
@ -811,7 +812,7 @@ func calcHasCall(n *Node) bool {
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
case OLITERAL, ONIL, ONAME, OTYPE:
|
case OLITERAL, ONIL, ONAME, OTYPE:
|
||||||
if n.HasCall() {
|
if n.HasCall() {
|
||||||
Fatalf("OLITERAL/ONAME/OTYPE should never have calls: %+v", n)
|
base.Fatalf("OLITERAL/ONAME/OTYPE should never have calls: %+v", n)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER:
|
case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER:
|
||||||
|
|
@ -870,7 +871,7 @@ func badtype(op Op, tl, tr *types.Type) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
yyerror("illegal types for operand: %v%s", op, s)
|
base.Errorf("illegal types for operand: %v%s", op, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
// brcom returns !(op).
|
// brcom returns !(op).
|
||||||
|
|
@ -890,7 +891,7 @@ func brcom(op Op) Op {
|
||||||
case OGE:
|
case OGE:
|
||||||
return OLT
|
return OLT
|
||||||
}
|
}
|
||||||
Fatalf("brcom: no com for %v\n", op)
|
base.Fatalf("brcom: no com for %v\n", op)
|
||||||
return op
|
return op
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -911,7 +912,7 @@ func brrev(op Op) Op {
|
||||||
case OGE:
|
case OGE:
|
||||||
return OLE
|
return OLE
|
||||||
}
|
}
|
||||||
Fatalf("brrev: no rev for %v\n", op)
|
base.Fatalf("brrev: no rev for %v\n", op)
|
||||||
return op
|
return op
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -972,7 +973,7 @@ func safeexpr(n *Node, init *Nodes) *Node {
|
||||||
|
|
||||||
// make a copy; must not be used as an lvalue
|
// make a copy; must not be used as an lvalue
|
||||||
if islvalue(n) {
|
if islvalue(n) {
|
||||||
Fatalf("missing lvalue case in safeexpr: %v", n)
|
base.Fatalf("missing lvalue case in safeexpr: %v", n)
|
||||||
}
|
}
|
||||||
return cheapexpr(n, init)
|
return cheapexpr(n, init)
|
||||||
}
|
}
|
||||||
|
|
@ -1161,7 +1162,7 @@ func adddot(n *Node) *Node {
|
||||||
n.Left.SetImplicit(true)
|
n.Left.SetImplicit(true)
|
||||||
}
|
}
|
||||||
case ambig:
|
case ambig:
|
||||||
yyerror("ambiguous selector %v", n)
|
base.Errorf("ambiguous selector %v", n)
|
||||||
n.Left = nil
|
n.Left = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1334,7 +1335,7 @@ func structargs(tl *types.Type, mustname bool) []*Node {
|
||||||
// method - M func (t T)(), a TFIELD type struct
|
// method - M func (t T)(), a TFIELD type struct
|
||||||
// newnam - the eventual mangled name of this function
|
// newnam - the eventual mangled name of this function
|
||||||
func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) {
|
func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) {
|
||||||
if false && Flag.LowerR != 0 {
|
if false && base.Flag.LowerR != 0 {
|
||||||
fmt.Printf("genwrapper rcvrtype=%v method=%v newnam=%v\n", rcvr, method, newnam)
|
fmt.Printf("genwrapper rcvrtype=%v method=%v newnam=%v\n", rcvr, method, newnam)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1350,7 +1351,7 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
lineno = autogeneratedPos
|
base.Pos = autogeneratedPos
|
||||||
dclcontext = PEXTERN
|
dclcontext = PEXTERN
|
||||||
|
|
||||||
tfn := nod(OTFUNC, nil, nil)
|
tfn := nod(OTFUNC, nil, nil)
|
||||||
|
|
@ -1384,7 +1385,7 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) {
|
||||||
// the TOC to the appropriate value for that module. But if it returns
|
// the TOC to the appropriate value for that module. But if it returns
|
||||||
// directly to the wrapper's caller, nothing will reset it to the correct
|
// directly to the wrapper's caller, nothing will reset it to the correct
|
||||||
// value for that function.
|
// value for that function.
|
||||||
if !instrumenting && rcvr.IsPtr() && methodrcvr.IsPtr() && method.Embedded != 0 && !isifacemethod(method.Type) && !(thearch.LinkArch.Name == "ppc64le" && Ctxt.Flag_dynlink) {
|
if !instrumenting && rcvr.IsPtr() && methodrcvr.IsPtr() && method.Embedded != 0 && !isifacemethod(method.Type) && !(thearch.LinkArch.Name == "ppc64le" && base.Ctxt.Flag_dynlink) {
|
||||||
// generate tail call: adjust pointer receiver and jump to embedded method.
|
// generate tail call: adjust pointer receiver and jump to embedded method.
|
||||||
dot = dot.Left // skip final .M
|
dot = dot.Left // skip final .M
|
||||||
// TODO(mdempsky): Remove dependency on dotlist.
|
// TODO(mdempsky): Remove dependency on dotlist.
|
||||||
|
|
@ -1407,12 +1408,12 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) {
|
||||||
fn.Nbody.Append(call)
|
fn.Nbody.Append(call)
|
||||||
}
|
}
|
||||||
|
|
||||||
if false && Flag.LowerR != 0 {
|
if false && base.Flag.LowerR != 0 {
|
||||||
dumplist("genwrapper body", fn.Nbody)
|
dumplist("genwrapper body", fn.Nbody)
|
||||||
}
|
}
|
||||||
|
|
||||||
funcbody()
|
funcbody()
|
||||||
if Debug.DclStack != 0 {
|
if base.Debug.DclStack != 0 {
|
||||||
testdclstack()
|
testdclstack()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1464,7 +1465,7 @@ func ifacelookdot(s *types.Sym, t *types.Type, ignorecase bool) (m *types.Field,
|
||||||
path, ambig := dotpath(s, t, &m, ignorecase)
|
path, ambig := dotpath(s, t, &m, ignorecase)
|
||||||
if path == nil {
|
if path == nil {
|
||||||
if ambig {
|
if ambig {
|
||||||
yyerror("%v.%v is ambiguous", t, s)
|
base.Errorf("%v.%v is ambiguous", t, s)
|
||||||
}
|
}
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
@ -1477,7 +1478,7 @@ func ifacelookdot(s *types.Sym, t *types.Type, ignorecase bool) (m *types.Field,
|
||||||
}
|
}
|
||||||
|
|
||||||
if !m.IsMethod() {
|
if !m.IsMethod() {
|
||||||
yyerror("%v.%v is a field, not a method", t, s)
|
base.Errorf("%v.%v is a field, not a method", t, s)
|
||||||
return nil, followptr
|
return nil, followptr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1548,8 +1549,8 @@ func implements(t, iface *types.Type, m, samename **types.Field, ptr *int) bool
|
||||||
// the method does not exist for value types.
|
// the method does not exist for value types.
|
||||||
rcvr := tm.Type.Recv().Type
|
rcvr := tm.Type.Recv().Type
|
||||||
if rcvr.IsPtr() && !t0.IsPtr() && !followptr && !isifacemethod(tm.Type) {
|
if rcvr.IsPtr() && !t0.IsPtr() && !followptr && !isifacemethod(tm.Type) {
|
||||||
if false && Flag.LowerR != 0 {
|
if false && base.Flag.LowerR != 0 {
|
||||||
yyerror("interface pointer mismatch")
|
base.Errorf("interface pointer mismatch")
|
||||||
}
|
}
|
||||||
|
|
||||||
*m = im
|
*m = im
|
||||||
|
|
@ -1624,40 +1625,40 @@ var reservedimports = []string{
|
||||||
|
|
||||||
func isbadimport(path string, allowSpace bool) bool {
|
func isbadimport(path string, allowSpace bool) bool {
|
||||||
if strings.Contains(path, "\x00") {
|
if strings.Contains(path, "\x00") {
|
||||||
yyerror("import path contains NUL")
|
base.Errorf("import path contains NUL")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, ri := range reservedimports {
|
for _, ri := range reservedimports {
|
||||||
if path == ri {
|
if path == ri {
|
||||||
yyerror("import path %q is reserved and cannot be used", path)
|
base.Errorf("import path %q is reserved and cannot be used", path)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, r := range path {
|
for _, r := range path {
|
||||||
if r == utf8.RuneError {
|
if r == utf8.RuneError {
|
||||||
yyerror("import path contains invalid UTF-8 sequence: %q", path)
|
base.Errorf("import path contains invalid UTF-8 sequence: %q", path)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if r < 0x20 || r == 0x7f {
|
if r < 0x20 || r == 0x7f {
|
||||||
yyerror("import path contains control character: %q", path)
|
base.Errorf("import path contains control character: %q", path)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if r == '\\' {
|
if r == '\\' {
|
||||||
yyerror("import path contains backslash; use slash: %q", path)
|
base.Errorf("import path contains backslash; use slash: %q", path)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if !allowSpace && unicode.IsSpace(r) {
|
if !allowSpace && unicode.IsSpace(r) {
|
||||||
yyerror("import path contains space character: %q", path)
|
base.Errorf("import path contains space character: %q", path)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.ContainsRune("!\"#$%&'()*,:;<=>?[]^`{|}", r) {
|
if strings.ContainsRune("!\"#$%&'()*,:;<=>?[]^`{|}", r) {
|
||||||
yyerror("import path contains invalid character '%c': %q", r, path)
|
base.Errorf("import path contains invalid character '%c': %q", r, path)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1709,7 +1710,7 @@ func itabType(itab *Node) *Node {
|
||||||
// It follows the pointer if !isdirectiface(t).
|
// It follows the pointer if !isdirectiface(t).
|
||||||
func ifaceData(pos src.XPos, n *Node, t *types.Type) *Node {
|
func ifaceData(pos src.XPos, n *Node, t *types.Type) *Node {
|
||||||
if t.IsInterface() {
|
if t.IsInterface() {
|
||||||
Fatalf("ifaceData interface: %v", t)
|
base.Fatalf("ifaceData interface: %v", t)
|
||||||
}
|
}
|
||||||
ptr := nodlSym(pos, OIDATA, n, nil)
|
ptr := nodlSym(pos, OIDATA, n, nil)
|
||||||
if isdirectiface(t) {
|
if isdirectiface(t) {
|
||||||
|
|
@ -1731,7 +1732,7 @@ func ifaceData(pos src.XPos, n *Node, t *types.Type) *Node {
|
||||||
func typePos(t *types.Type) src.XPos {
|
func typePos(t *types.Type) src.XPos {
|
||||||
n := asNode(t.Nod)
|
n := asNode(t.Nod)
|
||||||
if n == nil || !n.Pos.IsKnown() {
|
if n == nil || !n.Pos.IsKnown() {
|
||||||
Fatalf("bad type: %v", t)
|
base.Fatalf("bad type: %v", t)
|
||||||
}
|
}
|
||||||
return n.Pos
|
return n.Pos
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/src"
|
"cmd/internal/src"
|
||||||
"go/constant"
|
"go/constant"
|
||||||
|
|
@ -26,7 +27,7 @@ func typecheckTypeSwitch(n *Node) {
|
||||||
n.Left.Right = typecheck(n.Left.Right, ctxExpr)
|
n.Left.Right = typecheck(n.Left.Right, ctxExpr)
|
||||||
t := n.Left.Right.Type
|
t := n.Left.Right.Type
|
||||||
if t != nil && !t.IsInterface() {
|
if t != nil && !t.IsInterface() {
|
||||||
yyerrorl(n.Pos, "cannot type switch on non-interface value %L", n.Left.Right)
|
base.ErrorfAt(n.Pos, "cannot type switch on non-interface value %L", n.Left.Right)
|
||||||
t = nil
|
t = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -34,7 +35,7 @@ func typecheckTypeSwitch(n *Node) {
|
||||||
// declaration itself. So if there are no cases, we won't
|
// declaration itself. So if there are no cases, we won't
|
||||||
// notice that it went unused.
|
// notice that it went unused.
|
||||||
if v := n.Left.Left; v != nil && !v.isBlank() && n.List.Len() == 0 {
|
if v := n.Left.Left; v != nil && !v.isBlank() && n.List.Len() == 0 {
|
||||||
yyerrorl(v.Pos, "%v declared but not used", v.Sym)
|
base.ErrorfAt(v.Pos, "%v declared but not used", v.Sym)
|
||||||
}
|
}
|
||||||
|
|
||||||
var defCase, nilCase *Node
|
var defCase, nilCase *Node
|
||||||
|
|
@ -43,7 +44,7 @@ func typecheckTypeSwitch(n *Node) {
|
||||||
ls := ncase.List.Slice()
|
ls := ncase.List.Slice()
|
||||||
if len(ls) == 0 { // default:
|
if len(ls) == 0 { // default:
|
||||||
if defCase != nil {
|
if defCase != nil {
|
||||||
yyerrorl(ncase.Pos, "multiple defaults in switch (first at %v)", defCase.Line())
|
base.ErrorfAt(ncase.Pos, "multiple defaults in switch (first at %v)", defCase.Line())
|
||||||
} else {
|
} else {
|
||||||
defCase = ncase
|
defCase = ncase
|
||||||
}
|
}
|
||||||
|
|
@ -61,21 +62,21 @@ func typecheckTypeSwitch(n *Node) {
|
||||||
switch {
|
switch {
|
||||||
case n1.isNil(): // case nil:
|
case n1.isNil(): // case nil:
|
||||||
if nilCase != nil {
|
if nilCase != nil {
|
||||||
yyerrorl(ncase.Pos, "multiple nil cases in type switch (first at %v)", nilCase.Line())
|
base.ErrorfAt(ncase.Pos, "multiple nil cases in type switch (first at %v)", nilCase.Line())
|
||||||
} else {
|
} else {
|
||||||
nilCase = ncase
|
nilCase = ncase
|
||||||
}
|
}
|
||||||
case n1.Op != OTYPE:
|
case n1.Op != OTYPE:
|
||||||
yyerrorl(ncase.Pos, "%L is not a type", n1)
|
base.ErrorfAt(ncase.Pos, "%L is not a type", n1)
|
||||||
case !n1.Type.IsInterface() && !implements(n1.Type, t, &missing, &have, &ptr) && !missing.Broke():
|
case !n1.Type.IsInterface() && !implements(n1.Type, t, &missing, &have, &ptr) && !missing.Broke():
|
||||||
if have != nil && !have.Broke() {
|
if have != nil && !have.Broke() {
|
||||||
yyerrorl(ncase.Pos, "impossible type switch case: %L cannot have dynamic type %v"+
|
base.ErrorfAt(ncase.Pos, "impossible type switch case: %L cannot have dynamic type %v"+
|
||||||
" (wrong type for %v method)\n\thave %v%S\n\twant %v%S", n.Left.Right, n1.Type, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
|
" (wrong type for %v method)\n\thave %v%S\n\twant %v%S", n.Left.Right, n1.Type, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
|
||||||
} else if ptr != 0 {
|
} else if ptr != 0 {
|
||||||
yyerrorl(ncase.Pos, "impossible type switch case: %L cannot have dynamic type %v"+
|
base.ErrorfAt(ncase.Pos, "impossible type switch case: %L cannot have dynamic type %v"+
|
||||||
" (%v method has pointer receiver)", n.Left.Right, n1.Type, missing.Sym)
|
" (%v method has pointer receiver)", n.Left.Right, n1.Type, missing.Sym)
|
||||||
} else {
|
} else {
|
||||||
yyerrorl(ncase.Pos, "impossible type switch case: %L cannot have dynamic type %v"+
|
base.ErrorfAt(ncase.Pos, "impossible type switch case: %L cannot have dynamic type %v"+
|
||||||
" (missing %v method)", n.Left.Right, n1.Type, missing.Sym)
|
" (missing %v method)", n.Left.Right, n1.Type, missing.Sym)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -135,7 +136,7 @@ func (s *typeSet) add(pos src.XPos, typ *types.Type) {
|
||||||
prevs := s.m[ls]
|
prevs := s.m[ls]
|
||||||
for _, prev := range prevs {
|
for _, prev := range prevs {
|
||||||
if types.Identical(typ, prev.typ) {
|
if types.Identical(typ, prev.typ) {
|
||||||
yyerrorl(pos, "duplicate case %v in type switch\n\tprevious case at %s", typ, linestr(prev.pos))
|
base.ErrorfAt(pos, "duplicate case %v in type switch\n\tprevious case at %s", typ, base.FmtPos(prev.pos))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -162,9 +163,9 @@ func typecheckExprSwitch(n *Node) {
|
||||||
|
|
||||||
case !IsComparable(t):
|
case !IsComparable(t):
|
||||||
if t.IsStruct() {
|
if t.IsStruct() {
|
||||||
yyerrorl(n.Pos, "cannot switch on %L (struct containing %v cannot be compared)", n.Left, IncomparableField(t).Type)
|
base.ErrorfAt(n.Pos, "cannot switch on %L (struct containing %v cannot be compared)", n.Left, IncomparableField(t).Type)
|
||||||
} else {
|
} else {
|
||||||
yyerrorl(n.Pos, "cannot switch on %L", n.Left)
|
base.ErrorfAt(n.Pos, "cannot switch on %L", n.Left)
|
||||||
}
|
}
|
||||||
t = nil
|
t = nil
|
||||||
}
|
}
|
||||||
|
|
@ -176,7 +177,7 @@ func typecheckExprSwitch(n *Node) {
|
||||||
ls := ncase.List.Slice()
|
ls := ncase.List.Slice()
|
||||||
if len(ls) == 0 { // default:
|
if len(ls) == 0 { // default:
|
||||||
if defCase != nil {
|
if defCase != nil {
|
||||||
yyerrorl(ncase.Pos, "multiple defaults in switch (first at %v)", defCase.Line())
|
base.ErrorfAt(ncase.Pos, "multiple defaults in switch (first at %v)", defCase.Line())
|
||||||
} else {
|
} else {
|
||||||
defCase = ncase
|
defCase = ncase
|
||||||
}
|
}
|
||||||
|
|
@ -192,17 +193,17 @@ func typecheckExprSwitch(n *Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if nilonly != "" && !n1.isNil() {
|
if nilonly != "" && !n1.isNil() {
|
||||||
yyerrorl(ncase.Pos, "invalid case %v in switch (can only compare %s %v to nil)", n1, nilonly, n.Left)
|
base.ErrorfAt(ncase.Pos, "invalid case %v in switch (can only compare %s %v to nil)", n1, nilonly, n.Left)
|
||||||
} else if t.IsInterface() && !n1.Type.IsInterface() && !IsComparable(n1.Type) {
|
} else if t.IsInterface() && !n1.Type.IsInterface() && !IsComparable(n1.Type) {
|
||||||
yyerrorl(ncase.Pos, "invalid case %L in switch (incomparable type)", n1)
|
base.ErrorfAt(ncase.Pos, "invalid case %L in switch (incomparable type)", n1)
|
||||||
} else {
|
} else {
|
||||||
op1, _ := assignop(n1.Type, t)
|
op1, _ := assignop(n1.Type, t)
|
||||||
op2, _ := assignop(t, n1.Type)
|
op2, _ := assignop(t, n1.Type)
|
||||||
if op1 == OXXX && op2 == OXXX {
|
if op1 == OXXX && op2 == OXXX {
|
||||||
if n.Left != nil {
|
if n.Left != nil {
|
||||||
yyerrorl(ncase.Pos, "invalid case %v in switch on %v (mismatched types %v and %v)", n1, n.Left, n1.Type, t)
|
base.ErrorfAt(ncase.Pos, "invalid case %v in switch on %v (mismatched types %v and %v)", n1, n.Left, n1.Type, t)
|
||||||
} else {
|
} else {
|
||||||
yyerrorl(ncase.Pos, "invalid case %v in switch (mismatched types %v and bool)", n1, n1.Type)
|
base.ErrorfAt(ncase.Pos, "invalid case %v in switch (mismatched types %v and bool)", n1, n1.Type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -267,7 +268,7 @@ func walkExprSwitch(sw *Node) {
|
||||||
cond = copyexpr(cond, cond.Type, &sw.Nbody)
|
cond = copyexpr(cond, cond.Type, &sw.Nbody)
|
||||||
}
|
}
|
||||||
|
|
||||||
lineno = lno
|
base.Pos = lno
|
||||||
|
|
||||||
s := exprSwitch{
|
s := exprSwitch{
|
||||||
exprname: cond,
|
exprname: cond,
|
||||||
|
|
@ -282,7 +283,7 @@ func walkExprSwitch(sw *Node) {
|
||||||
// Process case dispatch.
|
// Process case dispatch.
|
||||||
if ncase.List.Len() == 0 {
|
if ncase.List.Len() == 0 {
|
||||||
if defaultGoto != nil {
|
if defaultGoto != nil {
|
||||||
Fatalf("duplicate default case not detected during typechecking")
|
base.Fatalf("duplicate default case not detected during typechecking")
|
||||||
}
|
}
|
||||||
defaultGoto = jmp
|
defaultGoto = jmp
|
||||||
}
|
}
|
||||||
|
|
@ -464,7 +465,7 @@ func allCaseExprsAreSideEffectFree(sw *Node) bool {
|
||||||
|
|
||||||
for _, ncase := range sw.List.Slice() {
|
for _, ncase := range sw.List.Slice() {
|
||||||
if ncase.Op != OCASE {
|
if ncase.Op != OCASE {
|
||||||
Fatalf("switch string(byteslice) bad op: %v", ncase.Op)
|
base.Fatalf("switch string(byteslice) bad op: %v", ncase.Op)
|
||||||
}
|
}
|
||||||
for _, v := range ncase.List.Slice() {
|
for _, v := range ncase.List.Slice() {
|
||||||
if v.Op != OLITERAL {
|
if v.Op != OLITERAL {
|
||||||
|
|
@ -517,7 +518,7 @@ func walkTypeSwitch(sw *Node) {
|
||||||
// Use a similar strategy for non-empty interfaces.
|
// Use a similar strategy for non-empty interfaces.
|
||||||
ifNil := nod(OIF, nil, nil)
|
ifNil := nod(OIF, nil, nil)
|
||||||
ifNil.Left = nod(OEQ, itab, nodnil())
|
ifNil.Left = nod(OEQ, itab, nodnil())
|
||||||
lineno = lineno.WithNotStmt() // disable statement marks after the first check.
|
base.Pos = base.Pos.WithNotStmt() // disable statement marks after the first check.
|
||||||
ifNil.Left = typecheck(ifNil.Left, ctxExpr)
|
ifNil.Left = typecheck(ifNil.Left, ctxExpr)
|
||||||
ifNil.Left = defaultlit(ifNil.Left, nil)
|
ifNil.Left = defaultlit(ifNil.Left, nil)
|
||||||
// ifNil.Nbody assigned at end.
|
// ifNil.Nbody assigned at end.
|
||||||
|
|
@ -558,7 +559,7 @@ func walkTypeSwitch(sw *Node) {
|
||||||
|
|
||||||
if ncase.List.Len() == 0 { // default:
|
if ncase.List.Len() == 0 { // default:
|
||||||
if defaultGoto != nil {
|
if defaultGoto != nil {
|
||||||
Fatalf("duplicate default case not detected during typechecking")
|
base.Fatalf("duplicate default case not detected during typechecking")
|
||||||
}
|
}
|
||||||
defaultGoto = jmp
|
defaultGoto = jmp
|
||||||
}
|
}
|
||||||
|
|
@ -566,7 +567,7 @@ func walkTypeSwitch(sw *Node) {
|
||||||
for _, n1 := range ncase.List.Slice() {
|
for _, n1 := range ncase.List.Slice() {
|
||||||
if n1.isNil() { // case nil:
|
if n1.isNil() { // case nil:
|
||||||
if nilGoto != nil {
|
if nilGoto != nil {
|
||||||
Fatalf("duplicate nil case not detected during typechecking")
|
base.Fatalf("duplicate nil case not detected during typechecking")
|
||||||
}
|
}
|
||||||
nilGoto = jmp
|
nilGoto = jmp
|
||||||
continue
|
continue
|
||||||
|
|
@ -586,7 +587,7 @@ func walkTypeSwitch(sw *Node) {
|
||||||
if singleType != nil {
|
if singleType != nil {
|
||||||
// We have a single concrete type. Extract the data.
|
// We have a single concrete type. Extract the data.
|
||||||
if singleType.IsInterface() {
|
if singleType.IsInterface() {
|
||||||
Fatalf("singleType interface should have been handled in Add")
|
base.Fatalf("singleType interface should have been handled in Add")
|
||||||
}
|
}
|
||||||
val = ifaceData(ncase.Pos, s.facename, singleType)
|
val = ifaceData(ncase.Pos, s.facename, singleType)
|
||||||
}
|
}
|
||||||
|
|
@ -733,7 +734,7 @@ func binarySearch(n int, out *Nodes, less func(i int) *Node, leaf func(i int, ni
|
||||||
for i := lo; i < hi; i++ {
|
for i := lo; i < hi; i++ {
|
||||||
nif := nod(OIF, nil, nil)
|
nif := nod(OIF, nil, nil)
|
||||||
leaf(i, nif)
|
leaf(i, nif)
|
||||||
lineno = lineno.WithNotStmt()
|
base.Pos = base.Pos.WithNotStmt()
|
||||||
nif.Left = typecheck(nif.Left, ctxExpr)
|
nif.Left = typecheck(nif.Left, ctxExpr)
|
||||||
nif.Left = defaultlit(nif.Left, nil)
|
nif.Left = defaultlit(nif.Left, nil)
|
||||||
out.Append(nif)
|
out.Append(nif)
|
||||||
|
|
@ -745,7 +746,7 @@ func binarySearch(n int, out *Nodes, less func(i int) *Node, leaf func(i int, ni
|
||||||
half := lo + n/2
|
half := lo + n/2
|
||||||
nif := nod(OIF, nil, nil)
|
nif := nod(OIF, nil, nil)
|
||||||
nif.Left = less(half)
|
nif.Left = less(half)
|
||||||
lineno = lineno.WithNotStmt()
|
base.Pos = base.Pos.WithNotStmt()
|
||||||
nif.Left = typecheck(nif.Left, ctxExpr)
|
nif.Left = typecheck(nif.Left, ctxExpr)
|
||||||
nif.Left = defaultlit(nif.Left, nil)
|
nif.Left = defaultlit(nif.Left, nil)
|
||||||
do(lo, half, &nif.Nbody)
|
do(lo, half, &nif.Nbody)
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/ssa"
|
"cmd/compile/internal/ssa"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
|
|
@ -106,7 +107,7 @@ func (n *Node) SubOp() Op {
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
case OASOP, ONAME:
|
case OASOP, ONAME:
|
||||||
default:
|
default:
|
||||||
Fatalf("unexpected op: %v", n.Op)
|
base.Fatalf("unexpected op: %v", n.Op)
|
||||||
}
|
}
|
||||||
return Op(n.aux)
|
return Op(n.aux)
|
||||||
}
|
}
|
||||||
|
|
@ -115,21 +116,21 @@ func (n *Node) SetSubOp(op Op) {
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
case OASOP, ONAME:
|
case OASOP, ONAME:
|
||||||
default:
|
default:
|
||||||
Fatalf("unexpected op: %v", n.Op)
|
base.Fatalf("unexpected op: %v", n.Op)
|
||||||
}
|
}
|
||||||
n.aux = uint8(op)
|
n.aux = uint8(op)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) IndexMapLValue() bool {
|
func (n *Node) IndexMapLValue() bool {
|
||||||
if n.Op != OINDEXMAP {
|
if n.Op != OINDEXMAP {
|
||||||
Fatalf("unexpected op: %v", n.Op)
|
base.Fatalf("unexpected op: %v", n.Op)
|
||||||
}
|
}
|
||||||
return n.aux != 0
|
return n.aux != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) SetIndexMapLValue(b bool) {
|
func (n *Node) SetIndexMapLValue(b bool) {
|
||||||
if n.Op != OINDEXMAP {
|
if n.Op != OINDEXMAP {
|
||||||
Fatalf("unexpected op: %v", n.Op)
|
base.Fatalf("unexpected op: %v", n.Op)
|
||||||
}
|
}
|
||||||
if b {
|
if b {
|
||||||
n.aux = 1
|
n.aux = 1
|
||||||
|
|
@ -140,14 +141,14 @@ func (n *Node) SetIndexMapLValue(b bool) {
|
||||||
|
|
||||||
func (n *Node) TChanDir() types.ChanDir {
|
func (n *Node) TChanDir() types.ChanDir {
|
||||||
if n.Op != OTCHAN {
|
if n.Op != OTCHAN {
|
||||||
Fatalf("unexpected op: %v", n.Op)
|
base.Fatalf("unexpected op: %v", n.Op)
|
||||||
}
|
}
|
||||||
return types.ChanDir(n.aux)
|
return types.ChanDir(n.aux)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) SetTChanDir(dir types.ChanDir) {
|
func (n *Node) SetTChanDir(dir types.ChanDir) {
|
||||||
if n.Op != OTCHAN {
|
if n.Op != OTCHAN {
|
||||||
Fatalf("unexpected op: %v", n.Op)
|
base.Fatalf("unexpected op: %v", n.Op)
|
||||||
}
|
}
|
||||||
n.aux = uint8(dir)
|
n.aux = uint8(dir)
|
||||||
}
|
}
|
||||||
|
|
@ -236,7 +237,7 @@ func (n *Node) SetEmbedded(b bool) { n.flags.set(nodeEmbedded, b) }
|
||||||
// inserted before dereferencing. See state.exprPtr.
|
// inserted before dereferencing. See state.exprPtr.
|
||||||
func (n *Node) MarkNonNil() {
|
func (n *Node) MarkNonNil() {
|
||||||
if !n.Type.IsPtr() && !n.Type.IsUnsafePtr() {
|
if !n.Type.IsPtr() && !n.Type.IsUnsafePtr() {
|
||||||
Fatalf("MarkNonNil(%v), type %v", n, n.Type)
|
base.Fatalf("MarkNonNil(%v), type %v", n, n.Type)
|
||||||
}
|
}
|
||||||
n.flags.set(nodeNonNil, true)
|
n.flags.set(nodeNonNil, true)
|
||||||
}
|
}
|
||||||
|
|
@ -255,7 +256,7 @@ func (n *Node) SetBounded(b bool) {
|
||||||
// No length and cap checks needed
|
// No length and cap checks needed
|
||||||
// since new slice and copied over slice data have same length.
|
// since new slice and copied over slice data have same length.
|
||||||
default:
|
default:
|
||||||
Fatalf("SetBounded(%v)", n)
|
base.Fatalf("SetBounded(%v)", n)
|
||||||
}
|
}
|
||||||
n.flags.set(nodeBounded, b)
|
n.flags.set(nodeBounded, b)
|
||||||
}
|
}
|
||||||
|
|
@ -263,7 +264,7 @@ func (n *Node) SetBounded(b bool) {
|
||||||
// MarkReadonly indicates that n is an ONAME with readonly contents.
|
// MarkReadonly indicates that n is an ONAME with readonly contents.
|
||||||
func (n *Node) MarkReadonly() {
|
func (n *Node) MarkReadonly() {
|
||||||
if n.Op != ONAME {
|
if n.Op != ONAME {
|
||||||
Fatalf("Node.MarkReadonly %v", n.Op)
|
base.Fatalf("Node.MarkReadonly %v", n.Op)
|
||||||
}
|
}
|
||||||
n.Name.SetReadonly(true)
|
n.Name.SetReadonly(true)
|
||||||
// Mark the linksym as readonly immediately
|
// Mark the linksym as readonly immediately
|
||||||
|
|
@ -284,9 +285,9 @@ func (n *Node) Val() constant.Value {
|
||||||
// which must not have been used with SetOpt.
|
// which must not have been used with SetOpt.
|
||||||
func (n *Node) SetVal(v constant.Value) {
|
func (n *Node) SetVal(v constant.Value) {
|
||||||
if n.HasOpt() {
|
if n.HasOpt() {
|
||||||
Flag.LowerH = 1
|
base.Flag.LowerH = 1
|
||||||
Dump("have Opt", n)
|
Dump("have Opt", n)
|
||||||
Fatalf("have Opt")
|
base.Fatalf("have Opt")
|
||||||
}
|
}
|
||||||
if n.Op == OLITERAL {
|
if n.Op == OLITERAL {
|
||||||
assertRepresents(n.Type, v)
|
assertRepresents(n.Type, v)
|
||||||
|
|
@ -314,9 +315,9 @@ func (n *Node) SetOpt(x interface{}) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if n.HasVal() {
|
if n.HasVal() {
|
||||||
Flag.LowerH = 1
|
base.Flag.LowerH = 1
|
||||||
Dump("have Val", n)
|
Dump("have Val", n)
|
||||||
Fatalf("have Val")
|
base.Fatalf("have Val")
|
||||||
}
|
}
|
||||||
n.SetHasOpt(true)
|
n.SetHasOpt(true)
|
||||||
n.E = x
|
n.E = x
|
||||||
|
|
@ -367,7 +368,7 @@ func (n *Node) pkgFuncName() string {
|
||||||
}
|
}
|
||||||
pkg := s.Pkg
|
pkg := s.Pkg
|
||||||
|
|
||||||
p := Ctxt.Pkgpath
|
p := base.Ctxt.Pkgpath
|
||||||
if pkg != nil && pkg.Path != "" {
|
if pkg != nil && pkg.Path != "" {
|
||||||
p = pkg.Path
|
p = pkg.Path
|
||||||
}
|
}
|
||||||
|
|
@ -764,8 +765,8 @@ func (f *Func) SetInstrumentBody(b bool) { f.flags.set(funcInstrumentB
|
||||||
func (f *Func) SetOpenCodedDeferDisallowed(b bool) { f.flags.set(funcOpenCodedDeferDisallowed, b) }
|
func (f *Func) SetOpenCodedDeferDisallowed(b bool) { f.flags.set(funcOpenCodedDeferDisallowed, b) }
|
||||||
|
|
||||||
func (f *Func) setWBPos(pos src.XPos) {
|
func (f *Func) setWBPos(pos src.XPos) {
|
||||||
if Debug.WB != 0 {
|
if base.Debug.WB != 0 {
|
||||||
Warnl(pos, "write barrier")
|
base.WarnfAt(pos, "write barrier")
|
||||||
}
|
}
|
||||||
if !f.WBPos.IsKnown() {
|
if !f.WBPos.IsKnown() {
|
||||||
f.WBPos = pos
|
f.WBPos = pos
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ package gc
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
tracepkg "runtime/trace"
|
tracepkg "runtime/trace"
|
||||||
|
|
||||||
|
"cmd/compile/internal/base"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
@ -18,10 +20,10 @@ func init() {
|
||||||
func traceHandlerGo17(traceprofile string) {
|
func traceHandlerGo17(traceprofile string) {
|
||||||
f, err := os.Create(traceprofile)
|
f, err := os.Create(traceprofile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatalf("%v", err)
|
base.Fatalf("%v", err)
|
||||||
}
|
}
|
||||||
if err := tracepkg.Start(f); err != nil {
|
if err := tracepkg.Start(f); err != nil {
|
||||||
Fatalf("%v", err)
|
base.Fatalf("%v", err)
|
||||||
}
|
}
|
||||||
atExit(tracepkg.Stop)
|
base.AtExit(tracepkg.Stop)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -7,6 +7,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/src"
|
"cmd/internal/src"
|
||||||
)
|
)
|
||||||
|
|
@ -98,7 +99,7 @@ func lexinit() {
|
||||||
for _, s := range &basicTypes {
|
for _, s := range &basicTypes {
|
||||||
etype := s.etype
|
etype := s.etype
|
||||||
if int(etype) >= len(types.Types) {
|
if int(etype) >= len(types.Types) {
|
||||||
Fatalf("lexinit: %s bad etype", s.name)
|
base.Fatalf("lexinit: %s bad etype", s.name)
|
||||||
}
|
}
|
||||||
s2 := builtinpkg.Lookup(s.name)
|
s2 := builtinpkg.Lookup(s.name)
|
||||||
t := types.Types[etype]
|
t := types.Types[etype]
|
||||||
|
|
@ -169,7 +170,7 @@ func lexinit() {
|
||||||
|
|
||||||
func typeinit() {
|
func typeinit() {
|
||||||
if Widthptr == 0 {
|
if Widthptr == 0 {
|
||||||
Fatalf("typeinit before betypeinit")
|
base.Fatalf("typeinit before betypeinit")
|
||||||
}
|
}
|
||||||
|
|
||||||
for et := types.EType(0); et < NTYPE; et++ {
|
for et := types.EType(0); et < NTYPE; et++ {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
|
import "cmd/compile/internal/base"
|
||||||
|
|
||||||
// evalunsafe evaluates a package unsafe operation and returns the result.
|
// evalunsafe evaluates a package unsafe operation and returns the result.
|
||||||
func evalunsafe(n *Node) int64 {
|
func evalunsafe(n *Node) int64 {
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
|
|
@ -23,7 +25,7 @@ func evalunsafe(n *Node) int64 {
|
||||||
case OOFFSETOF:
|
case OOFFSETOF:
|
||||||
// must be a selector.
|
// must be a selector.
|
||||||
if n.Left.Op != OXDOT {
|
if n.Left.Op != OXDOT {
|
||||||
yyerror("invalid expression %v", n)
|
base.Errorf("invalid expression %v", n)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -41,10 +43,10 @@ func evalunsafe(n *Node) int64 {
|
||||||
case ODOT, ODOTPTR:
|
case ODOT, ODOTPTR:
|
||||||
break
|
break
|
||||||
case OCALLPART:
|
case OCALLPART:
|
||||||
yyerror("invalid expression %v: argument is a method value", n)
|
base.Errorf("invalid expression %v: argument is a method value", n)
|
||||||
return 0
|
return 0
|
||||||
default:
|
default:
|
||||||
yyerror("invalid expression %v", n)
|
base.Errorf("invalid expression %v", n)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,7 +59,7 @@ func evalunsafe(n *Node) int64 {
|
||||||
// but accessing f must not otherwise involve
|
// but accessing f must not otherwise involve
|
||||||
// indirection via embedded pointer types.
|
// indirection via embedded pointer types.
|
||||||
if r.Left != sbase {
|
if r.Left != sbase {
|
||||||
yyerror("invalid expression %v: selector implies indirection of embedded %v", n, r.Left)
|
base.Errorf("invalid expression %v: selector implies indirection of embedded %v", n, r.Left)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
fallthrough
|
fallthrough
|
||||||
|
|
@ -65,12 +67,12 @@ func evalunsafe(n *Node) int64 {
|
||||||
v += r.Xoffset
|
v += r.Xoffset
|
||||||
default:
|
default:
|
||||||
Dump("unsafenmagic", n.Left)
|
Dump("unsafenmagic", n.Left)
|
||||||
Fatalf("impossible %#v node after dot insertion", r.Op)
|
base.Fatalf("impossible %#v node after dot insertion", r.Op)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
Fatalf("unexpected op %v", n.Op)
|
base.Fatalf("unexpected op %v", n.Op)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,27 +8,14 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"runtime/pprof"
|
"runtime/pprof"
|
||||||
|
|
||||||
|
"cmd/compile/internal/base"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Line returns n's position as a string. If n has been inlined,
|
// Line returns n's position as a string. If n has been inlined,
|
||||||
// it uses the outermost position where n has been inlined.
|
// it uses the outermost position where n has been inlined.
|
||||||
func (n *Node) Line() string {
|
func (n *Node) Line() string {
|
||||||
return linestr(n.Pos)
|
return base.FmtPos(n.Pos)
|
||||||
}
|
|
||||||
|
|
||||||
var atExitFuncs []func()
|
|
||||||
|
|
||||||
func atExit(f func()) {
|
|
||||||
atExitFuncs = append(atExitFuncs, f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Exit(code int) {
|
|
||||||
for i := len(atExitFuncs) - 1; i >= 0; i-- {
|
|
||||||
f := atExitFuncs[i]
|
|
||||||
atExitFuncs = atExitFuncs[:i]
|
|
||||||
f()
|
|
||||||
}
|
|
||||||
os.Exit(code)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -37,25 +24,25 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func startProfile() {
|
func startProfile() {
|
||||||
if Flag.CPUProfile != "" {
|
if base.Flag.CPUProfile != "" {
|
||||||
f, err := os.Create(Flag.CPUProfile)
|
f, err := os.Create(base.Flag.CPUProfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatalf("%v", err)
|
base.Fatalf("%v", err)
|
||||||
}
|
}
|
||||||
if err := pprof.StartCPUProfile(f); err != nil {
|
if err := pprof.StartCPUProfile(f); err != nil {
|
||||||
Fatalf("%v", err)
|
base.Fatalf("%v", err)
|
||||||
}
|
}
|
||||||
atExit(pprof.StopCPUProfile)
|
base.AtExit(pprof.StopCPUProfile)
|
||||||
}
|
}
|
||||||
if Flag.MemProfile != "" {
|
if base.Flag.MemProfile != "" {
|
||||||
if memprofilerate != 0 {
|
if memprofilerate != 0 {
|
||||||
runtime.MemProfileRate = int(memprofilerate)
|
runtime.MemProfileRate = int(memprofilerate)
|
||||||
}
|
}
|
||||||
f, err := os.Create(Flag.MemProfile)
|
f, err := os.Create(base.Flag.MemProfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatalf("%v", err)
|
base.Fatalf("%v", err)
|
||||||
}
|
}
|
||||||
atExit(func() {
|
base.AtExit(func() {
|
||||||
// Profile all outstanding allocations.
|
// Profile all outstanding allocations.
|
||||||
runtime.GC()
|
runtime.GC()
|
||||||
// compilebench parses the memory profile to extract memstats,
|
// compilebench parses the memory profile to extract memstats,
|
||||||
|
|
@ -63,36 +50,36 @@ func startProfile() {
|
||||||
// See golang.org/issue/18641 and runtime/pprof/pprof.go:writeHeap.
|
// See golang.org/issue/18641 and runtime/pprof/pprof.go:writeHeap.
|
||||||
const writeLegacyFormat = 1
|
const writeLegacyFormat = 1
|
||||||
if err := pprof.Lookup("heap").WriteTo(f, writeLegacyFormat); err != nil {
|
if err := pprof.Lookup("heap").WriteTo(f, writeLegacyFormat); err != nil {
|
||||||
Fatalf("%v", err)
|
base.Fatalf("%v", err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// Not doing memory profiling; disable it entirely.
|
// Not doing memory profiling; disable it entirely.
|
||||||
runtime.MemProfileRate = 0
|
runtime.MemProfileRate = 0
|
||||||
}
|
}
|
||||||
if Flag.BlockProfile != "" {
|
if base.Flag.BlockProfile != "" {
|
||||||
f, err := os.Create(Flag.BlockProfile)
|
f, err := os.Create(base.Flag.BlockProfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatalf("%v", err)
|
base.Fatalf("%v", err)
|
||||||
}
|
}
|
||||||
runtime.SetBlockProfileRate(1)
|
runtime.SetBlockProfileRate(1)
|
||||||
atExit(func() {
|
base.AtExit(func() {
|
||||||
pprof.Lookup("block").WriteTo(f, 0)
|
pprof.Lookup("block").WriteTo(f, 0)
|
||||||
f.Close()
|
f.Close()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if Flag.MutexProfile != "" {
|
if base.Flag.MutexProfile != "" {
|
||||||
f, err := os.Create(Flag.MutexProfile)
|
f, err := os.Create(base.Flag.MutexProfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatalf("%v", err)
|
base.Fatalf("%v", err)
|
||||||
}
|
}
|
||||||
startMutexProfiling()
|
startMutexProfiling()
|
||||||
atExit(func() {
|
base.AtExit(func() {
|
||||||
pprof.Lookup("mutex").WriteTo(f, 0)
|
pprof.Lookup("mutex").WriteTo(f, 0)
|
||||||
f.Close()
|
f.Close()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if Flag.TraceProfile != "" && traceHandler != nil {
|
if base.Flag.TraceProfile != "" && traceHandler != nil {
|
||||||
traceHandler(Flag.TraceProfile)
|
traceHandler(base.Flag.TraceProfile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
|
|
@ -22,14 +23,14 @@ const zeroValSize = 1024 // must match value of runtime/map.go:maxZero
|
||||||
|
|
||||||
func walk(fn *Node) {
|
func walk(fn *Node) {
|
||||||
Curfn = fn
|
Curfn = fn
|
||||||
errorsBefore := Errors()
|
errorsBefore := base.Errors()
|
||||||
|
|
||||||
if Flag.W != 0 {
|
if base.Flag.W != 0 {
|
||||||
s := fmt.Sprintf("\nbefore walk %v", Curfn.Func.Nname.Sym)
|
s := fmt.Sprintf("\nbefore walk %v", Curfn.Func.Nname.Sym)
|
||||||
dumplist(s, Curfn.Nbody)
|
dumplist(s, Curfn.Nbody)
|
||||||
}
|
}
|
||||||
|
|
||||||
lno := lineno
|
lno := base.Pos
|
||||||
|
|
||||||
// Final typecheck for any unused variables.
|
// Final typecheck for any unused variables.
|
||||||
for i, ln := range fn.Func.Dcl {
|
for i, ln := range fn.Func.Dcl {
|
||||||
|
|
@ -54,26 +55,26 @@ func walk(fn *Node) {
|
||||||
if defn.Left.Name.Used() {
|
if defn.Left.Name.Used() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
yyerrorl(defn.Left.Pos, "%v declared but not used", ln.Sym)
|
base.ErrorfAt(defn.Left.Pos, "%v declared but not used", ln.Sym)
|
||||||
defn.Left.Name.SetUsed(true) // suppress repeats
|
defn.Left.Name.SetUsed(true) // suppress repeats
|
||||||
} else {
|
} else {
|
||||||
yyerrorl(ln.Pos, "%v declared but not used", ln.Sym)
|
base.ErrorfAt(ln.Pos, "%v declared but not used", ln.Sym)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lineno = lno
|
base.Pos = lno
|
||||||
if Errors() > errorsBefore {
|
if base.Errors() > errorsBefore {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
walkstmtlist(Curfn.Nbody.Slice())
|
walkstmtlist(Curfn.Nbody.Slice())
|
||||||
if Flag.W != 0 {
|
if base.Flag.W != 0 {
|
||||||
s := fmt.Sprintf("after walk %v", Curfn.Func.Nname.Sym)
|
s := fmt.Sprintf("after walk %v", Curfn.Func.Nname.Sym)
|
||||||
dumplist(s, Curfn.Nbody)
|
dumplist(s, Curfn.Nbody)
|
||||||
}
|
}
|
||||||
|
|
||||||
zeroResults()
|
zeroResults()
|
||||||
heapmoves()
|
heapmoves()
|
||||||
if Flag.W != 0 && Curfn.Func.Enter.Len() > 0 {
|
if base.Flag.W != 0 && Curfn.Func.Enter.Len() > 0 {
|
||||||
s := fmt.Sprintf("enter %v", Curfn.Func.Nname.Sym)
|
s := fmt.Sprintf("enter %v", Curfn.Func.Nname.Sym)
|
||||||
dumplist(s, Curfn.Func.Enter)
|
dumplist(s, Curfn.Func.Enter)
|
||||||
}
|
}
|
||||||
|
|
@ -116,9 +117,9 @@ func walkstmt(n *Node) *Node {
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
default:
|
default:
|
||||||
if n.Op == ONAME {
|
if n.Op == ONAME {
|
||||||
yyerror("%v is not a top level statement", n.Sym)
|
base.Errorf("%v is not a top level statement", n.Sym)
|
||||||
} else {
|
} else {
|
||||||
yyerror("%v is not a top level statement", n.Op)
|
base.Errorf("%v is not a top level statement", n.Op)
|
||||||
}
|
}
|
||||||
Dump("nottop", n)
|
Dump("nottop", n)
|
||||||
|
|
||||||
|
|
@ -144,7 +145,7 @@ func walkstmt(n *Node) *Node {
|
||||||
ORECOVER,
|
ORECOVER,
|
||||||
OGETG:
|
OGETG:
|
||||||
if n.Typecheck() == 0 {
|
if n.Typecheck() == 0 {
|
||||||
Fatalf("missing typecheck: %+v", n)
|
base.Fatalf("missing typecheck: %+v", n)
|
||||||
}
|
}
|
||||||
wascopy := n.Op == OCOPY
|
wascopy := n.Op == OCOPY
|
||||||
init := n.Ninit
|
init := n.Ninit
|
||||||
|
|
@ -159,7 +160,7 @@ func walkstmt(n *Node) *Node {
|
||||||
// the value received.
|
// the value received.
|
||||||
case ORECV:
|
case ORECV:
|
||||||
if n.Typecheck() == 0 {
|
if n.Typecheck() == 0 {
|
||||||
Fatalf("missing typecheck: %+v", n)
|
base.Fatalf("missing typecheck: %+v", n)
|
||||||
}
|
}
|
||||||
init := n.Ninit
|
init := n.Ninit
|
||||||
n.Ninit.Set(nil)
|
n.Ninit.Set(nil)
|
||||||
|
|
@ -186,8 +187,8 @@ func walkstmt(n *Node) *Node {
|
||||||
case ODCL:
|
case ODCL:
|
||||||
v := n.Left
|
v := n.Left
|
||||||
if v.Class() == PAUTOHEAP {
|
if v.Class() == PAUTOHEAP {
|
||||||
if Flag.CompilingRuntime {
|
if base.Flag.CompilingRuntime {
|
||||||
yyerror("%v escapes to heap, not allowed in runtime", v)
|
base.Errorf("%v escapes to heap, not allowed in runtime", v)
|
||||||
}
|
}
|
||||||
if prealloc[v] == nil {
|
if prealloc[v] == nil {
|
||||||
prealloc[v] = callnew(v.Type)
|
prealloc[v] = callnew(v.Type)
|
||||||
|
|
@ -202,7 +203,7 @@ func walkstmt(n *Node) *Node {
|
||||||
walkstmtlist(n.List.Slice())
|
walkstmtlist(n.List.Slice())
|
||||||
|
|
||||||
case OCASE:
|
case OCASE:
|
||||||
yyerror("case statement out of place")
|
base.Errorf("case statement out of place")
|
||||||
|
|
||||||
case ODEFER:
|
case ODEFER:
|
||||||
Curfn.Func.SetHasDefer(true)
|
Curfn.Func.SetHasDefer(true)
|
||||||
|
|
@ -291,7 +292,7 @@ func walkstmt(n *Node) *Node {
|
||||||
if got, want := n.List.Len(), len(rl); got != want {
|
if got, want := n.List.Len(), len(rl); got != want {
|
||||||
// order should have rewritten multi-value function calls
|
// order should have rewritten multi-value function calls
|
||||||
// with explicit OAS2FUNC nodes.
|
// with explicit OAS2FUNC nodes.
|
||||||
Fatalf("expected %v return arguments, have %v", want, got)
|
base.Fatalf("expected %v return arguments, have %v", want, got)
|
||||||
}
|
}
|
||||||
|
|
||||||
// move function calls out, to make reorder3's job easier.
|
// move function calls out, to make reorder3's job easier.
|
||||||
|
|
@ -334,7 +335,7 @@ func walkstmt(n *Node) *Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Op == ONAME {
|
if n.Op == ONAME {
|
||||||
Fatalf("walkstmt ended up with name: %+v", n)
|
base.Fatalf("walkstmt ended up with name: %+v", n)
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
@ -405,7 +406,7 @@ func convFuncName(from, to *types.Type) (fnname string, needsaddr bool) {
|
||||||
return "convT2I", true
|
return "convT2I", true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Fatalf("unknown conv func %c2%c", from.Tie(), to.Tie())
|
base.Fatalf("unknown conv func %c2%c", from.Tie(), to.Tie())
|
||||||
panic("unreachable")
|
panic("unreachable")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -429,7 +430,7 @@ func walkexpr(n *Node, init *Nodes) *Node {
|
||||||
// not okay to use n->ninit when walking n,
|
// not okay to use n->ninit when walking n,
|
||||||
// because we might replace n with some other node
|
// because we might replace n with some other node
|
||||||
// and would lose the init list.
|
// and would lose the init list.
|
||||||
Fatalf("walkexpr init == &n->ninit")
|
base.Fatalf("walkexpr init == &n->ninit")
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Ninit.Len() != 0 {
|
if n.Ninit.Len() != 0 {
|
||||||
|
|
@ -439,16 +440,16 @@ func walkexpr(n *Node, init *Nodes) *Node {
|
||||||
|
|
||||||
lno := setlineno(n)
|
lno := setlineno(n)
|
||||||
|
|
||||||
if Flag.LowerW > 1 {
|
if base.Flag.LowerW > 1 {
|
||||||
Dump("before walk expr", n)
|
Dump("before walk expr", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Typecheck() != 1 {
|
if n.Typecheck() != 1 {
|
||||||
Fatalf("missed typecheck: %+v", n)
|
base.Fatalf("missed typecheck: %+v", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Type.IsUntyped() {
|
if n.Type.IsUntyped() {
|
||||||
Fatalf("expression has untyped type: %+v", n)
|
base.Fatalf("expression has untyped type: %+v", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Op == ONAME && n.Class() == PAUTOHEAP {
|
if n.Op == ONAME && n.Class() == PAUTOHEAP {
|
||||||
|
|
@ -463,7 +464,7 @@ opswitch:
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
default:
|
default:
|
||||||
Dump("walk", n)
|
Dump("walk", n)
|
||||||
Fatalf("walkexpr: switch 1 unknown op %+S", n)
|
base.Fatalf("walkexpr: switch 1 unknown op %+S", n)
|
||||||
|
|
||||||
case ONONAME, OEMPTY, OGETG, ONEWOBJ, OMETHEXPR:
|
case ONONAME, OEMPTY, OGETG, ONEWOBJ, OMETHEXPR:
|
||||||
|
|
||||||
|
|
@ -587,7 +588,7 @@ opswitch:
|
||||||
// the mapassign call.
|
// the mapassign call.
|
||||||
mapAppend := n.Left.Op == OINDEXMAP && n.Right.Op == OAPPEND
|
mapAppend := n.Left.Op == OINDEXMAP && n.Right.Op == OAPPEND
|
||||||
if mapAppend && !samesafeexpr(n.Left, n.Right.List.First()) {
|
if mapAppend && !samesafeexpr(n.Left, n.Right.List.First()) {
|
||||||
Fatalf("not same expressions: %v != %v", n.Left, n.Right.List.First())
|
base.Fatalf("not same expressions: %v != %v", n.Left, n.Right.List.First())
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Left = walkexpr(n.Left, init)
|
n.Left = walkexpr(n.Left, init)
|
||||||
|
|
@ -638,7 +639,7 @@ opswitch:
|
||||||
// x = append(...)
|
// x = append(...)
|
||||||
r := n.Right
|
r := n.Right
|
||||||
if r.Type.Elem().NotInHeap() {
|
if r.Type.Elem().NotInHeap() {
|
||||||
yyerror("%v can't be allocated in Go; it is incomplete (or unallocatable)", r.Type.Elem())
|
base.Errorf("%v can't be allocated in Go; it is incomplete (or unallocatable)", r.Type.Elem())
|
||||||
}
|
}
|
||||||
switch {
|
switch {
|
||||||
case isAppendOfMake(r):
|
case isAppendOfMake(r):
|
||||||
|
|
@ -1046,25 +1047,25 @@ opswitch:
|
||||||
}
|
}
|
||||||
if t.IsArray() {
|
if t.IsArray() {
|
||||||
n.SetBounded(bounded(r, t.NumElem()))
|
n.SetBounded(bounded(r, t.NumElem()))
|
||||||
if Flag.LowerM != 0 && n.Bounded() && !Isconst(n.Right, constant.Int) {
|
if base.Flag.LowerM != 0 && n.Bounded() && !Isconst(n.Right, constant.Int) {
|
||||||
Warn("index bounds check elided")
|
base.Warn("index bounds check elided")
|
||||||
}
|
}
|
||||||
if smallintconst(n.Right) && !n.Bounded() {
|
if smallintconst(n.Right) && !n.Bounded() {
|
||||||
yyerror("index out of bounds")
|
base.Errorf("index out of bounds")
|
||||||
}
|
}
|
||||||
} else if Isconst(n.Left, constant.String) {
|
} else if Isconst(n.Left, constant.String) {
|
||||||
n.SetBounded(bounded(r, int64(len(n.Left.StringVal()))))
|
n.SetBounded(bounded(r, int64(len(n.Left.StringVal()))))
|
||||||
if Flag.LowerM != 0 && n.Bounded() && !Isconst(n.Right, constant.Int) {
|
if base.Flag.LowerM != 0 && n.Bounded() && !Isconst(n.Right, constant.Int) {
|
||||||
Warn("index bounds check elided")
|
base.Warn("index bounds check elided")
|
||||||
}
|
}
|
||||||
if smallintconst(n.Right) && !n.Bounded() {
|
if smallintconst(n.Right) && !n.Bounded() {
|
||||||
yyerror("index out of bounds")
|
base.Errorf("index out of bounds")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if Isconst(n.Right, constant.Int) {
|
if Isconst(n.Right, constant.Int) {
|
||||||
if v := n.Right.Val(); constant.Sign(v) < 0 || doesoverflow(v, types.Types[TINT]) {
|
if v := n.Right.Val(); constant.Sign(v) < 0 || doesoverflow(v, types.Types[TINT]) {
|
||||||
yyerror("index out of bounds")
|
base.Errorf("index out of bounds")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1107,7 +1108,7 @@ opswitch:
|
||||||
n.SetTypecheck(1)
|
n.SetTypecheck(1)
|
||||||
|
|
||||||
case ORECV:
|
case ORECV:
|
||||||
Fatalf("walkexpr ORECV") // should see inside OAS only
|
base.Fatalf("walkexpr ORECV") // should see inside OAS only
|
||||||
|
|
||||||
case OSLICEHEADER:
|
case OSLICEHEADER:
|
||||||
n.Left = walkexpr(n.Left, init)
|
n.Left = walkexpr(n.Left, init)
|
||||||
|
|
@ -1149,11 +1150,11 @@ opswitch:
|
||||||
|
|
||||||
case ONEW:
|
case ONEW:
|
||||||
if n.Type.Elem().NotInHeap() {
|
if n.Type.Elem().NotInHeap() {
|
||||||
yyerror("%v can't be allocated in Go; it is incomplete (or unallocatable)", n.Type.Elem())
|
base.Errorf("%v can't be allocated in Go; it is incomplete (or unallocatable)", n.Type.Elem())
|
||||||
}
|
}
|
||||||
if n.Esc == EscNone {
|
if n.Esc == EscNone {
|
||||||
if n.Type.Elem().Width >= maxImplicitStackVarSize {
|
if n.Type.Elem().Width >= maxImplicitStackVarSize {
|
||||||
Fatalf("large ONEW with EscNone: %v", n)
|
base.Fatalf("large ONEW with EscNone: %v", n)
|
||||||
}
|
}
|
||||||
r := temp(n.Type.Elem())
|
r := temp(n.Type.Elem())
|
||||||
r = nod(OAS, r, nil) // zero temp
|
r = nod(OAS, r, nil) // zero temp
|
||||||
|
|
@ -1171,10 +1172,10 @@ opswitch:
|
||||||
|
|
||||||
case OAPPEND:
|
case OAPPEND:
|
||||||
// order should make sure we only see OAS(node, OAPPEND), which we handle above.
|
// order should make sure we only see OAS(node, OAPPEND), which we handle above.
|
||||||
Fatalf("append outside assignment")
|
base.Fatalf("append outside assignment")
|
||||||
|
|
||||||
case OCOPY:
|
case OCOPY:
|
||||||
n = copyany(n, init, instrumenting && !Flag.CompilingRuntime)
|
n = copyany(n, init, instrumenting && !base.Flag.CompilingRuntime)
|
||||||
|
|
||||||
// cannot use chanfn - closechan takes any, not chan any
|
// cannot use chanfn - closechan takes any, not chan any
|
||||||
case OCLOSE:
|
case OCLOSE:
|
||||||
|
|
@ -1320,17 +1321,17 @@ opswitch:
|
||||||
}
|
}
|
||||||
t := n.Type
|
t := n.Type
|
||||||
if t.Elem().NotInHeap() {
|
if t.Elem().NotInHeap() {
|
||||||
yyerror("%v can't be allocated in Go; it is incomplete (or unallocatable)", t.Elem())
|
base.Errorf("%v can't be allocated in Go; it is incomplete (or unallocatable)", t.Elem())
|
||||||
}
|
}
|
||||||
if n.Esc == EscNone {
|
if n.Esc == EscNone {
|
||||||
if why := heapAllocReason(n); why != "" {
|
if why := heapAllocReason(n); why != "" {
|
||||||
Fatalf("%v has EscNone, but %v", n, why)
|
base.Fatalf("%v has EscNone, but %v", n, why)
|
||||||
}
|
}
|
||||||
// var arr [r]T
|
// var arr [r]T
|
||||||
// n = arr[:l]
|
// n = arr[:l]
|
||||||
i := indexconst(r)
|
i := indexconst(r)
|
||||||
if i < 0 {
|
if i < 0 {
|
||||||
Fatalf("walkexpr: invalid index %v", r)
|
base.Fatalf("walkexpr: invalid index %v", r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// cap is constrained to [0,2^31) or [0,2^63) depending on whether
|
// cap is constrained to [0,2^31) or [0,2^63) depending on whether
|
||||||
|
|
@ -1392,12 +1393,12 @@ opswitch:
|
||||||
|
|
||||||
case OMAKESLICECOPY:
|
case OMAKESLICECOPY:
|
||||||
if n.Esc == EscNone {
|
if n.Esc == EscNone {
|
||||||
Fatalf("OMAKESLICECOPY with EscNone: %v", n)
|
base.Fatalf("OMAKESLICECOPY with EscNone: %v", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
t := n.Type
|
t := n.Type
|
||||||
if t.Elem().NotInHeap() {
|
if t.Elem().NotInHeap() {
|
||||||
yyerror("%v can't be allocated in Go; it is incomplete (or unallocatable)", t.Elem())
|
base.Errorf("%v can't be allocated in Go; it is incomplete (or unallocatable)", t.Elem())
|
||||||
}
|
}
|
||||||
|
|
||||||
length := conv(n.Left, types.Types[TINT])
|
length := conv(n.Left, types.Types[TINT])
|
||||||
|
|
@ -1583,7 +1584,7 @@ opswitch:
|
||||||
t := n.Type
|
t := n.Type
|
||||||
n = evalConst(n)
|
n = evalConst(n)
|
||||||
if n.Type != t {
|
if n.Type != t {
|
||||||
Fatalf("evconst changed Type: %v had type %v, now %v", n, t, n.Type)
|
base.Fatalf("evconst changed Type: %v had type %v, now %v", n, t, n.Type)
|
||||||
}
|
}
|
||||||
if n.Op == OLITERAL {
|
if n.Op == OLITERAL {
|
||||||
n = typecheck(n, ctxExpr)
|
n = typecheck(n, ctxExpr)
|
||||||
|
|
@ -1596,11 +1597,11 @@ opswitch:
|
||||||
|
|
||||||
updateHasCall(n)
|
updateHasCall(n)
|
||||||
|
|
||||||
if Flag.LowerW != 0 && n != nil {
|
if base.Flag.LowerW != 0 && n != nil {
|
||||||
Dump("after walk expr", n)
|
Dump("after walk expr", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
lineno = lno
|
base.Pos = lno
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1685,8 +1686,8 @@ func reduceSlice(n *Node) *Node {
|
||||||
n.SetSliceBounds(low, high, max)
|
n.SetSliceBounds(low, high, max)
|
||||||
if (n.Op == OSLICE || n.Op == OSLICESTR) && low == nil && high == nil {
|
if (n.Op == OSLICE || n.Op == OSLICESTR) && low == nil && high == nil {
|
||||||
// Reduce x[:] to x.
|
// Reduce x[:] to x.
|
||||||
if Debug.Slice > 0 {
|
if base.Debug.Slice > 0 {
|
||||||
Warn("slice: omit slice operation")
|
base.Warn("slice: omit slice operation")
|
||||||
}
|
}
|
||||||
return n.Left
|
return n.Left
|
||||||
}
|
}
|
||||||
|
|
@ -1736,7 +1737,7 @@ func ascompatee(op Op, nl, nr []*Node, init *Nodes) []*Node {
|
||||||
var nln, nrn Nodes
|
var nln, nrn Nodes
|
||||||
nln.Set(nl)
|
nln.Set(nl)
|
||||||
nrn.Set(nr)
|
nrn.Set(nr)
|
||||||
Fatalf("error in shape across %+v %v %+v / %d %d [%s]", nln, op, nrn, len(nl), len(nr), Curfn.funcname())
|
base.Fatalf("error in shape across %+v %v %+v / %d %d [%s]", nln, op, nrn, len(nl), len(nr), Curfn.funcname())
|
||||||
}
|
}
|
||||||
return nn
|
return nn
|
||||||
}
|
}
|
||||||
|
|
@ -1758,7 +1759,7 @@ func fncall(l *Node, rt *types.Type) bool {
|
||||||
// expr-list = func()
|
// expr-list = func()
|
||||||
func ascompatet(nl Nodes, nr *types.Type) []*Node {
|
func ascompatet(nl Nodes, nr *types.Type) []*Node {
|
||||||
if nl.Len() != nr.NumFields() {
|
if nl.Len() != nr.NumFields() {
|
||||||
Fatalf("ascompatet: assignment count mismatch: %d = %d", nl.Len(), nr.NumFields())
|
base.Fatalf("ascompatet: assignment count mismatch: %d = %d", nl.Len(), nr.NumFields())
|
||||||
}
|
}
|
||||||
|
|
||||||
var nn, mm Nodes
|
var nn, mm Nodes
|
||||||
|
|
@ -1780,7 +1781,7 @@ func ascompatet(nl Nodes, nr *types.Type) []*Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
res := nod(ORESULT, nil, nil)
|
res := nod(ORESULT, nil, nil)
|
||||||
res.Xoffset = Ctxt.FixedFrameSize() + r.Offset
|
res.Xoffset = base.Ctxt.FixedFrameSize() + r.Offset
|
||||||
res.Type = r.Type
|
res.Type = r.Type
|
||||||
res.SetTypecheck(1)
|
res.SetTypecheck(1)
|
||||||
|
|
||||||
|
|
@ -1789,7 +1790,7 @@ func ascompatet(nl Nodes, nr *types.Type) []*Node {
|
||||||
updateHasCall(a)
|
updateHasCall(a)
|
||||||
if a.HasCall() {
|
if a.HasCall() {
|
||||||
Dump("ascompatet ucount", a)
|
Dump("ascompatet ucount", a)
|
||||||
Fatalf("ascompatet: too many function calls evaluating parameters")
|
base.Fatalf("ascompatet: too many function calls evaluating parameters")
|
||||||
}
|
}
|
||||||
|
|
||||||
nn.Append(a)
|
nn.Append(a)
|
||||||
|
|
@ -1811,7 +1812,7 @@ func mkdotargslice(typ *types.Type, args []*Node) *Node {
|
||||||
|
|
||||||
n = typecheck(n, ctxExpr)
|
n = typecheck(n, ctxExpr)
|
||||||
if n.Type == nil {
|
if n.Type == nil {
|
||||||
Fatalf("mkdotargslice: typecheck failed")
|
base.Fatalf("mkdotargslice: typecheck failed")
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
@ -2069,7 +2070,7 @@ func isReflectHeaderDataField(l *Node) bool {
|
||||||
|
|
||||||
func convas(n *Node, init *Nodes) *Node {
|
func convas(n *Node, init *Nodes) *Node {
|
||||||
if n.Op != OAS {
|
if n.Op != OAS {
|
||||||
Fatalf("convas: not OAS %v", n.Op)
|
base.Fatalf("convas: not OAS %v", n.Op)
|
||||||
}
|
}
|
||||||
defer updateHasCall(n)
|
defer updateHasCall(n)
|
||||||
|
|
||||||
|
|
@ -2134,7 +2135,7 @@ func reorder3(all []*Node) []*Node {
|
||||||
|
|
||||||
switch l.Op {
|
switch l.Op {
|
||||||
default:
|
default:
|
||||||
Fatalf("reorder3 unexpected lvalue %#v", l.Op)
|
base.Fatalf("reorder3 unexpected lvalue %#v", l.Op)
|
||||||
|
|
||||||
case ONAME:
|
case ONAME:
|
||||||
break
|
break
|
||||||
|
|
@ -2182,7 +2183,7 @@ func outervalue(n *Node) *Node {
|
||||||
for {
|
for {
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
case OXDOT:
|
case OXDOT:
|
||||||
Fatalf("OXDOT in walk")
|
base.Fatalf("OXDOT in walk")
|
||||||
case ODOT, OPAREN, OCONVNOP:
|
case ODOT, OPAREN, OCONVNOP:
|
||||||
n = n.Left
|
n = n.Left
|
||||||
continue
|
continue
|
||||||
|
|
@ -2230,7 +2231,7 @@ func aliased(r *Node, all []*Node) bool {
|
||||||
|
|
||||||
switch l.Class() {
|
switch l.Class() {
|
||||||
default:
|
default:
|
||||||
Fatalf("unexpected class: %v, %v", l, l.Class())
|
base.Fatalf("unexpected class: %v, %v", l, l.Class())
|
||||||
|
|
||||||
case PAUTOHEAP, PEXTERN:
|
case PAUTOHEAP, PEXTERN:
|
||||||
memwrite = true
|
memwrite = true
|
||||||
|
|
@ -2317,7 +2318,7 @@ func varexpr(n *Node) bool {
|
||||||
|
|
||||||
case ODOT: // but not ODOTPTR
|
case ODOT: // but not ODOTPTR
|
||||||
// Should have been handled in aliased.
|
// Should have been handled in aliased.
|
||||||
Fatalf("varexpr unexpected ODOT")
|
base.Fatalf("varexpr unexpected ODOT")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Be conservative.
|
// Be conservative.
|
||||||
|
|
@ -2468,25 +2469,25 @@ func returnsfromheap(params *types.Type) []*Node {
|
||||||
// between the stack and the heap. The generated code is added to Curfn's
|
// between the stack and the heap. The generated code is added to Curfn's
|
||||||
// Enter and Exit lists.
|
// Enter and Exit lists.
|
||||||
func heapmoves() {
|
func heapmoves() {
|
||||||
lno := lineno
|
lno := base.Pos
|
||||||
lineno = Curfn.Pos
|
base.Pos = Curfn.Pos
|
||||||
nn := paramstoheap(Curfn.Type.Recvs())
|
nn := paramstoheap(Curfn.Type.Recvs())
|
||||||
nn = append(nn, paramstoheap(Curfn.Type.Params())...)
|
nn = append(nn, paramstoheap(Curfn.Type.Params())...)
|
||||||
nn = append(nn, paramstoheap(Curfn.Type.Results())...)
|
nn = append(nn, paramstoheap(Curfn.Type.Results())...)
|
||||||
Curfn.Func.Enter.Append(nn...)
|
Curfn.Func.Enter.Append(nn...)
|
||||||
lineno = Curfn.Func.Endlineno
|
base.Pos = Curfn.Func.Endlineno
|
||||||
Curfn.Func.Exit.Append(returnsfromheap(Curfn.Type.Results())...)
|
Curfn.Func.Exit.Append(returnsfromheap(Curfn.Type.Results())...)
|
||||||
lineno = lno
|
base.Pos = lno
|
||||||
}
|
}
|
||||||
|
|
||||||
func vmkcall(fn *Node, t *types.Type, init *Nodes, va []*Node) *Node {
|
func vmkcall(fn *Node, t *types.Type, init *Nodes, va []*Node) *Node {
|
||||||
if fn.Type == nil || fn.Type.Etype != TFUNC {
|
if fn.Type == nil || fn.Type.Etype != TFUNC {
|
||||||
Fatalf("mkcall %v %v", fn, fn.Type)
|
base.Fatalf("mkcall %v %v", fn, fn.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
n := fn.Type.NumParams()
|
n := fn.Type.NumParams()
|
||||||
if n != len(va) {
|
if n != len(va) {
|
||||||
Fatalf("vmkcall %v needs %v args got %v", fn, n, len(va))
|
base.Fatalf("vmkcall %v needs %v args got %v", fn, n, len(va))
|
||||||
}
|
}
|
||||||
|
|
||||||
r := nod(OCALL, fn, nil)
|
r := nod(OCALL, fn, nil)
|
||||||
|
|
@ -2552,12 +2553,12 @@ func byteindex(n *Node) *Node {
|
||||||
|
|
||||||
func chanfn(name string, n int, t *types.Type) *Node {
|
func chanfn(name string, n int, t *types.Type) *Node {
|
||||||
if !t.IsChan() {
|
if !t.IsChan() {
|
||||||
Fatalf("chanfn %v", t)
|
base.Fatalf("chanfn %v", t)
|
||||||
}
|
}
|
||||||
fn := syslook(name)
|
fn := syslook(name)
|
||||||
switch n {
|
switch n {
|
||||||
default:
|
default:
|
||||||
Fatalf("chanfn %d", n)
|
base.Fatalf("chanfn %d", n)
|
||||||
case 1:
|
case 1:
|
||||||
fn = substArgTypes(fn, t.Elem())
|
fn = substArgTypes(fn, t.Elem())
|
||||||
case 2:
|
case 2:
|
||||||
|
|
@ -2568,7 +2569,7 @@ func chanfn(name string, n int, t *types.Type) *Node {
|
||||||
|
|
||||||
func mapfn(name string, t *types.Type) *Node {
|
func mapfn(name string, t *types.Type) *Node {
|
||||||
if !t.IsMap() {
|
if !t.IsMap() {
|
||||||
Fatalf("mapfn %v", t)
|
base.Fatalf("mapfn %v", t)
|
||||||
}
|
}
|
||||||
fn := syslook(name)
|
fn := syslook(name)
|
||||||
fn = substArgTypes(fn, t.Key(), t.Elem(), t.Key(), t.Elem())
|
fn = substArgTypes(fn, t.Key(), t.Elem(), t.Key(), t.Elem())
|
||||||
|
|
@ -2577,7 +2578,7 @@ func mapfn(name string, t *types.Type) *Node {
|
||||||
|
|
||||||
func mapfndel(name string, t *types.Type) *Node {
|
func mapfndel(name string, t *types.Type) *Node {
|
||||||
if !t.IsMap() {
|
if !t.IsMap() {
|
||||||
Fatalf("mapfn %v", t)
|
base.Fatalf("mapfn %v", t)
|
||||||
}
|
}
|
||||||
fn := syslook(name)
|
fn := syslook(name)
|
||||||
fn = substArgTypes(fn, t.Key(), t.Elem(), t.Key())
|
fn = substArgTypes(fn, t.Key(), t.Elem(), t.Key())
|
||||||
|
|
@ -2618,7 +2619,7 @@ func mapfast(t *types.Type) int {
|
||||||
if Widthptr == 4 {
|
if Widthptr == 4 {
|
||||||
return mapfast32ptr
|
return mapfast32ptr
|
||||||
}
|
}
|
||||||
Fatalf("small pointer %v", t.Key())
|
base.Fatalf("small pointer %v", t.Key())
|
||||||
case AMEM64:
|
case AMEM64:
|
||||||
if !t.Key().HasPointers() {
|
if !t.Key().HasPointers() {
|
||||||
return mapfast64
|
return mapfast64
|
||||||
|
|
@ -2645,7 +2646,7 @@ func addstr(n *Node, init *Nodes) *Node {
|
||||||
c := n.List.Len()
|
c := n.List.Len()
|
||||||
|
|
||||||
if c < 2 {
|
if c < 2 {
|
||||||
Fatalf("addstr count %d too small", c)
|
base.Fatalf("addstr count %d too small", c)
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := nodnil()
|
buf := nodnil()
|
||||||
|
|
@ -2784,7 +2785,7 @@ func appendslice(n *Node, init *Nodes) *Node {
|
||||||
ptr1, len1 := nptr1.backingArrayPtrLen()
|
ptr1, len1 := nptr1.backingArrayPtrLen()
|
||||||
ptr2, len2 := nptr2.backingArrayPtrLen()
|
ptr2, len2 := nptr2.backingArrayPtrLen()
|
||||||
ncopy = mkcall1(fn, types.Types[TINT], &nodes, typename(elemtype), ptr1, len1, ptr2, len2)
|
ncopy = mkcall1(fn, types.Types[TINT], &nodes, typename(elemtype), ptr1, len1, ptr2, len2)
|
||||||
} else if instrumenting && !Flag.CompilingRuntime {
|
} else if instrumenting && !base.Flag.CompilingRuntime {
|
||||||
// rely on runtime to instrument:
|
// rely on runtime to instrument:
|
||||||
// copy(s[len(l1):], l2)
|
// copy(s[len(l1):], l2)
|
||||||
// l2 can be a slice or string.
|
// l2 can be a slice or string.
|
||||||
|
|
@ -2827,12 +2828,12 @@ func appendslice(n *Node, init *Nodes) *Node {
|
||||||
// isAppendOfMake reports whether n is of the form append(x , make([]T, y)...).
|
// isAppendOfMake reports whether n is of the form append(x , make([]T, y)...).
|
||||||
// isAppendOfMake assumes n has already been typechecked.
|
// isAppendOfMake assumes n has already been typechecked.
|
||||||
func isAppendOfMake(n *Node) bool {
|
func isAppendOfMake(n *Node) bool {
|
||||||
if Flag.N != 0 || instrumenting {
|
if base.Flag.N != 0 || instrumenting {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Typecheck() == 0 {
|
if n.Typecheck() == 0 {
|
||||||
Fatalf("missing typecheck: %+v", n)
|
base.Fatalf("missing typecheck: %+v", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Op != OAPPEND || !n.IsDDD() || n.List.Len() != 2 {
|
if n.Op != OAPPEND || !n.IsDDD() || n.List.Len() != 2 {
|
||||||
|
|
@ -3036,7 +3037,7 @@ func walkappend(n *Node, init *Nodes, dst *Node) *Node {
|
||||||
|
|
||||||
// General case, with no function calls left as arguments.
|
// General case, with no function calls left as arguments.
|
||||||
// Leave for gen, except that instrumentation requires old form.
|
// Leave for gen, except that instrumentation requires old form.
|
||||||
if !instrumenting || Flag.CompilingRuntime {
|
if !instrumenting || base.Flag.CompilingRuntime {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3185,7 +3186,7 @@ func eqfor(t *types.Type) (n *Node, needsize bool) {
|
||||||
})
|
})
|
||||||
return n, false
|
return n, false
|
||||||
}
|
}
|
||||||
Fatalf("eqfor %v", t)
|
base.Fatalf("eqfor %v", t)
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3262,7 +3263,7 @@ func walkcompare(n *Node, init *Nodes) *Node {
|
||||||
|
|
||||||
switch t.Etype {
|
switch t.Etype {
|
||||||
default:
|
default:
|
||||||
if Debug.Libfuzzer != 0 && t.IsInteger() {
|
if base.Debug.Libfuzzer != 0 && t.IsInteger() {
|
||||||
n.Left = cheapexpr(n.Left, init)
|
n.Left = cheapexpr(n.Left, init)
|
||||||
n.Right = cheapexpr(n.Right, init)
|
n.Right = cheapexpr(n.Right, init)
|
||||||
|
|
||||||
|
|
@ -3304,7 +3305,7 @@ func walkcompare(n *Node, init *Nodes) *Node {
|
||||||
}
|
}
|
||||||
paramType = types.Types[TUINT64]
|
paramType = types.Types[TUINT64]
|
||||||
default:
|
default:
|
||||||
Fatalf("unexpected integer size %d for %v", t.Size(), t)
|
base.Fatalf("unexpected integer size %d for %v", t.Size(), t)
|
||||||
}
|
}
|
||||||
init.Append(mkcall(fn, nil, init, tracecmpArg(l, paramType, init), tracecmpArg(r, paramType, init)))
|
init.Append(mkcall(fn, nil, init, tracecmpArg(l, paramType, init), tracecmpArg(r, paramType, init)))
|
||||||
}
|
}
|
||||||
|
|
@ -3329,7 +3330,7 @@ func walkcompare(n *Node, init *Nodes) *Node {
|
||||||
if !inline {
|
if !inline {
|
||||||
// eq algs take pointers; cmpl and cmpr must be addressable
|
// eq algs take pointers; cmpl and cmpr must be addressable
|
||||||
if !islvalue(cmpl) || !islvalue(cmpr) {
|
if !islvalue(cmpl) || !islvalue(cmpr) {
|
||||||
Fatalf("arguments of comparison must be lvalues - %v %v", cmpl, cmpr)
|
base.Fatalf("arguments of comparison must be lvalues - %v %v", cmpl, cmpr)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn, needsize := eqfor(t)
|
fn, needsize := eqfor(t)
|
||||||
|
|
@ -3722,7 +3723,7 @@ func usefield(n *Node) {
|
||||||
|
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
default:
|
default:
|
||||||
Fatalf("usefield %v", n.Op)
|
base.Fatalf("usefield %v", n.Op)
|
||||||
|
|
||||||
case ODOT, ODOTPTR:
|
case ODOT, ODOTPTR:
|
||||||
break
|
break
|
||||||
|
|
@ -3739,10 +3740,10 @@ func usefield(n *Node) {
|
||||||
}
|
}
|
||||||
field := n.Opt().(*types.Field)
|
field := n.Opt().(*types.Field)
|
||||||
if field == nil {
|
if field == nil {
|
||||||
Fatalf("usefield %v %v without paramfld", n.Left.Type, n.Sym)
|
base.Fatalf("usefield %v %v without paramfld", n.Left.Type, n.Sym)
|
||||||
}
|
}
|
||||||
if field.Sym != n.Sym || field.Offset != n.Xoffset {
|
if field.Sym != n.Sym || field.Offset != n.Xoffset {
|
||||||
Fatalf("field inconsistency: %v,%v != %v,%v", field.Sym, field.Offset, n.Sym, n.Xoffset)
|
base.Fatalf("field inconsistency: %v,%v != %v,%v", field.Sym, field.Offset, n.Sym, n.Xoffset)
|
||||||
}
|
}
|
||||||
if !strings.Contains(field.Note, "go:\"track\"") {
|
if !strings.Contains(field.Note, "go:\"track\"") {
|
||||||
return
|
return
|
||||||
|
|
@ -3753,10 +3754,10 @@ func usefield(n *Node) {
|
||||||
outer = outer.Elem()
|
outer = outer.Elem()
|
||||||
}
|
}
|
||||||
if outer.Sym == nil {
|
if outer.Sym == nil {
|
||||||
yyerror("tracked field must be in named struct type")
|
base.Errorf("tracked field must be in named struct type")
|
||||||
}
|
}
|
||||||
if !types.IsExported(field.Sym.Name) {
|
if !types.IsExported(field.Sym.Name) {
|
||||||
yyerror("tracked field must be exported (upper case)")
|
base.Errorf("tracked field must be exported (upper case)")
|
||||||
}
|
}
|
||||||
|
|
||||||
sym := tracksym(outer, field)
|
sym := tracksym(outer, field)
|
||||||
|
|
@ -3968,7 +3969,7 @@ func substArgTypes(old *Node, types_ ...*types.Type) *Node {
|
||||||
}
|
}
|
||||||
n.Type = types.SubstAny(n.Type, &types_)
|
n.Type = types.SubstAny(n.Type, &types_)
|
||||||
if len(types_) > 0 {
|
if len(types_) > 0 {
|
||||||
Fatalf("substArgTypes: too many argument types")
|
base.Fatalf("substArgTypes: too many argument types")
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
@ -3991,17 +3992,17 @@ func canMergeLoads() bool {
|
||||||
// isRuneCount reports whether n is of the form len([]rune(string)).
|
// isRuneCount reports whether n is of the form len([]rune(string)).
|
||||||
// These are optimized into a call to runtime.countrunes.
|
// These are optimized into a call to runtime.countrunes.
|
||||||
func isRuneCount(n *Node) bool {
|
func isRuneCount(n *Node) bool {
|
||||||
return Flag.N == 0 && !instrumenting && n.Op == OLEN && n.Left.Op == OSTR2RUNES
|
return base.Flag.N == 0 && !instrumenting && n.Op == OLEN && n.Left.Op == OSTR2RUNES
|
||||||
}
|
}
|
||||||
|
|
||||||
func walkCheckPtrAlignment(n *Node, init *Nodes, count *Node) *Node {
|
func walkCheckPtrAlignment(n *Node, init *Nodes, count *Node) *Node {
|
||||||
if !n.Type.IsPtr() {
|
if !n.Type.IsPtr() {
|
||||||
Fatalf("expected pointer type: %v", n.Type)
|
base.Fatalf("expected pointer type: %v", n.Type)
|
||||||
}
|
}
|
||||||
elem := n.Type.Elem()
|
elem := n.Type.Elem()
|
||||||
if count != nil {
|
if count != nil {
|
||||||
if !elem.IsArray() {
|
if !elem.IsArray() {
|
||||||
Fatalf("expected array type: %v", elem)
|
base.Fatalf("expected array type: %v", elem)
|
||||||
}
|
}
|
||||||
elem = elem.Elem()
|
elem = elem.Elem()
|
||||||
}
|
}
|
||||||
|
|
@ -4031,7 +4032,7 @@ func walkCheckPtrArithmetic(n *Node, init *Nodes) *Node {
|
||||||
} else if opt != nil {
|
} else if opt != nil {
|
||||||
// We use n.Opt() here because today it's not used for OCONVNOP. If that changes,
|
// We use n.Opt() here because today it's not used for OCONVNOP. If that changes,
|
||||||
// there's no guarantee that temporarily replacing it is safe, so just hard fail here.
|
// there's no guarantee that temporarily replacing it is safe, so just hard fail here.
|
||||||
Fatalf("unexpected Opt: %v", opt)
|
base.Fatalf("unexpected Opt: %v", opt)
|
||||||
}
|
}
|
||||||
n.SetOpt(&walkCheckPtrArithmeticMarker)
|
n.SetOpt(&walkCheckPtrArithmeticMarker)
|
||||||
defer n.SetOpt(nil)
|
defer n.SetOpt(nil)
|
||||||
|
|
@ -4087,5 +4088,5 @@ func walkCheckPtrArithmetic(n *Node, init *Nodes) *Node {
|
||||||
// function fn at a given level. See debugHelpFooter for defined
|
// function fn at a given level. See debugHelpFooter for defined
|
||||||
// levels.
|
// levels.
|
||||||
func checkPtr(fn *Node, level int) bool {
|
func checkPtr(fn *Node, level int) bool {
|
||||||
return Debug.Checkptr >= level && fn.Func.Pragma&NoCheckPtr == 0
|
return base.Debug.Checkptr >= level && fn.Func.Pragma&NoCheckPtr == 0
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package mips
|
package mips
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/gc"
|
"cmd/compile/internal/gc"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
"cmd/internal/obj/mips"
|
"cmd/internal/obj/mips"
|
||||||
|
|
@ -18,7 +19,7 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
|
||||||
}
|
}
|
||||||
if cnt < int64(4*gc.Widthptr) {
|
if cnt < int64(4*gc.Widthptr) {
|
||||||
for i := int64(0); i < cnt; i += int64(gc.Widthptr) {
|
for i := int64(0); i < cnt; i += int64(gc.Widthptr) {
|
||||||
p = pp.Appendpp(p, mips.AMOVW, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGSP, gc.Ctxt.FixedFrameSize()+off+i)
|
p = pp.Appendpp(p, mips.AMOVW, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGSP, base.Ctxt.FixedFrameSize()+off+i)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//fmt.Printf("zerorange frame:%v, lo: %v, hi:%v \n", frame ,lo, hi)
|
//fmt.Printf("zerorange frame:%v, lo: %v, hi:%v \n", frame ,lo, hi)
|
||||||
|
|
@ -28,7 +29,7 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
|
||||||
// MOVW R0, (Widthptr)r1
|
// MOVW R0, (Widthptr)r1
|
||||||
// ADD $Widthptr, r1
|
// ADD $Widthptr, r1
|
||||||
// BNE r1, r2, loop
|
// BNE r1, r2, loop
|
||||||
p = pp.Appendpp(p, mips.AADD, obj.TYPE_CONST, 0, gc.Ctxt.FixedFrameSize()+off-4, obj.TYPE_REG, mips.REGRT1, 0)
|
p = pp.Appendpp(p, mips.AADD, obj.TYPE_CONST, 0, base.Ctxt.FixedFrameSize()+off-4, obj.TYPE_REG, mips.REGRT1, 0)
|
||||||
p.Reg = mips.REGSP
|
p.Reg = mips.REGSP
|
||||||
p = pp.Appendpp(p, mips.AADD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, mips.REGRT2, 0)
|
p = pp.Appendpp(p, mips.AADD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, mips.REGRT2, 0)
|
||||||
p.Reg = mips.REGRT1
|
p.Reg = mips.REGRT1
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ package mips
|
||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/gc"
|
"cmd/compile/internal/gc"
|
||||||
"cmd/compile/internal/logopt"
|
"cmd/compile/internal/logopt"
|
||||||
"cmd/compile/internal/ssa"
|
"cmd/compile/internal/ssa"
|
||||||
|
|
@ -766,8 +767,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
if logopt.Enabled() {
|
if logopt.Enabled() {
|
||||||
logopt.LogOpt(v.Pos, "nilcheck", "genssa", v.Block.Func.Name)
|
logopt.LogOpt(v.Pos, "nilcheck", "genssa", v.Block.Func.Name)
|
||||||
}
|
}
|
||||||
if gc.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
|
if base.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
|
||||||
gc.Warnl(v.Pos, "generated nil check")
|
base.WarnfAt(v.Pos, "generated nil check")
|
||||||
}
|
}
|
||||||
case ssa.OpMIPSFPFlagTrue,
|
case ssa.OpMIPSFPFlagTrue,
|
||||||
ssa.OpMIPSFPFlagFalse:
|
ssa.OpMIPSFPFlagFalse:
|
||||||
|
|
@ -796,7 +797,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
// caller's SP is FixedFrameSize below the address of the first arg
|
// caller's SP is FixedFrameSize below the address of the first arg
|
||||||
p := s.Prog(mips.AMOVW)
|
p := s.Prog(mips.AMOVW)
|
||||||
p.From.Type = obj.TYPE_ADDR
|
p.From.Type = obj.TYPE_ADDR
|
||||||
p.From.Offset = -gc.Ctxt.FixedFrameSize()
|
p.From.Offset = -base.Ctxt.FixedFrameSize()
|
||||||
p.From.Name = obj.NAME_PARAM
|
p.From.Name = obj.NAME_PARAM
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = v.Reg()
|
p.To.Reg = v.Reg()
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ package mips64
|
||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/gc"
|
"cmd/compile/internal/gc"
|
||||||
"cmd/compile/internal/logopt"
|
"cmd/compile/internal/logopt"
|
||||||
"cmd/compile/internal/ssa"
|
"cmd/compile/internal/ssa"
|
||||||
|
|
@ -724,8 +725,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
if logopt.Enabled() {
|
if logopt.Enabled() {
|
||||||
logopt.LogOpt(v.Pos, "nilcheck", "genssa", v.Block.Func.Name)
|
logopt.LogOpt(v.Pos, "nilcheck", "genssa", v.Block.Func.Name)
|
||||||
}
|
}
|
||||||
if gc.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
|
if base.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
|
||||||
gc.Warnl(v.Pos, "generated nil check")
|
base.WarnfAt(v.Pos, "generated nil check")
|
||||||
}
|
}
|
||||||
case ssa.OpMIPS64FPFlagTrue,
|
case ssa.OpMIPS64FPFlagTrue,
|
||||||
ssa.OpMIPS64FPFlagFalse:
|
ssa.OpMIPS64FPFlagFalse:
|
||||||
|
|
@ -757,7 +758,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
// caller's SP is FixedFrameSize below the address of the first arg
|
// caller's SP is FixedFrameSize below the address of the first arg
|
||||||
p := s.Prog(mips.AMOVV)
|
p := s.Prog(mips.AMOVV)
|
||||||
p.From.Type = obj.TYPE_ADDR
|
p.From.Type = obj.TYPE_ADDR
|
||||||
p.From.Offset = -gc.Ctxt.FixedFrameSize()
|
p.From.Offset = -base.Ctxt.FixedFrameSize()
|
||||||
p.From.Name = obj.NAME_PARAM
|
p.From.Name = obj.NAME_PARAM
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = v.Reg()
|
p.To.Reg = v.Reg()
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package ppc64
|
package ppc64
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/gc"
|
"cmd/compile/internal/gc"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
"cmd/internal/obj/ppc64"
|
"cmd/internal/obj/ppc64"
|
||||||
|
|
@ -16,17 +17,17 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
|
||||||
}
|
}
|
||||||
if cnt < int64(4*gc.Widthptr) {
|
if cnt < int64(4*gc.Widthptr) {
|
||||||
for i := int64(0); i < cnt; i += int64(gc.Widthptr) {
|
for i := int64(0); i < cnt; i += int64(gc.Widthptr) {
|
||||||
p = pp.Appendpp(p, ppc64.AMOVD, obj.TYPE_REG, ppc64.REGZERO, 0, obj.TYPE_MEM, ppc64.REGSP, gc.Ctxt.FixedFrameSize()+off+i)
|
p = pp.Appendpp(p, ppc64.AMOVD, obj.TYPE_REG, ppc64.REGZERO, 0, obj.TYPE_MEM, ppc64.REGSP, base.Ctxt.FixedFrameSize()+off+i)
|
||||||
}
|
}
|
||||||
} else if cnt <= int64(128*gc.Widthptr) {
|
} else if cnt <= int64(128*gc.Widthptr) {
|
||||||
p = pp.Appendpp(p, ppc64.AADD, obj.TYPE_CONST, 0, gc.Ctxt.FixedFrameSize()+off-8, obj.TYPE_REG, ppc64.REGRT1, 0)
|
p = pp.Appendpp(p, ppc64.AADD, obj.TYPE_CONST, 0, base.Ctxt.FixedFrameSize()+off-8, obj.TYPE_REG, ppc64.REGRT1, 0)
|
||||||
p.Reg = ppc64.REGSP
|
p.Reg = ppc64.REGSP
|
||||||
p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
|
p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
|
||||||
p.To.Name = obj.NAME_EXTERN
|
p.To.Name = obj.NAME_EXTERN
|
||||||
p.To.Sym = gc.Duffzero
|
p.To.Sym = gc.Duffzero
|
||||||
p.To.Offset = 4 * (128 - cnt/int64(gc.Widthptr))
|
p.To.Offset = 4 * (128 - cnt/int64(gc.Widthptr))
|
||||||
} else {
|
} else {
|
||||||
p = pp.Appendpp(p, ppc64.AMOVD, obj.TYPE_CONST, 0, gc.Ctxt.FixedFrameSize()+off-8, obj.TYPE_REG, ppc64.REGTMP, 0)
|
p = pp.Appendpp(p, ppc64.AMOVD, obj.TYPE_CONST, 0, base.Ctxt.FixedFrameSize()+off-8, obj.TYPE_REG, ppc64.REGTMP, 0)
|
||||||
p = pp.Appendpp(p, ppc64.AADD, obj.TYPE_REG, ppc64.REGTMP, 0, obj.TYPE_REG, ppc64.REGRT1, 0)
|
p = pp.Appendpp(p, ppc64.AADD, obj.TYPE_REG, ppc64.REGTMP, 0, obj.TYPE_REG, ppc64.REGRT1, 0)
|
||||||
p.Reg = ppc64.REGSP
|
p.Reg = ppc64.REGSP
|
||||||
p = pp.Appendpp(p, ppc64.AMOVD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, ppc64.REGTMP, 0)
|
p = pp.Appendpp(p, ppc64.AMOVD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, ppc64.REGTMP, 0)
|
||||||
|
|
@ -66,7 +67,7 @@ func ginsnopdefer(pp *gc.Progs) *obj.Prog {
|
||||||
// on ppc64 in both shared and non-shared modes.
|
// on ppc64 in both shared and non-shared modes.
|
||||||
|
|
||||||
ginsnop(pp)
|
ginsnop(pp)
|
||||||
if gc.Ctxt.Flag_shared {
|
if base.Ctxt.Flag_shared {
|
||||||
p := pp.Prog(ppc64.AMOVD)
|
p := pp.Prog(ppc64.AMOVD)
|
||||||
p.From.Type = obj.TYPE_MEM
|
p.From.Type = obj.TYPE_MEM
|
||||||
p.From.Offset = 24
|
p.From.Offset = 24
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package ppc64
|
package ppc64
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/gc"
|
"cmd/compile/internal/gc"
|
||||||
"cmd/compile/internal/logopt"
|
"cmd/compile/internal/logopt"
|
||||||
"cmd/compile/internal/ssa"
|
"cmd/compile/internal/ssa"
|
||||||
|
|
@ -473,7 +474,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
// caller's SP is FixedFrameSize below the address of the first arg
|
// caller's SP is FixedFrameSize below the address of the first arg
|
||||||
p := s.Prog(ppc64.AMOVD)
|
p := s.Prog(ppc64.AMOVD)
|
||||||
p.From.Type = obj.TYPE_ADDR
|
p.From.Type = obj.TYPE_ADDR
|
||||||
p.From.Offset = -gc.Ctxt.FixedFrameSize()
|
p.From.Offset = -base.Ctxt.FixedFrameSize()
|
||||||
p.From.Name = obj.NAME_PARAM
|
p.From.Name = obj.NAME_PARAM
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = v.Reg()
|
p.To.Reg = v.Reg()
|
||||||
|
|
@ -1784,7 +1785,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
// Insert a hint this is not a subroutine return.
|
// Insert a hint this is not a subroutine return.
|
||||||
pp.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: 1})
|
pp.SetFrom3(obj.Addr{Type: obj.TYPE_CONST, Offset: 1})
|
||||||
|
|
||||||
if gc.Ctxt.Flag_shared {
|
if base.Ctxt.Flag_shared {
|
||||||
// When compiling Go into PIC, the function we just
|
// When compiling Go into PIC, the function we just
|
||||||
// called via pointer might have been implemented in
|
// called via pointer might have been implemented in
|
||||||
// a separate module and so overwritten the TOC
|
// a separate module and so overwritten the TOC
|
||||||
|
|
@ -1852,8 +1853,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
if logopt.Enabled() {
|
if logopt.Enabled() {
|
||||||
logopt.LogOpt(v.Pos, "nilcheck", "genssa", v.Block.Func.Name)
|
logopt.LogOpt(v.Pos, "nilcheck", "genssa", v.Block.Func.Name)
|
||||||
}
|
}
|
||||||
if gc.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
|
if base.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
|
||||||
gc.Warnl(v.Pos, "generated nil check")
|
base.WarnfAt(v.Pos, "generated nil check")
|
||||||
}
|
}
|
||||||
|
|
||||||
// These should be resolved by rules and not make it here.
|
// These should be resolved by rules and not make it here.
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package riscv64
|
package riscv64
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/gc"
|
"cmd/compile/internal/gc"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
"cmd/internal/obj/riscv"
|
"cmd/internal/obj/riscv"
|
||||||
|
|
@ -16,7 +17,7 @@ func zeroRange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust the frame to account for LR.
|
// Adjust the frame to account for LR.
|
||||||
off += gc.Ctxt.FixedFrameSize()
|
off += base.Ctxt.FixedFrameSize()
|
||||||
|
|
||||||
if cnt < int64(4*gc.Widthptr) {
|
if cnt < int64(4*gc.Widthptr) {
|
||||||
for i := int64(0); i < cnt; i += int64(gc.Widthptr) {
|
for i := int64(0); i < cnt; i += int64(gc.Widthptr) {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package riscv64
|
package riscv64
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/gc"
|
"cmd/compile/internal/gc"
|
||||||
"cmd/compile/internal/ssa"
|
"cmd/compile/internal/ssa"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
|
|
@ -91,7 +92,7 @@ func loadByType(t *types.Type) obj.As {
|
||||||
case 8:
|
case 8:
|
||||||
return riscv.AMOVD
|
return riscv.AMOVD
|
||||||
default:
|
default:
|
||||||
gc.Fatalf("unknown float width for load %d in type %v", width, t)
|
base.Fatalf("unknown float width for load %d in type %v", width, t)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -118,7 +119,7 @@ func loadByType(t *types.Type) obj.As {
|
||||||
case 8:
|
case 8:
|
||||||
return riscv.AMOV
|
return riscv.AMOV
|
||||||
default:
|
default:
|
||||||
gc.Fatalf("unknown width for load %d in type %v", width, t)
|
base.Fatalf("unknown width for load %d in type %v", width, t)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -134,7 +135,7 @@ func storeByType(t *types.Type) obj.As {
|
||||||
case 8:
|
case 8:
|
||||||
return riscv.AMOVD
|
return riscv.AMOVD
|
||||||
default:
|
default:
|
||||||
gc.Fatalf("unknown float width for store %d in type %v", width, t)
|
base.Fatalf("unknown float width for store %d in type %v", width, t)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -149,7 +150,7 @@ func storeByType(t *types.Type) obj.As {
|
||||||
case 8:
|
case 8:
|
||||||
return riscv.AMOV
|
return riscv.AMOV
|
||||||
default:
|
default:
|
||||||
gc.Fatalf("unknown width for store %d in type %v", width, t)
|
base.Fatalf("unknown width for store %d in type %v", width, t)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -586,8 +587,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
gc.AddAux(&p.From, v)
|
gc.AddAux(&p.From, v)
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = riscv.REG_ZERO
|
p.To.Reg = riscv.REG_ZERO
|
||||||
if gc.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Pos == 1 in generated wrappers
|
if base.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Pos == 1 in generated wrappers
|
||||||
gc.Warnl(v.Pos, "generated nil check")
|
base.WarnfAt(v.Pos, "generated nil check")
|
||||||
}
|
}
|
||||||
|
|
||||||
case ssa.OpRISCV64LoweredGetClosurePtr:
|
case ssa.OpRISCV64LoweredGetClosurePtr:
|
||||||
|
|
@ -598,7 +599,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
// caller's SP is FixedFrameSize below the address of the first arg
|
// caller's SP is FixedFrameSize below the address of the first arg
|
||||||
p := s.Prog(riscv.AMOV)
|
p := s.Prog(riscv.AMOV)
|
||||||
p.From.Type = obj.TYPE_ADDR
|
p.From.Type = obj.TYPE_ADDR
|
||||||
p.From.Offset = -gc.Ctxt.FixedFrameSize()
|
p.From.Offset = -base.Ctxt.FixedFrameSize()
|
||||||
p.From.Name = obj.NAME_PARAM
|
p.From.Name = obj.NAME_PARAM
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = v.Reg()
|
p.To.Reg = v.Reg()
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package s390x
|
package s390x
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/gc"
|
"cmd/compile/internal/gc"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
"cmd/internal/obj/s390x"
|
"cmd/internal/obj/s390x"
|
||||||
|
|
@ -23,7 +24,7 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust the frame to account for LR.
|
// Adjust the frame to account for LR.
|
||||||
off += gc.Ctxt.FixedFrameSize()
|
off += base.Ctxt.FixedFrameSize()
|
||||||
reg := int16(s390x.REGSP)
|
reg := int16(s390x.REGSP)
|
||||||
|
|
||||||
// If the off cannot fit in a 12-bit unsigned displacement then we
|
// If the off cannot fit in a 12-bit unsigned displacement then we
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ package s390x
|
||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/gc"
|
"cmd/compile/internal/gc"
|
||||||
"cmd/compile/internal/logopt"
|
"cmd/compile/internal/logopt"
|
||||||
"cmd/compile/internal/ssa"
|
"cmd/compile/internal/ssa"
|
||||||
|
|
@ -573,7 +574,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
// caller's SP is FixedFrameSize below the address of the first arg
|
// caller's SP is FixedFrameSize below the address of the first arg
|
||||||
p := s.Prog(s390x.AMOVD)
|
p := s.Prog(s390x.AMOVD)
|
||||||
p.From.Type = obj.TYPE_ADDR
|
p.From.Type = obj.TYPE_ADDR
|
||||||
p.From.Offset = -gc.Ctxt.FixedFrameSize()
|
p.From.Offset = -base.Ctxt.FixedFrameSize()
|
||||||
p.From.Name = obj.NAME_PARAM
|
p.From.Name = obj.NAME_PARAM
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = v.Reg()
|
p.To.Reg = v.Reg()
|
||||||
|
|
@ -642,8 +643,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
if logopt.Enabled() {
|
if logopt.Enabled() {
|
||||||
logopt.LogOpt(v.Pos, "nilcheck", "genssa", v.Block.Func.Name)
|
logopt.LogOpt(v.Pos, "nilcheck", "genssa", v.Block.Func.Name)
|
||||||
}
|
}
|
||||||
if gc.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
|
if base.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
|
||||||
gc.Warnl(v.Pos, "generated nil check")
|
base.WarnfAt(v.Pos, "generated nil check")
|
||||||
}
|
}
|
||||||
case ssa.OpS390XMVC:
|
case ssa.OpS390XMVC:
|
||||||
vo := v.AuxValAndOff()
|
vo := v.AuxValAndOff()
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package wasm
|
package wasm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/gc"
|
"cmd/compile/internal/gc"
|
||||||
"cmd/compile/internal/logopt"
|
"cmd/compile/internal/logopt"
|
||||||
"cmd/compile/internal/ssa"
|
"cmd/compile/internal/ssa"
|
||||||
|
|
@ -33,7 +34,7 @@ func zeroRange(pp *gc.Progs, p *obj.Prog, off, cnt int64, state *uint32) *obj.Pr
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
if cnt%8 != 0 {
|
if cnt%8 != 0 {
|
||||||
gc.Fatalf("zerorange count not a multiple of widthptr %d", cnt)
|
base.Fatalf("zerorange count not a multiple of widthptr %d", cnt)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := int64(0); i < cnt; i += 8 {
|
for i := int64(0); i < cnt; i += 8 {
|
||||||
|
|
@ -165,8 +166,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
if logopt.Enabled() {
|
if logopt.Enabled() {
|
||||||
logopt.LogOpt(v.Pos, "nilcheck", "genssa", v.Block.Func.Name)
|
logopt.LogOpt(v.Pos, "nilcheck", "genssa", v.Block.Func.Name)
|
||||||
}
|
}
|
||||||
if gc.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
|
if base.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
|
||||||
gc.Warnl(v.Pos, "generated nil check")
|
base.WarnfAt(v.Pos, "generated nil check")
|
||||||
}
|
}
|
||||||
|
|
||||||
case ssa.OpWasmLoweredWB:
|
case ssa.OpWasmLoweredWB:
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package x86
|
package x86
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/gc"
|
"cmd/compile/internal/gc"
|
||||||
"cmd/internal/obj/x86"
|
"cmd/internal/obj/x86"
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
|
|
@ -24,10 +25,10 @@ func Init(arch *gc.Arch) {
|
||||||
arch.SoftFloat = true
|
arch.SoftFloat = true
|
||||||
case "387":
|
case "387":
|
||||||
fmt.Fprintf(os.Stderr, "unsupported setting GO386=387. Consider using GO386=softfloat instead.\n")
|
fmt.Fprintf(os.Stderr, "unsupported setting GO386=387. Consider using GO386=softfloat instead.\n")
|
||||||
gc.Exit(1)
|
base.Exit(1)
|
||||||
default:
|
default:
|
||||||
fmt.Fprintf(os.Stderr, "unsupported setting GO386=%s\n", v)
|
fmt.Fprintf(os.Stderr, "unsupported setting GO386=%s\n", v)
|
||||||
gc.Exit(1)
|
base.Exit(1)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/gc"
|
"cmd/compile/internal/gc"
|
||||||
"cmd/compile/internal/logopt"
|
"cmd/compile/internal/logopt"
|
||||||
"cmd/compile/internal/ssa"
|
"cmd/compile/internal/ssa"
|
||||||
|
|
@ -480,9 +481,9 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
p.From.Name = obj.NAME_EXTERN
|
p.From.Name = obj.NAME_EXTERN
|
||||||
f := math.Float64frombits(uint64(v.AuxInt))
|
f := math.Float64frombits(uint64(v.AuxInt))
|
||||||
if v.Op == ssa.Op386MOVSDconst1 {
|
if v.Op == ssa.Op386MOVSDconst1 {
|
||||||
p.From.Sym = gc.Ctxt.Float64Sym(f)
|
p.From.Sym = base.Ctxt.Float64Sym(f)
|
||||||
} else {
|
} else {
|
||||||
p.From.Sym = gc.Ctxt.Float32Sym(float32(f))
|
p.From.Sym = base.Ctxt.Float32Sym(float32(f))
|
||||||
}
|
}
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = v.Reg()
|
p.To.Reg = v.Reg()
|
||||||
|
|
@ -713,7 +714,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
r := v.Reg()
|
r := v.Reg()
|
||||||
// See the comments in cmd/internal/obj/x86/obj6.go
|
// See the comments in cmd/internal/obj/x86/obj6.go
|
||||||
// near CanUse1InsnTLS for a detailed explanation of these instructions.
|
// near CanUse1InsnTLS for a detailed explanation of these instructions.
|
||||||
if x86.CanUse1InsnTLS(gc.Ctxt) {
|
if x86.CanUse1InsnTLS(base.Ctxt) {
|
||||||
// MOVL (TLS), r
|
// MOVL (TLS), r
|
||||||
p := s.Prog(x86.AMOVL)
|
p := s.Prog(x86.AMOVL)
|
||||||
p.From.Type = obj.TYPE_MEM
|
p.From.Type = obj.TYPE_MEM
|
||||||
|
|
@ -749,7 +750,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
// caller's SP is the address of the first arg
|
// caller's SP is the address of the first arg
|
||||||
p := s.Prog(x86.AMOVL)
|
p := s.Prog(x86.AMOVL)
|
||||||
p.From.Type = obj.TYPE_ADDR
|
p.From.Type = obj.TYPE_ADDR
|
||||||
p.From.Offset = -gc.Ctxt.FixedFrameSize() // 0 on 386, just to be consistent with other architectures
|
p.From.Offset = -base.Ctxt.FixedFrameSize() // 0 on 386, just to be consistent with other architectures
|
||||||
p.From.Name = obj.NAME_PARAM
|
p.From.Name = obj.NAME_PARAM
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = v.Reg()
|
p.To.Reg = v.Reg()
|
||||||
|
|
@ -850,8 +851,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
if logopt.Enabled() {
|
if logopt.Enabled() {
|
||||||
logopt.LogOpt(v.Pos, "nilcheck", "genssa", v.Block.Func.Name)
|
logopt.LogOpt(v.Pos, "nilcheck", "genssa", v.Block.Func.Name)
|
||||||
}
|
}
|
||||||
if gc.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
|
if base.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
|
||||||
gc.Warnl(v.Pos, "generated nil check")
|
base.WarnfAt(v.Pos, "generated nil check")
|
||||||
}
|
}
|
||||||
case ssa.OpClobber:
|
case ssa.OpClobber:
|
||||||
p := s.Prog(x86.AMOVL)
|
p := s.Prog(x86.AMOVL)
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"cmd/compile/internal/amd64"
|
"cmd/compile/internal/amd64"
|
||||||
"cmd/compile/internal/arm"
|
"cmd/compile/internal/arm"
|
||||||
"cmd/compile/internal/arm64"
|
"cmd/compile/internal/arm64"
|
||||||
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/gc"
|
"cmd/compile/internal/gc"
|
||||||
"cmd/compile/internal/mips"
|
"cmd/compile/internal/mips"
|
||||||
"cmd/compile/internal/mips64"
|
"cmd/compile/internal/mips64"
|
||||||
|
|
@ -50,5 +51,5 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
gc.Main(archInit)
|
gc.Main(archInit)
|
||||||
gc.Exit(0)
|
base.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2
src/cmd/dist/buildtool.go
vendored
2
src/cmd/dist/buildtool.go
vendored
|
|
@ -38,6 +38,7 @@ var bootstrapDirs = []string{
|
||||||
"cmd/cgo",
|
"cmd/cgo",
|
||||||
"cmd/compile",
|
"cmd/compile",
|
||||||
"cmd/compile/internal/amd64",
|
"cmd/compile/internal/amd64",
|
||||||
|
"cmd/compile/internal/base",
|
||||||
"cmd/compile/internal/arm",
|
"cmd/compile/internal/arm",
|
||||||
"cmd/compile/internal/arm64",
|
"cmd/compile/internal/arm64",
|
||||||
"cmd/compile/internal/gc",
|
"cmd/compile/internal/gc",
|
||||||
|
|
@ -72,6 +73,7 @@ var bootstrapDirs = []string{
|
||||||
"cmd/internal/sys",
|
"cmd/internal/sys",
|
||||||
"cmd/link",
|
"cmd/link",
|
||||||
"cmd/link/internal/amd64",
|
"cmd/link/internal/amd64",
|
||||||
|
"cmd/compile/internal/base",
|
||||||
"cmd/link/internal/arm",
|
"cmd/link/internal/arm",
|
||||||
"cmd/link/internal/arm64",
|
"cmd/link/internal/arm64",
|
||||||
"cmd/link/internal/benchmark",
|
"cmd/link/internal/benchmark",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue