- The Match and Glob functions now
+ The Match and
+ Glob functions now
return an error if the unmatched part of the pattern has a
syntax error. Previously, the functions returned early on a failed
match, and thus did not report any later syntax error in the
@@ -814,9 +848,10 @@ Do not send CLs removing the interior tags from such phrases.
- reflect
-
- StructTag now allows multiple space-separated keys
- in key:value pairs, as in `json xml:"field1"`
- (equivalent to `json:"field1" xml:"field1"`).
+ StructTag
+ now allows multiple space-separated keys in key:value pairs,
+ as in `json xml:"field1"` (equivalent to
+ `json:"field1" xml:"field1"`).
diff --git a/doc/install-source.html b/doc/install-source.html
index c6dc3aed43..f0a909263c 100644
--- a/doc/install-source.html
+++ b/doc/install-source.html
@@ -119,11 +119,26 @@ The Go toolchain is written in Go. To build it, you need a Go compiler installed
The scripts that do the initial build of the tools look for a "go" command
in $PATH, so as long as you have Go installed in your
system and configured in your $PATH, you are ready to build Go
-from source.
+from source.
Or if you prefer you can set $GOROOT_BOOTSTRAP to the
root of a Go installation to use to build the new Go toolchain;
$GOROOT_BOOTSTRAP/bin/go should be the go command to use.
+
+There are four possible ways to obtain a bootstrap toolchain:
+
+
+
+- Download a recent binary release of Go.
+
- Cross-compile a toolchain using a system with a working Go installation.
+
- Use gccgo.
+
- Compile a toolchain from Go 1.4, the last Go release with a compiler written in C.
+
+
+
+These approaches are detailed below.
+
+
Bootstrap toolchain from binary release
@@ -132,30 +147,6 @@ To use a binary release as a bootstrap toolchain, see
packaged Go distribution.
-Bootstrap toolchain from source
-
-
-To build a bootstrap toolchain from source, use
-either the git branch release-branch.go1.4 or
-go1.4-bootstrap-20171003.tar.gz,
-which contains the Go 1.4 source code plus accumulated fixes
-to keep the tools running on newer operating systems.
-(Go 1.4 was the last distribution in which the toolchain was written in C.)
-After unpacking the Go 1.4 source, cd to
-the src subdirectory, set CGO_ENABLED=0 in
-the environment, and run make.bash (or,
-on Windows, make.bat).
-
-
-
-Once the Go 1.4 source has been unpacked into your GOROOT_BOOTSTRAP directory,
-you must keep this git clone instance checked out to branch
-release-branch.go1.4. Specifically, do not attempt to reuse
-this git clone in the later step named "Fetch the repository." The go1.4
-bootstrap toolchain must be able to properly traverse the go1.4 sources
-that it assumes are present under this repository root.
-
-
Bootstrap toolchain from cross-compiled source
@@ -194,6 +185,36 @@ $ sudo update-alternatives --set go /usr/bin/go-5
$ GOROOT_BOOTSTRAP=/usr ./make.bash
+
Bootstrap toolchain from C source code
+
+
+To build a bootstrap toolchain from C source code, use
+either the git branch release-branch.go1.4 or
+go1.4-bootstrap-20171003.tar.gz,
+which contains the Go 1.4 source code plus accumulated fixes
+to keep the tools running on newer operating systems.
+(Go 1.4 was the last distribution in which the toolchain was written in C.)
+After unpacking the Go 1.4 source, cd to
+the src subdirectory, set CGO_ENABLED=0 in
+the environment, and run make.bash (or,
+on Windows, make.bat).
+
+
+
+Once the Go 1.4 source has been unpacked into your GOROOT_BOOTSTRAP directory,
+you must keep this git clone instance checked out to branch
+release-branch.go1.4. Specifically, do not attempt to reuse
+this git clone in the later step named "Fetch the repository." The go1.4
+bootstrap toolchain must be able to properly traverse the go1.4 sources
+that it assumes are present under this repository root.
+
+
+
+Note that Go 1.4 does not run on all systems that later versions of Go do.
+In particular, Go 1.4 does not support current versions of macOS.
+On such systems, the bootstrap toolchain must be obtained using one of the other methods.
+
+
Install Git, if needed
diff --git a/src/cmd/asm/internal/flags/flags.go b/src/cmd/asm/internal/flags/flags.go
index 426e0156aa..1335860315 100644
--- a/src/cmd/asm/internal/flags/flags.go
+++ b/src/cmd/asm/internal/flags/flags.go
@@ -20,6 +20,7 @@ var (
TrimPath = flag.String("trimpath", "", "remove prefix from recorded source file paths")
Shared = flag.Bool("shared", false, "generate code that can be linked into a shared library")
Dynlink = flag.Bool("dynlink", false, "support references to Go symbols defined in other shared libraries")
+ Linkshared = flag.Bool("linkshared", false, "generate code that will be linked against Go shared libraries")
AllErrors = flag.Bool("e", false, "no limit on number of errors reported")
SymABIs = flag.Bool("gensymabis", false, "write symbol ABI information to output file, don't assemble")
Importpath = flag.String("p", "", "set expected package import to path")
diff --git a/src/cmd/asm/main.go b/src/cmd/asm/main.go
index 149925d23f..31636e3045 100644
--- a/src/cmd/asm/main.go
+++ b/src/cmd/asm/main.go
@@ -37,6 +37,7 @@ func main() {
ctxt := obj.Linknew(architecture.LinkArch)
ctxt.Debugasm = flags.PrintOut
ctxt.Flag_dynlink = *flags.Dynlink
+ ctxt.Flag_linkshared = *flags.Linkshared
ctxt.Flag_shared = *flags.Shared || *flags.Dynlink
ctxt.IsAsm = true
ctxt.Pkgpath = *flags.Importpath
diff --git a/src/cmd/compile/internal/gc/inl.go b/src/cmd/compile/internal/gc/inl.go
index b571c2b914..d81aa52651 100644
--- a/src/cmd/compile/internal/gc/inl.go
+++ b/src/cmd/compile/internal/gc/inl.go
@@ -740,7 +740,7 @@ func reassigned(name *ir.Name) bool {
if n.Left() == name && n != name.Defn {
return true
}
- case ir.OAS2, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2DOTTYPE:
+ case ir.OAS2, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2DOTTYPE, ir.OAS2RECV, ir.OSELRECV2:
for _, p := range n.List().Slice() {
if p == name && n != name.Defn {
return true
diff --git a/src/cmd/compile/internal/gc/order.go b/src/cmd/compile/internal/gc/order.go
index 87d7cf3aa9..888e8ea907 100644
--- a/src/cmd/compile/internal/gc/order.go
+++ b/src/cmd/compile/internal/gc/order.go
@@ -894,7 +894,7 @@ func (o *Order) stmt(n ir.Node) {
// case x, ok = <-c
recv := r.Rlist().First().(*ir.UnaryExpr)
recv.SetLeft(o.expr(recv.Left(), nil))
- if recv.Left().Op() != ir.ONAME {
+ if !ir.IsAutoTmp(recv.Left()) {
recv.SetLeft(o.copyExpr(recv.Left()))
}
r := r.(*ir.AssignListStmt)
diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go
index fbfed0640d..d3b4e903b2 100644
--- a/src/cmd/compile/internal/gc/ssa.go
+++ b/src/cmd/compile/internal/gc/ssa.go
@@ -6003,7 +6003,7 @@ func (s *state) dottype(n *ir.TypeAssertExpr, commaok bool) (res, resok *ssa.Val
// Load type out of itab, build interface with existing idata.
off := s.newValue1I(ssa.OpOffPtr, byteptr, int64(Widthptr), itab)
typ := s.load(byteptr, off)
- idata := s.newValue1(ssa.OpIData, n.Type(), iface)
+ idata := s.newValue1(ssa.OpIData, byteptr, iface)
res = s.newValue2(ssa.OpIMake, n.Type(), typ, idata)
return
}
@@ -6025,7 +6025,7 @@ func (s *state) dottype(n *ir.TypeAssertExpr, commaok bool) (res, resok *ssa.Val
bOk.AddEdgeTo(bEnd)
bFail.AddEdgeTo(bEnd)
s.startBlock(bEnd)
- idata := s.newValue1(ssa.OpIData, n.Type(), iface)
+ idata := s.newValue1(ssa.OpIData, byteptr, iface)
res = s.newValue2(ssa.OpIMake, n.Type(), s.variable(typVar, byteptr), idata)
resok = cond
delete(s.vars, typVar)
diff --git a/src/cmd/compile/internal/ssa/check.go b/src/cmd/compile/internal/ssa/check.go
index 4d57eef556..9e4aa6cd79 100644
--- a/src/cmd/compile/internal/ssa/check.go
+++ b/src/cmd/compile/internal/ssa/check.go
@@ -147,6 +147,11 @@ func checkFunc(f *Func) {
canHaveAuxInt = true
case auxInt128:
// AuxInt must be zero, so leave canHaveAuxInt set to false.
+ case auxUInt8:
+ if v.AuxInt != int64(uint8(v.AuxInt)) {
+ f.Fatalf("bad uint8 AuxInt value for %v", v)
+ }
+ canHaveAuxInt = true
case auxFloat32:
canHaveAuxInt = true
if math.IsNaN(v.AuxFloat()) {
diff --git a/src/cmd/compile/internal/ssa/expand_calls.go b/src/cmd/compile/internal/ssa/expand_calls.go
index 0eba238d81..e1c657d4a4 100644
--- a/src/cmd/compile/internal/ssa/expand_calls.go
+++ b/src/cmd/compile/internal/ssa/expand_calls.go
@@ -196,9 +196,6 @@ func expandCalls(f *Func) {
}
if leaf.Op == OpIData {
leafType = removeTrivialWrapperTypes(leaf.Type)
- if leafType.IsEmptyInterface() {
- leafType = typ.BytePtr
- }
}
aux := selector.Aux
auxInt := selector.AuxInt + offset
@@ -247,12 +244,9 @@ func expandCalls(f *Func) {
// i.e., the struct select is generated and remains in because it is not applied to an actual structure.
// The OpLoad was created to load the single field of the IData
// This case removes that StructSelect.
- if leafType != selector.Type && !selector.Type.IsEmptyInterface() { // empty interface for #42727
+ if leafType != selector.Type {
f.Fatalf("Unexpected Load as selector, leaf=%s, selector=%s\n", leaf.LongString(), selector.LongString())
}
- if selector.Type.IsEmptyInterface() {
- selector.Type = typ.BytePtr
- }
leaf.copyOf(selector)
for _, s := range namedSelects[selector] {
locs = append(locs, f.Names[s.locIndex])
diff --git a/src/cmd/compile/internal/ssa/gen/S390X.rules b/src/cmd/compile/internal/ssa/gen/S390X.rules
index 39949edbc2..384f2e807e 100644
--- a/src/cmd/compile/internal/ssa/gen/S390X.rules
+++ b/src/cmd/compile/internal/ssa/gen/S390X.rules
@@ -663,8 +663,8 @@
((OR|XOR)W x (MOVDconst [c])) => ((OR|XOR)Wconst [int32(c)] x)
// Constant shifts.
-(S(LD|RD|RAD) x (MOVDconst [c])) => (S(LD|RD|RAD)const x [int8(c&63)])
-(S(LW|RW|RAW) x (MOVDconst [c])) && c&32 == 0 => (S(LW|RW|RAW)const x [int8(c&31)])
+(S(LD|RD|RAD) x (MOVDconst [c])) => (S(LD|RD|RAD)const x [uint8(c&63)])
+(S(LW|RW|RAW) x (MOVDconst [c])) && c&32 == 0 => (S(LW|RW|RAW)const x [uint8(c&31)])
(S(LW|RW) _ (MOVDconst [c])) && c&32 != 0 => (MOVDconst [0])
(SRAW x (MOVDconst [c])) && c&32 != 0 => (SRAWconst x [31])
@@ -685,8 +685,8 @@
(SRAW x (MOV(W|H|B|WZ|HZ|BZ)reg y)) => (SRAW x y)
// Match rotate by constant.
-(RLLG x (MOVDconst [c])) => (RISBGZ x {s390x.NewRotateParams(0, 63, int8(c&63))})
-(RLL x (MOVDconst [c])) => (RLLconst x [int8(c&31)])
+(RLLG x (MOVDconst [c])) => (RISBGZ x {s390x.NewRotateParams(0, 63, uint8(c&63))})
+(RLL x (MOVDconst [c])) => (RLLconst x [uint8(c&31)])
// Match rotate by constant pattern.
((ADD|OR|XOR) (SLDconst x [c]) (SRDconst x [64-c])) => (RISBGZ x {s390x.NewRotateParams(0, 63, c)})
@@ -705,10 +705,10 @@
(CMP(W|WU) (MOVDconst [c]) x) => (InvertFlags (CMP(W|WU)const x [int32(c)]))
// Match (x >> c) << d to 'rotate then insert selected bits [into zero]'.
-(SLDconst (SRDconst x [c]) [d]) => (RISBGZ x {s390x.NewRotateParams(max8(0, c-d), 63-d, (d-c)&63)})
+(SLDconst (SRDconst x [c]) [d]) => (RISBGZ x {s390x.NewRotateParams(uint8(max8(0, int8(c-d))), 63-d, uint8(int8(d-c)&63))})
// Match (x << c) >> d to 'rotate then insert selected bits [into zero]'.
-(SRDconst (SLDconst x [c]) [d]) => (RISBGZ x {s390x.NewRotateParams(d, min8(63, 63-c+d), (c-d)&63)})
+(SRDconst (SLDconst x [c]) [d]) => (RISBGZ x {s390x.NewRotateParams(d, uint8(min8(63, int8(63-c+d))), uint8(int8(c-d)&63))})
// Absorb input zero extension into 'rotate then insert selected bits [into zero]'.
(RISBGZ (MOVWZreg x) {r}) && r.InMerge(0xffffffff) != nil => (RISBGZ x {*r.InMerge(0xffffffff)})
@@ -818,18 +818,18 @@
// c = 2ˣ + 2ʸ => c - 2ˣ = 2ʸ
(MULL(D|W)const x [c]) && isPowerOfTwo32(c&(c-1))
- => ((ADD|ADDW) (SL(D|W)const x [int8(log32(c&(c-1)))])
- (SL(D|W)const x [int8(log32(c&^(c-1)))]))
+ => ((ADD|ADDW) (SL(D|W)const x [uint8(log32(c&(c-1)))])
+ (SL(D|W)const x [uint8(log32(c&^(c-1)))]))
// c = 2ʸ - 2ˣ => c + 2ˣ = 2ʸ
(MULL(D|W)const x [c]) && isPowerOfTwo32(c+(c&^(c-1)))
- => ((SUB|SUBW) (SL(D|W)const x [int8(log32(c+(c&^(c-1))))])
- (SL(D|W)const x [int8(log32(c&^(c-1)))]))
+ => ((SUB|SUBW) (SL(D|W)const x [uint8(log32(c+(c&^(c-1))))])
+ (SL(D|W)const x [uint8(log32(c&^(c-1)))]))
// c = 2ˣ - 2ʸ => -c + 2ˣ = 2ʸ
(MULL(D|W)const x [c]) && isPowerOfTwo32(-c+(-c&^(-c-1)))
- => ((SUB|SUBW) (SL(D|W)const x [int8(log32(-c&^(-c-1)))])
- (SL(D|W)const x [int8(log32(-c+(-c&^(-c-1))))]))
+ => ((SUB|SUBW) (SL(D|W)const x [uint8(log32(-c&^(-c-1)))])
+ (SL(D|W)const x [uint8(log32(-c+(-c&^(-c-1))))]))
// Fold ADD into MOVDaddr. Odd offsets from SB shouldn't be folded (LARL can't handle them).
(ADDconst [c] (MOVDaddr [d] {s} x:(SB))) && ((c+d)&1 == 0) && is32Bit(int64(c)+int64(d)) => (MOVDaddr [c+d] {s} x)
diff --git a/src/cmd/compile/internal/ssa/gen/S390XOps.go b/src/cmd/compile/internal/ssa/gen/S390XOps.go
index f0cf2f2f6e..b24fd61942 100644
--- a/src/cmd/compile/internal/ssa/gen/S390XOps.go
+++ b/src/cmd/compile/internal/ssa/gen/S390XOps.go
@@ -330,27 +330,27 @@ func init() {
{name: "LTDBR", argLength: 1, reg: fp1flags, asm: "LTDBR", typ: "Flags"}, // arg0 compare to 0, f64
{name: "LTEBR", argLength: 1, reg: fp1flags, asm: "LTEBR", typ: "Flags"}, // arg0 compare to 0, f32
- {name: "SLD", argLength: 2, reg: sh21, asm: "SLD"}, // arg0 << arg1, shift amount is mod 64
- {name: "SLW", argLength: 2, reg: sh21, asm: "SLW"}, // arg0 << arg1, shift amount is mod 64
- {name: "SLDconst", argLength: 1, reg: gp11, asm: "SLD", aux: "Int8"}, // arg0 << auxint, shift amount 0-63
- {name: "SLWconst", argLength: 1, reg: gp11, asm: "SLW", aux: "Int8"}, // arg0 << auxint, shift amount 0-31
+ {name: "SLD", argLength: 2, reg: sh21, asm: "SLD"}, // arg0 << arg1, shift amount is mod 64
+ {name: "SLW", argLength: 2, reg: sh21, asm: "SLW"}, // arg0 << arg1, shift amount is mod 64
+ {name: "SLDconst", argLength: 1, reg: gp11, asm: "SLD", aux: "UInt8"}, // arg0 << auxint, shift amount 0-63
+ {name: "SLWconst", argLength: 1, reg: gp11, asm: "SLW", aux: "UInt8"}, // arg0 << auxint, shift amount 0-31
- {name: "SRD", argLength: 2, reg: sh21, asm: "SRD"}, // unsigned arg0 >> arg1, shift amount is mod 64
- {name: "SRW", argLength: 2, reg: sh21, asm: "SRW"}, // unsigned uint32(arg0) >> arg1, shift amount is mod 64
- {name: "SRDconst", argLength: 1, reg: gp11, asm: "SRD", aux: "Int8"}, // unsigned arg0 >> auxint, shift amount 0-63
- {name: "SRWconst", argLength: 1, reg: gp11, asm: "SRW", aux: "Int8"}, // unsigned uint32(arg0) >> auxint, shift amount 0-31
+ {name: "SRD", argLength: 2, reg: sh21, asm: "SRD"}, // unsigned arg0 >> arg1, shift amount is mod 64
+ {name: "SRW", argLength: 2, reg: sh21, asm: "SRW"}, // unsigned uint32(arg0) >> arg1, shift amount is mod 64
+ {name: "SRDconst", argLength: 1, reg: gp11, asm: "SRD", aux: "UInt8"}, // unsigned arg0 >> auxint, shift amount 0-63
+ {name: "SRWconst", argLength: 1, reg: gp11, asm: "SRW", aux: "UInt8"}, // unsigned uint32(arg0) >> auxint, shift amount 0-31
// Arithmetic shifts clobber flags.
- {name: "SRAD", argLength: 2, reg: sh21, asm: "SRAD", clobberFlags: true}, // signed arg0 >> arg1, shift amount is mod 64
- {name: "SRAW", argLength: 2, reg: sh21, asm: "SRAW", clobberFlags: true}, // signed int32(arg0) >> arg1, shift amount is mod 64
- {name: "SRADconst", argLength: 1, reg: gp11, asm: "SRAD", aux: "Int8", clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-63
- {name: "SRAWconst", argLength: 1, reg: gp11, asm: "SRAW", aux: "Int8", clobberFlags: true}, // signed int32(arg0) >> auxint, shift amount 0-31
+ {name: "SRAD", argLength: 2, reg: sh21, asm: "SRAD", clobberFlags: true}, // signed arg0 >> arg1, shift amount is mod 64
+ {name: "SRAW", argLength: 2, reg: sh21, asm: "SRAW", clobberFlags: true}, // signed int32(arg0) >> arg1, shift amount is mod 64
+ {name: "SRADconst", argLength: 1, reg: gp11, asm: "SRAD", aux: "UInt8", clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-63
+ {name: "SRAWconst", argLength: 1, reg: gp11, asm: "SRAW", aux: "UInt8", clobberFlags: true}, // signed int32(arg0) >> auxint, shift amount 0-31
// Rotate instructions.
// Note: no RLLGconst - use RISBGZ instead.
- {name: "RLLG", argLength: 2, reg: sh21, asm: "RLLG"}, // arg0 rotate left arg1, rotate amount 0-63
- {name: "RLL", argLength: 2, reg: sh21, asm: "RLL"}, // arg0 rotate left arg1, rotate amount 0-31
- {name: "RLLconst", argLength: 1, reg: gp11, asm: "RLL", aux: "Int8"}, // arg0 rotate left auxint, rotate amount 0-31
+ {name: "RLLG", argLength: 2, reg: sh21, asm: "RLLG"}, // arg0 rotate left arg1, rotate amount 0-63
+ {name: "RLL", argLength: 2, reg: sh21, asm: "RLL"}, // arg0 rotate left arg1, rotate amount 0-31
+ {name: "RLLconst", argLength: 1, reg: gp11, asm: "RLL", aux: "UInt8"}, // arg0 rotate left auxint, rotate amount 0-31
// Rotate then (and|or|xor|insert) selected bits instructions.
//
diff --git a/src/cmd/compile/internal/ssa/gen/rulegen.go b/src/cmd/compile/internal/ssa/gen/rulegen.go
index 120ccbbdb3..aaf9101368 100644
--- a/src/cmd/compile/internal/ssa/gen/rulegen.go
+++ b/src/cmd/compile/internal/ssa/gen/rulegen.go
@@ -1395,7 +1395,7 @@ func parseValue(val string, arch arch, loc string) (op opData, oparch, typ, auxi
func opHasAuxInt(op opData) bool {
switch op.aux {
- case "Bool", "Int8", "Int16", "Int32", "Int64", "Int128", "Float32", "Float64",
+ case "Bool", "Int8", "Int16", "Int32", "Int64", "Int128", "UInt8", "Float32", "Float64",
"SymOff", "CallOff", "SymValAndOff", "TypSize", "ARM64BitField", "FlagConstant", "CCop":
return true
}
@@ -1780,6 +1780,8 @@ func (op opData) auxIntType() string {
return "int64"
case "Int128":
return "int128"
+ case "UInt8":
+ return "uint8"
case "Float32":
return "float32"
case "Float64":
diff --git a/src/cmd/compile/internal/ssa/op.go b/src/cmd/compile/internal/ssa/op.go
index 9bc5aaec02..5e6ce2b508 100644
--- a/src/cmd/compile/internal/ssa/op.go
+++ b/src/cmd/compile/internal/ssa/op.go
@@ -207,6 +207,7 @@ const (
auxInt32 // auxInt is a 32-bit integer
auxInt64 // auxInt is a 64-bit integer
auxInt128 // auxInt represents a 128-bit integer. Always 0.
+ auxUInt8 // auxInt is an 8-bit unsigned integer
auxFloat32 // auxInt is a float32 (encoded with math.Float64bits)
auxFloat64 // auxInt is a float64 (encoded with math.Float64bits)
auxFlagConstant // auxInt is a flagConstant
diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go
index eceef1d91a..83d35cf7e1 100644
--- a/src/cmd/compile/internal/ssa/opGen.go
+++ b/src/cmd/compile/internal/ssa/opGen.go
@@ -30569,7 +30569,7 @@ var opcodeTable = [...]opInfo{
},
{
name: "SLDconst",
- auxType: auxInt8,
+ auxType: auxUInt8,
argLen: 1,
asm: s390x.ASLD,
reg: regInfo{
@@ -30583,7 +30583,7 @@ var opcodeTable = [...]opInfo{
},
{
name: "SLWconst",
- auxType: auxInt8,
+ auxType: auxUInt8,
argLen: 1,
asm: s390x.ASLW,
reg: regInfo{
@@ -30625,7 +30625,7 @@ var opcodeTable = [...]opInfo{
},
{
name: "SRDconst",
- auxType: auxInt8,
+ auxType: auxUInt8,
argLen: 1,
asm: s390x.ASRD,
reg: regInfo{
@@ -30639,7 +30639,7 @@ var opcodeTable = [...]opInfo{
},
{
name: "SRWconst",
- auxType: auxInt8,
+ auxType: auxUInt8,
argLen: 1,
asm: s390x.ASRW,
reg: regInfo{
@@ -30683,7 +30683,7 @@ var opcodeTable = [...]opInfo{
},
{
name: "SRADconst",
- auxType: auxInt8,
+ auxType: auxUInt8,
argLen: 1,
clobberFlags: true,
asm: s390x.ASRAD,
@@ -30698,7 +30698,7 @@ var opcodeTable = [...]opInfo{
},
{
name: "SRAWconst",
- auxType: auxInt8,
+ auxType: auxUInt8,
argLen: 1,
clobberFlags: true,
asm: s390x.ASRAW,
@@ -30741,7 +30741,7 @@ var opcodeTable = [...]opInfo{
},
{
name: "RLLconst",
- auxType: auxInt8,
+ auxType: auxUInt8,
argLen: 1,
asm: s390x.ARLL,
reg: regInfo{
diff --git a/src/cmd/compile/internal/ssa/rewriteS390X.go b/src/cmd/compile/internal/ssa/rewriteS390X.go
index d66113d111..a9722b820c 100644
--- a/src/cmd/compile/internal/ssa/rewriteS390X.go
+++ b/src/cmd/compile/internal/ssa/rewriteS390X.go
@@ -1240,7 +1240,7 @@ func rewriteValueS390X_OpAvg64u(v *Value) bool {
y := v_1
v.reset(OpS390XADD)
v0 := b.NewValue0(v.Pos, OpS390XSRDconst, t)
- v0.AuxInt = int8ToAuxInt(1)
+ v0.AuxInt = uint8ToAuxInt(1)
v1 := b.NewValue0(v.Pos, OpS390XSUB, t)
v1.AddArg2(x, y)
v0.AddArg(v1)
@@ -1737,7 +1737,7 @@ func rewriteValueS390X_OpHmul32(v *Value) bool {
x := v_0
y := v_1
v.reset(OpS390XSRDconst)
- v.AuxInt = int8ToAuxInt(32)
+ v.AuxInt = uint8ToAuxInt(32)
v0 := b.NewValue0(v.Pos, OpS390XMULLD, typ.Int64)
v1 := b.NewValue0(v.Pos, OpS390XMOVWreg, typ.Int64)
v1.AddArg(x)
@@ -1759,7 +1759,7 @@ func rewriteValueS390X_OpHmul32u(v *Value) bool {
x := v_0
y := v_1
v.reset(OpS390XSRDconst)
- v.AuxInt = int8ToAuxInt(32)
+ v.AuxInt = uint8ToAuxInt(32)
v0 := b.NewValue0(v.Pos, OpS390XMULLD, typ.Int64)
v1 := b.NewValue0(v.Pos, OpS390XMOVWZreg, typ.UInt64)
v1.AddArg(x)
@@ -5281,9 +5281,9 @@ func rewriteValueS390X_OpS390XADD(v *Value) bool {
if v_0.Op != OpS390XSLDconst {
continue
}
- c := auxIntToInt8(v_0.AuxInt)
+ c := auxIntToUint8(v_0.AuxInt)
x := v_0.Args[0]
- if v_1.Op != OpS390XSRDconst || auxIntToInt8(v_1.AuxInt) != 64-c || x != v_1.Args[0] {
+ if v_1.Op != OpS390XSRDconst || auxIntToUint8(v_1.AuxInt) != 64-c || x != v_1.Args[0] {
continue
}
v.reset(OpS390XRISBGZ)
@@ -5474,13 +5474,13 @@ func rewriteValueS390X_OpS390XADDW(v *Value) bool {
if v_0.Op != OpS390XSLWconst {
continue
}
- c := auxIntToInt8(v_0.AuxInt)
+ c := auxIntToUint8(v_0.AuxInt)
x := v_0.Args[0]
- if v_1.Op != OpS390XSRWconst || auxIntToInt8(v_1.AuxInt) != 32-c || x != v_1.Args[0] {
+ if v_1.Op != OpS390XSRWconst || auxIntToUint8(v_1.AuxInt) != 32-c || x != v_1.Args[0] {
continue
}
v.reset(OpS390XRLLconst)
- v.AuxInt = int8ToAuxInt(c)
+ v.AuxInt = uint8ToAuxInt(c)
v.AddArg(x)
return true
}
@@ -6460,7 +6460,7 @@ func rewriteValueS390X_OpS390XCMPUconst(v *Value) bool {
if v_0.Op != OpS390XSRDconst {
break
}
- c := auxIntToInt8(v_0.AuxInt)
+ c := auxIntToUint8(v_0.AuxInt)
if !(c > 0 && c < 64 && (1< 0 && c < 32 && (1< 0 && n < 0) {
break
}
@@ -7020,7 +7020,7 @@ func rewriteValueS390X_OpS390XCMPWconst(v *Value) bool {
if x.Op != OpS390XSRWconst {
break
}
- c := auxIntToInt8(x.AuxInt)
+ c := auxIntToUint8(x.AuxInt)
if !(c > 0 && n >= 0) {
break
}
@@ -7112,7 +7112,7 @@ func rewriteValueS390X_OpS390XCMPconst(v *Value) bool {
if v_0.Op != OpS390XSRDconst {
break
}
- c := auxIntToInt8(v_0.AuxInt)
+ c := auxIntToUint8(v_0.AuxInt)
if !(c > 0 && n < 0) {
break
}
@@ -7250,7 +7250,7 @@ func rewriteValueS390X_OpS390XCMPconst(v *Value) bool {
if x.Op != OpS390XSRDconst {
break
}
- c := auxIntToInt8(x.AuxInt)
+ c := auxIntToUint8(x.AuxInt)
if !(c > 0 && n >= 0) {
break
}
@@ -8673,7 +8673,7 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool {
break
}
x_1 := x.Args[1]
- if x_1.Op != OpS390XSRDconst || auxIntToInt8(x_1.AuxInt) != 8 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
+ if x_1.Op != OpS390XSRDconst || auxIntToUint8(x_1.AuxInt) != 8 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpS390XMOVHstore)
@@ -8693,7 +8693,7 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool {
if w0.Op != OpS390XSRDconst {
break
}
- j := auxIntToInt8(w0.AuxInt)
+ j := auxIntToUint8(w0.AuxInt)
w := w0.Args[0]
x := v_2
if x.Op != OpS390XMOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
@@ -8704,7 +8704,7 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool {
break
}
x_1 := x.Args[1]
- if x_1.Op != OpS390XSRDconst || auxIntToInt8(x_1.AuxInt) != j+8 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
+ if x_1.Op != OpS390XSRDconst || auxIntToUint8(x_1.AuxInt) != j+8 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpS390XMOVHstore)
@@ -8730,7 +8730,7 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool {
break
}
x_1 := x.Args[1]
- if x_1.Op != OpS390XSRWconst || auxIntToInt8(x_1.AuxInt) != 8 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
+ if x_1.Op != OpS390XSRWconst || auxIntToUint8(x_1.AuxInt) != 8 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpS390XMOVHstore)
@@ -8750,7 +8750,7 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool {
if w0.Op != OpS390XSRWconst {
break
}
- j := auxIntToInt8(w0.AuxInt)
+ j := auxIntToUint8(w0.AuxInt)
w := w0.Args[0]
x := v_2
if x.Op != OpS390XMOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
@@ -8761,7 +8761,7 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool {
break
}
x_1 := x.Args[1]
- if x_1.Op != OpS390XSRWconst || auxIntToInt8(x_1.AuxInt) != j+8 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
+ if x_1.Op != OpS390XSRWconst || auxIntToUint8(x_1.AuxInt) != j+8 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpS390XMOVHstore)
@@ -8777,7 +8777,7 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
p := v_0
- if v_1.Op != OpS390XSRDconst || auxIntToInt8(v_1.AuxInt) != 8 {
+ if v_1.Op != OpS390XSRDconst || auxIntToUint8(v_1.AuxInt) != 8 {
break
}
w := v_1.Args[0]
@@ -8805,7 +8805,7 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool {
if v_1.Op != OpS390XSRDconst {
break
}
- j := auxIntToInt8(v_1.AuxInt)
+ j := auxIntToUint8(v_1.AuxInt)
w := v_1.Args[0]
x := v_2
if x.Op != OpS390XMOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
@@ -8816,7 +8816,7 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool {
break
}
w0 := x.Args[1]
- if w0.Op != OpS390XSRDconst || auxIntToInt8(w0.AuxInt) != j-8 || w != w0.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
+ if w0.Op != OpS390XSRDconst || auxIntToUint8(w0.AuxInt) != j-8 || w != w0.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpS390XMOVHBRstore)
@@ -8832,7 +8832,7 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
p := v_0
- if v_1.Op != OpS390XSRWconst || auxIntToInt8(v_1.AuxInt) != 8 {
+ if v_1.Op != OpS390XSRWconst || auxIntToUint8(v_1.AuxInt) != 8 {
break
}
w := v_1.Args[0]
@@ -8860,7 +8860,7 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool {
if v_1.Op != OpS390XSRWconst {
break
}
- j := auxIntToInt8(v_1.AuxInt)
+ j := auxIntToUint8(v_1.AuxInt)
w := v_1.Args[0]
x := v_2
if x.Op != OpS390XMOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
@@ -8871,7 +8871,7 @@ func rewriteValueS390X_OpS390XMOVBstore(v *Value) bool {
break
}
w0 := x.Args[1]
- if w0.Op != OpS390XSRWconst || auxIntToInt8(w0.AuxInt) != j-8 || w != w0.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
+ if w0.Op != OpS390XSRWconst || auxIntToUint8(w0.AuxInt) != j-8 || w != w0.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpS390XMOVHBRstore)
@@ -9345,7 +9345,7 @@ func rewriteValueS390X_OpS390XMOVHBRstore(v *Value) bool {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
p := v_0
- if v_1.Op != OpS390XSRDconst || auxIntToInt8(v_1.AuxInt) != 16 {
+ if v_1.Op != OpS390XSRDconst || auxIntToUint8(v_1.AuxInt) != 16 {
break
}
w := v_1.Args[0]
@@ -9373,7 +9373,7 @@ func rewriteValueS390X_OpS390XMOVHBRstore(v *Value) bool {
if v_1.Op != OpS390XSRDconst {
break
}
- j := auxIntToInt8(v_1.AuxInt)
+ j := auxIntToUint8(v_1.AuxInt)
w := v_1.Args[0]
x := v_2
if x.Op != OpS390XMOVHBRstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
@@ -9384,7 +9384,7 @@ func rewriteValueS390X_OpS390XMOVHBRstore(v *Value) bool {
break
}
w0 := x.Args[1]
- if w0.Op != OpS390XSRDconst || auxIntToInt8(w0.AuxInt) != j-16 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) {
+ if w0.Op != OpS390XSRDconst || auxIntToUint8(w0.AuxInt) != j-16 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpS390XMOVWBRstore)
@@ -9400,7 +9400,7 @@ func rewriteValueS390X_OpS390XMOVHBRstore(v *Value) bool {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
p := v_0
- if v_1.Op != OpS390XSRWconst || auxIntToInt8(v_1.AuxInt) != 16 {
+ if v_1.Op != OpS390XSRWconst || auxIntToUint8(v_1.AuxInt) != 16 {
break
}
w := v_1.Args[0]
@@ -9428,7 +9428,7 @@ func rewriteValueS390X_OpS390XMOVHBRstore(v *Value) bool {
if v_1.Op != OpS390XSRWconst {
break
}
- j := auxIntToInt8(v_1.AuxInt)
+ j := auxIntToUint8(v_1.AuxInt)
w := v_1.Args[0]
x := v_2
if x.Op != OpS390XMOVHBRstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
@@ -9439,7 +9439,7 @@ func rewriteValueS390X_OpS390XMOVHBRstore(v *Value) bool {
break
}
w0 := x.Args[1]
- if w0.Op != OpS390XSRWconst || auxIntToInt8(w0.AuxInt) != j-16 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) {
+ if w0.Op != OpS390XSRWconst || auxIntToUint8(w0.AuxInt) != j-16 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpS390XMOVWBRstore)
@@ -10086,7 +10086,7 @@ func rewriteValueS390X_OpS390XMOVHstore(v *Value) bool {
break
}
x_1 := x.Args[1]
- if x_1.Op != OpS390XSRDconst || auxIntToInt8(x_1.AuxInt) != 16 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
+ if x_1.Op != OpS390XSRDconst || auxIntToUint8(x_1.AuxInt) != 16 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpS390XMOVWstore)
@@ -10106,7 +10106,7 @@ func rewriteValueS390X_OpS390XMOVHstore(v *Value) bool {
if w0.Op != OpS390XSRDconst {
break
}
- j := auxIntToInt8(w0.AuxInt)
+ j := auxIntToUint8(w0.AuxInt)
w := w0.Args[0]
x := v_2
if x.Op != OpS390XMOVHstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
@@ -10117,7 +10117,7 @@ func rewriteValueS390X_OpS390XMOVHstore(v *Value) bool {
break
}
x_1 := x.Args[1]
- if x_1.Op != OpS390XSRDconst || auxIntToInt8(x_1.AuxInt) != j+16 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
+ if x_1.Op != OpS390XSRDconst || auxIntToUint8(x_1.AuxInt) != j+16 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpS390XMOVWstore)
@@ -10143,7 +10143,7 @@ func rewriteValueS390X_OpS390XMOVHstore(v *Value) bool {
break
}
x_1 := x.Args[1]
- if x_1.Op != OpS390XSRWconst || auxIntToInt8(x_1.AuxInt) != 16 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
+ if x_1.Op != OpS390XSRWconst || auxIntToUint8(x_1.AuxInt) != 16 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpS390XMOVWstore)
@@ -10163,7 +10163,7 @@ func rewriteValueS390X_OpS390XMOVHstore(v *Value) bool {
if w0.Op != OpS390XSRWconst {
break
}
- j := auxIntToInt8(w0.AuxInt)
+ j := auxIntToUint8(w0.AuxInt)
w := w0.Args[0]
x := v_2
if x.Op != OpS390XMOVHstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
@@ -10174,7 +10174,7 @@ func rewriteValueS390X_OpS390XMOVHstore(v *Value) bool {
break
}
x_1 := x.Args[1]
- if x_1.Op != OpS390XSRWconst || auxIntToInt8(x_1.AuxInt) != j+16 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
+ if x_1.Op != OpS390XSRWconst || auxIntToUint8(x_1.AuxInt) != j+16 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpS390XMOVWstore)
@@ -10273,7 +10273,7 @@ func rewriteValueS390X_OpS390XMOVWBRstore(v *Value) bool {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
p := v_0
- if v_1.Op != OpS390XSRDconst || auxIntToInt8(v_1.AuxInt) != 32 {
+ if v_1.Op != OpS390XSRDconst || auxIntToUint8(v_1.AuxInt) != 32 {
break
}
w := v_1.Args[0]
@@ -10301,7 +10301,7 @@ func rewriteValueS390X_OpS390XMOVWBRstore(v *Value) bool {
if v_1.Op != OpS390XSRDconst {
break
}
- j := auxIntToInt8(v_1.AuxInt)
+ j := auxIntToUint8(v_1.AuxInt)
w := v_1.Args[0]
x := v_2
if x.Op != OpS390XMOVWBRstore || auxIntToInt32(x.AuxInt) != i-4 || auxToSym(x.Aux) != s {
@@ -10312,7 +10312,7 @@ func rewriteValueS390X_OpS390XMOVWBRstore(v *Value) bool {
break
}
w0 := x.Args[1]
- if w0.Op != OpS390XSRDconst || auxIntToInt8(w0.AuxInt) != j-32 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) {
+ if w0.Op != OpS390XSRDconst || auxIntToUint8(w0.AuxInt) != j-32 || w != w0.Args[0] || !(x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpS390XMOVDBRstore)
@@ -10914,7 +10914,7 @@ func rewriteValueS390X_OpS390XMOVWstore(v *Value) bool {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
p := v_0
- if v_1.Op != OpS390XSRDconst || auxIntToInt8(v_1.AuxInt) != 32 {
+ if v_1.Op != OpS390XSRDconst || auxIntToUint8(v_1.AuxInt) != 32 {
break
}
w := v_1.Args[0]
@@ -10943,7 +10943,7 @@ func rewriteValueS390X_OpS390XMOVWstore(v *Value) bool {
if w0.Op != OpS390XSRDconst {
break
}
- j := auxIntToInt8(w0.AuxInt)
+ j := auxIntToUint8(w0.AuxInt)
w := w0.Args[0]
x := v_2
if x.Op != OpS390XMOVWstore || auxIntToInt32(x.AuxInt) != i-4 || auxToSym(x.Aux) != s {
@@ -10954,7 +10954,7 @@ func rewriteValueS390X_OpS390XMOVWstore(v *Value) bool {
break
}
x_1 := x.Args[1]
- if x_1.Op != OpS390XSRDconst || auxIntToInt8(x_1.AuxInt) != j+32 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
+ if x_1.Op != OpS390XSRDconst || auxIntToUint8(x_1.AuxInt) != j+32 || w != x_1.Args[0] || !(p.Op != OpSB && x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpS390XMOVDstore)
@@ -11180,7 +11180,7 @@ func rewriteValueS390X_OpS390XMULLDconst(v *Value) bool {
b := v.Block
// match: (MULLDconst x [c])
// cond: isPowerOfTwo32(c&(c-1))
- // result: (ADD (SLDconst x [int8(log32(c&(c-1)))]) (SLDconst x [int8(log32(c&^(c-1)))]))
+ // result: (ADD (SLDconst x [uint8(log32(c&(c-1)))]) (SLDconst x [uint8(log32(c&^(c-1)))]))
for {
t := v.Type
c := auxIntToInt32(v.AuxInt)
@@ -11190,17 +11190,17 @@ func rewriteValueS390X_OpS390XMULLDconst(v *Value) bool {
}
v.reset(OpS390XADD)
v0 := b.NewValue0(v.Pos, OpS390XSLDconst, t)
- v0.AuxInt = int8ToAuxInt(int8(log32(c & (c - 1))))
+ v0.AuxInt = uint8ToAuxInt(uint8(log32(c & (c - 1))))
v0.AddArg(x)
v1 := b.NewValue0(v.Pos, OpS390XSLDconst, t)
- v1.AuxInt = int8ToAuxInt(int8(log32(c &^ (c - 1))))
+ v1.AuxInt = uint8ToAuxInt(uint8(log32(c &^ (c - 1))))
v1.AddArg(x)
v.AddArg2(v0, v1)
return true
}
// match: (MULLDconst x [c])
// cond: isPowerOfTwo32(c+(c&^(c-1)))
- // result: (SUB (SLDconst x [int8(log32(c+(c&^(c-1))))]) (SLDconst x [int8(log32(c&^(c-1)))]))
+ // result: (SUB (SLDconst x [uint8(log32(c+(c&^(c-1))))]) (SLDconst x [uint8(log32(c&^(c-1)))]))
for {
t := v.Type
c := auxIntToInt32(v.AuxInt)
@@ -11210,17 +11210,17 @@ func rewriteValueS390X_OpS390XMULLDconst(v *Value) bool {
}
v.reset(OpS390XSUB)
v0 := b.NewValue0(v.Pos, OpS390XSLDconst, t)
- v0.AuxInt = int8ToAuxInt(int8(log32(c + (c &^ (c - 1)))))
+ v0.AuxInt = uint8ToAuxInt(uint8(log32(c + (c &^ (c - 1)))))
v0.AddArg(x)
v1 := b.NewValue0(v.Pos, OpS390XSLDconst, t)
- v1.AuxInt = int8ToAuxInt(int8(log32(c &^ (c - 1))))
+ v1.AuxInt = uint8ToAuxInt(uint8(log32(c &^ (c - 1))))
v1.AddArg(x)
v.AddArg2(v0, v1)
return true
}
// match: (MULLDconst x [c])
// cond: isPowerOfTwo32(-c+(-c&^(-c-1)))
- // result: (SUB (SLDconst x [int8(log32(-c&^(-c-1)))]) (SLDconst x [int8(log32(-c+(-c&^(-c-1))))]))
+ // result: (SUB (SLDconst x [uint8(log32(-c&^(-c-1)))]) (SLDconst x [uint8(log32(-c+(-c&^(-c-1))))]))
for {
t := v.Type
c := auxIntToInt32(v.AuxInt)
@@ -11230,10 +11230,10 @@ func rewriteValueS390X_OpS390XMULLDconst(v *Value) bool {
}
v.reset(OpS390XSUB)
v0 := b.NewValue0(v.Pos, OpS390XSLDconst, t)
- v0.AuxInt = int8ToAuxInt(int8(log32(-c &^ (-c - 1))))
+ v0.AuxInt = uint8ToAuxInt(uint8(log32(-c &^ (-c - 1))))
v0.AddArg(x)
v1 := b.NewValue0(v.Pos, OpS390XSLDconst, t)
- v1.AuxInt = int8ToAuxInt(int8(log32(-c + (-c &^ (-c - 1)))))
+ v1.AuxInt = uint8ToAuxInt(uint8(log32(-c + (-c &^ (-c - 1)))))
v1.AddArg(x)
v.AddArg2(v0, v1)
return true
@@ -11407,7 +11407,7 @@ func rewriteValueS390X_OpS390XMULLWconst(v *Value) bool {
b := v.Block
// match: (MULLWconst x [c])
// cond: isPowerOfTwo32(c&(c-1))
- // result: (ADDW (SLWconst x [int8(log32(c&(c-1)))]) (SLWconst x [int8(log32(c&^(c-1)))]))
+ // result: (ADDW (SLWconst x [uint8(log32(c&(c-1)))]) (SLWconst x [uint8(log32(c&^(c-1)))]))
for {
t := v.Type
c := auxIntToInt32(v.AuxInt)
@@ -11417,17 +11417,17 @@ func rewriteValueS390X_OpS390XMULLWconst(v *Value) bool {
}
v.reset(OpS390XADDW)
v0 := b.NewValue0(v.Pos, OpS390XSLWconst, t)
- v0.AuxInt = int8ToAuxInt(int8(log32(c & (c - 1))))
+ v0.AuxInt = uint8ToAuxInt(uint8(log32(c & (c - 1))))
v0.AddArg(x)
v1 := b.NewValue0(v.Pos, OpS390XSLWconst, t)
- v1.AuxInt = int8ToAuxInt(int8(log32(c &^ (c - 1))))
+ v1.AuxInt = uint8ToAuxInt(uint8(log32(c &^ (c - 1))))
v1.AddArg(x)
v.AddArg2(v0, v1)
return true
}
// match: (MULLWconst x [c])
// cond: isPowerOfTwo32(c+(c&^(c-1)))
- // result: (SUBW (SLWconst x [int8(log32(c+(c&^(c-1))))]) (SLWconst x [int8(log32(c&^(c-1)))]))
+ // result: (SUBW (SLWconst x [uint8(log32(c+(c&^(c-1))))]) (SLWconst x [uint8(log32(c&^(c-1)))]))
for {
t := v.Type
c := auxIntToInt32(v.AuxInt)
@@ -11437,17 +11437,17 @@ func rewriteValueS390X_OpS390XMULLWconst(v *Value) bool {
}
v.reset(OpS390XSUBW)
v0 := b.NewValue0(v.Pos, OpS390XSLWconst, t)
- v0.AuxInt = int8ToAuxInt(int8(log32(c + (c &^ (c - 1)))))
+ v0.AuxInt = uint8ToAuxInt(uint8(log32(c + (c &^ (c - 1)))))
v0.AddArg(x)
v1 := b.NewValue0(v.Pos, OpS390XSLWconst, t)
- v1.AuxInt = int8ToAuxInt(int8(log32(c &^ (c - 1))))
+ v1.AuxInt = uint8ToAuxInt(uint8(log32(c &^ (c - 1))))
v1.AddArg(x)
v.AddArg2(v0, v1)
return true
}
// match: (MULLWconst x [c])
// cond: isPowerOfTwo32(-c+(-c&^(-c-1)))
- // result: (SUBW (SLWconst x [int8(log32(-c&^(-c-1)))]) (SLWconst x [int8(log32(-c+(-c&^(-c-1))))]))
+ // result: (SUBW (SLWconst x [uint8(log32(-c&^(-c-1)))]) (SLWconst x [uint8(log32(-c+(-c&^(-c-1))))]))
for {
t := v.Type
c := auxIntToInt32(v.AuxInt)
@@ -11457,10 +11457,10 @@ func rewriteValueS390X_OpS390XMULLWconst(v *Value) bool {
}
v.reset(OpS390XSUBW)
v0 := b.NewValue0(v.Pos, OpS390XSLWconst, t)
- v0.AuxInt = int8ToAuxInt(int8(log32(-c &^ (-c - 1))))
+ v0.AuxInt = uint8ToAuxInt(uint8(log32(-c &^ (-c - 1))))
v0.AddArg(x)
v1 := b.NewValue0(v.Pos, OpS390XSLWconst, t)
- v1.AuxInt = int8ToAuxInt(int8(log32(-c + (-c &^ (-c - 1)))))
+ v1.AuxInt = uint8ToAuxInt(uint8(log32(-c + (-c &^ (-c - 1)))))
v1.AddArg(x)
v.AddArg2(v0, v1)
return true
@@ -11640,9 +11640,9 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
if v_0.Op != OpS390XSLDconst {
continue
}
- c := auxIntToInt8(v_0.AuxInt)
+ c := auxIntToUint8(v_0.AuxInt)
x := v_0.Args[0]
- if v_1.Op != OpS390XSRDconst || auxIntToInt8(v_1.AuxInt) != 64-c || x != v_1.Args[0] {
+ if v_1.Op != OpS390XSRDconst || auxIntToUint8(v_1.AuxInt) != 64-c || x != v_1.Args[0] {
continue
}
v.reset(OpS390XRISBGZ)
@@ -11804,7 +11804,7 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
mem := x1.Args[1]
p := x1.Args[0]
sh := v_1
- if sh.Op != OpS390XSLDconst || auxIntToInt8(sh.AuxInt) != 8 {
+ if sh.Op != OpS390XSLDconst || auxIntToUint8(sh.AuxInt) != 8 {
continue
}
x0 := sh.Args[0]
@@ -11843,7 +11843,7 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
mem := x1.Args[1]
p := x1.Args[0]
sh := v_1
- if sh.Op != OpS390XSLDconst || auxIntToInt8(sh.AuxInt) != 16 {
+ if sh.Op != OpS390XSLDconst || auxIntToUint8(sh.AuxInt) != 16 {
continue
}
x0 := sh.Args[0]
@@ -11882,7 +11882,7 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
mem := x1.Args[1]
p := x1.Args[0]
sh := v_1
- if sh.Op != OpS390XSLDconst || auxIntToInt8(sh.AuxInt) != 32 {
+ if sh.Op != OpS390XSLDconst || auxIntToUint8(sh.AuxInt) != 32 {
continue
}
x0 := sh.Args[0]
@@ -11916,7 +11916,7 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
if s0.Op != OpS390XSLDconst {
continue
}
- j0 := auxIntToInt8(s0.AuxInt)
+ j0 := auxIntToUint8(s0.AuxInt)
x0 := s0.Args[0]
if x0.Op != OpS390XMOVBZload {
continue
@@ -11937,7 +11937,7 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
if s1.Op != OpS390XSLDconst {
continue
}
- j1 := auxIntToInt8(s1.AuxInt)
+ j1 := auxIntToUint8(s1.AuxInt)
x1 := s1.Args[0]
if x1.Op != OpS390XMOVBZload {
continue
@@ -11958,7 +11958,7 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
v0 := b.NewValue0(x1.Pos, OpS390XOR, v.Type)
v.copyOf(v0)
v1 := b.NewValue0(x1.Pos, OpS390XSLDconst, v.Type)
- v1.AuxInt = int8ToAuxInt(j1)
+ v1.AuxInt = uint8ToAuxInt(j1)
v2 := b.NewValue0(x1.Pos, OpS390XMOVHZload, typ.UInt16)
v2.AuxInt = int32ToAuxInt(i0)
v2.Aux = symToAux(s)
@@ -11979,7 +11979,7 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
if s0.Op != OpS390XSLDconst {
continue
}
- j0 := auxIntToInt8(s0.AuxInt)
+ j0 := auxIntToUint8(s0.AuxInt)
x0 := s0.Args[0]
if x0.Op != OpS390XMOVHZload {
continue
@@ -12000,7 +12000,7 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
if s1.Op != OpS390XSLDconst {
continue
}
- j1 := auxIntToInt8(s1.AuxInt)
+ j1 := auxIntToUint8(s1.AuxInt)
x1 := s1.Args[0]
if x1.Op != OpS390XMOVHZload {
continue
@@ -12021,7 +12021,7 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
v0 := b.NewValue0(x1.Pos, OpS390XOR, v.Type)
v.copyOf(v0)
v1 := b.NewValue0(x1.Pos, OpS390XSLDconst, v.Type)
- v1.AuxInt = int8ToAuxInt(j1)
+ v1.AuxInt = uint8ToAuxInt(j1)
v2 := b.NewValue0(x1.Pos, OpS390XMOVWZload, typ.UInt32)
v2.AuxInt = int32ToAuxInt(i0)
v2.Aux = symToAux(s)
@@ -12047,7 +12047,7 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
mem := x0.Args[1]
p := x0.Args[0]
sh := v_1
- if sh.Op != OpS390XSLDconst || auxIntToInt8(sh.AuxInt) != 8 {
+ if sh.Op != OpS390XSLDconst || auxIntToUint8(sh.AuxInt) != 8 {
continue
}
x1 := sh.Args[0]
@@ -12092,7 +12092,7 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
mem := x0.Args[1]
p := x0.Args[0]
sh := v_1
- if sh.Op != OpS390XSLDconst || auxIntToInt8(sh.AuxInt) != 16 {
+ if sh.Op != OpS390XSLDconst || auxIntToUint8(sh.AuxInt) != 16 {
continue
}
r1 := sh.Args[0]
@@ -12141,7 +12141,7 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
mem := x0.Args[1]
p := x0.Args[0]
sh := v_1
- if sh.Op != OpS390XSLDconst || auxIntToInt8(sh.AuxInt) != 32 {
+ if sh.Op != OpS390XSLDconst || auxIntToUint8(sh.AuxInt) != 32 {
continue
}
r1 := sh.Args[0]
@@ -12179,7 +12179,7 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
if s1.Op != OpS390XSLDconst {
continue
}
- j1 := auxIntToInt8(s1.AuxInt)
+ j1 := auxIntToUint8(s1.AuxInt)
x1 := s1.Args[0]
if x1.Op != OpS390XMOVBZload {
continue
@@ -12200,7 +12200,7 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
if s0.Op != OpS390XSLDconst {
continue
}
- j0 := auxIntToInt8(s0.AuxInt)
+ j0 := auxIntToUint8(s0.AuxInt)
x0 := s0.Args[0]
if x0.Op != OpS390XMOVBZload {
continue
@@ -12221,7 +12221,7 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
v0 := b.NewValue0(x0.Pos, OpS390XOR, v.Type)
v.copyOf(v0)
v1 := b.NewValue0(x0.Pos, OpS390XSLDconst, v.Type)
- v1.AuxInt = int8ToAuxInt(j0)
+ v1.AuxInt = uint8ToAuxInt(j0)
v2 := b.NewValue0(x0.Pos, OpS390XMOVHZreg, typ.UInt64)
v3 := b.NewValue0(x0.Pos, OpS390XMOVHBRload, typ.UInt16)
v3.AuxInt = int32ToAuxInt(i0)
@@ -12244,7 +12244,7 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
if s1.Op != OpS390XSLDconst {
continue
}
- j1 := auxIntToInt8(s1.AuxInt)
+ j1 := auxIntToUint8(s1.AuxInt)
r1 := s1.Args[0]
if r1.Op != OpS390XMOVHZreg {
continue
@@ -12269,7 +12269,7 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
if s0.Op != OpS390XSLDconst {
continue
}
- j0 := auxIntToInt8(s0.AuxInt)
+ j0 := auxIntToUint8(s0.AuxInt)
r0 := s0.Args[0]
if r0.Op != OpS390XMOVHZreg {
continue
@@ -12294,7 +12294,7 @@ func rewriteValueS390X_OpS390XOR(v *Value) bool {
v0 := b.NewValue0(x0.Pos, OpS390XOR, v.Type)
v.copyOf(v0)
v1 := b.NewValue0(x0.Pos, OpS390XSLDconst, v.Type)
- v1.AuxInt = int8ToAuxInt(j0)
+ v1.AuxInt = uint8ToAuxInt(j0)
v2 := b.NewValue0(x0.Pos, OpS390XMOVWZreg, typ.UInt64)
v3 := b.NewValue0(x0.Pos, OpS390XMOVWBRload, typ.UInt32)
v3.AuxInt = int32ToAuxInt(i0)
@@ -12338,13 +12338,13 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
if v_0.Op != OpS390XSLWconst {
continue
}
- c := auxIntToInt8(v_0.AuxInt)
+ c := auxIntToUint8(v_0.AuxInt)
x := v_0.Args[0]
- if v_1.Op != OpS390XSRWconst || auxIntToInt8(v_1.AuxInt) != 32-c || x != v_1.Args[0] {
+ if v_1.Op != OpS390XSRWconst || auxIntToUint8(v_1.AuxInt) != 32-c || x != v_1.Args[0] {
continue
}
v.reset(OpS390XRLLconst)
- v.AuxInt = int8ToAuxInt(c)
+ v.AuxInt = uint8ToAuxInt(c)
v.AddArg(x)
return true
}
@@ -12428,7 +12428,7 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
mem := x1.Args[1]
p := x1.Args[0]
sh := v_1
- if sh.Op != OpS390XSLWconst || auxIntToInt8(sh.AuxInt) != 8 {
+ if sh.Op != OpS390XSLWconst || auxIntToUint8(sh.AuxInt) != 8 {
continue
}
x0 := sh.Args[0]
@@ -12467,7 +12467,7 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
mem := x1.Args[1]
p := x1.Args[0]
sh := v_1
- if sh.Op != OpS390XSLWconst || auxIntToInt8(sh.AuxInt) != 16 {
+ if sh.Op != OpS390XSLWconst || auxIntToUint8(sh.AuxInt) != 16 {
continue
}
x0 := sh.Args[0]
@@ -12501,7 +12501,7 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
if s0.Op != OpS390XSLWconst {
continue
}
- j0 := auxIntToInt8(s0.AuxInt)
+ j0 := auxIntToUint8(s0.AuxInt)
x0 := s0.Args[0]
if x0.Op != OpS390XMOVBZload {
continue
@@ -12522,7 +12522,7 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
if s1.Op != OpS390XSLWconst {
continue
}
- j1 := auxIntToInt8(s1.AuxInt)
+ j1 := auxIntToUint8(s1.AuxInt)
x1 := s1.Args[0]
if x1.Op != OpS390XMOVBZload {
continue
@@ -12543,7 +12543,7 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
v0 := b.NewValue0(x1.Pos, OpS390XORW, v.Type)
v.copyOf(v0)
v1 := b.NewValue0(x1.Pos, OpS390XSLWconst, v.Type)
- v1.AuxInt = int8ToAuxInt(j1)
+ v1.AuxInt = uint8ToAuxInt(j1)
v2 := b.NewValue0(x1.Pos, OpS390XMOVHZload, typ.UInt16)
v2.AuxInt = int32ToAuxInt(i0)
v2.Aux = symToAux(s)
@@ -12569,7 +12569,7 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
mem := x0.Args[1]
p := x0.Args[0]
sh := v_1
- if sh.Op != OpS390XSLWconst || auxIntToInt8(sh.AuxInt) != 8 {
+ if sh.Op != OpS390XSLWconst || auxIntToUint8(sh.AuxInt) != 8 {
continue
}
x1 := sh.Args[0]
@@ -12614,7 +12614,7 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
mem := x0.Args[1]
p := x0.Args[0]
sh := v_1
- if sh.Op != OpS390XSLWconst || auxIntToInt8(sh.AuxInt) != 16 {
+ if sh.Op != OpS390XSLWconst || auxIntToUint8(sh.AuxInt) != 16 {
continue
}
r1 := sh.Args[0]
@@ -12652,7 +12652,7 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
if s1.Op != OpS390XSLWconst {
continue
}
- j1 := auxIntToInt8(s1.AuxInt)
+ j1 := auxIntToUint8(s1.AuxInt)
x1 := s1.Args[0]
if x1.Op != OpS390XMOVBZload {
continue
@@ -12673,7 +12673,7 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
if s0.Op != OpS390XSLWconst {
continue
}
- j0 := auxIntToInt8(s0.AuxInt)
+ j0 := auxIntToUint8(s0.AuxInt)
x0 := s0.Args[0]
if x0.Op != OpS390XMOVBZload {
continue
@@ -12694,7 +12694,7 @@ func rewriteValueS390X_OpS390XORW(v *Value) bool {
v0 := b.NewValue0(x0.Pos, OpS390XORW, v.Type)
v.copyOf(v0)
v1 := b.NewValue0(x0.Pos, OpS390XSLWconst, v.Type)
- v1.AuxInt = int8ToAuxInt(j0)
+ v1.AuxInt = uint8ToAuxInt(j0)
v2 := b.NewValue0(x0.Pos, OpS390XMOVHZreg, typ.UInt64)
v3 := b.NewValue0(x0.Pos, OpS390XMOVHBRload, typ.UInt16)
v3.AuxInt = int32ToAuxInt(i0)
@@ -12974,7 +12974,7 @@ func rewriteValueS390X_OpS390XRISBGZ(v *Value) bool {
if v_0.Op != OpS390XSLDconst {
break
}
- c := auxIntToInt8(v_0.AuxInt)
+ c := auxIntToUint8(v_0.AuxInt)
x := v_0.Args[0]
if !(r.InMerge(^uint64(0)<>c) != nil) {
break
@@ -13030,7 +13030,7 @@ func rewriteValueS390X_OpS390XRISBGZ(v *Value) bool {
break
}
v.reset(OpS390XSRDconst)
- v.AuxInt = int8ToAuxInt(-r.Amount & 63)
+ v.AuxInt = uint8ToAuxInt(-r.Amount & 63)
v.AddArg(x)
return true
}
@@ -13044,7 +13044,7 @@ func rewriteValueS390X_OpS390XRISBGZ(v *Value) bool {
break
}
v.reset(OpS390XSLDconst)
- v.AuxInt = int8ToAuxInt(r.Amount)
+ v.AuxInt = uint8ToAuxInt(r.Amount)
v.AddArg(x)
return true
}
@@ -13056,7 +13056,7 @@ func rewriteValueS390X_OpS390XRISBGZ(v *Value) bool {
if v_0.Op != OpS390XSRADconst {
break
}
- c := auxIntToInt8(v_0.AuxInt)
+ c := auxIntToUint8(v_0.AuxInt)
x := v_0.Args[0]
if !(r.Start == r.End && (r.Start+r.Amount)&63 <= c) {
break
@@ -13131,7 +13131,7 @@ func rewriteValueS390X_OpS390XRLL(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (RLL x (MOVDconst [c]))
- // result: (RLLconst x [int8(c&31)])
+ // result: (RLLconst x [uint8(c&31)])
for {
x := v_0
if v_1.Op != OpS390XMOVDconst {
@@ -13139,7 +13139,7 @@ func rewriteValueS390X_OpS390XRLL(v *Value) bool {
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpS390XRLLconst)
- v.AuxInt = int8ToAuxInt(int8(c & 31))
+ v.AuxInt = uint8ToAuxInt(uint8(c & 31))
v.AddArg(x)
return true
}
@@ -13149,7 +13149,7 @@ func rewriteValueS390X_OpS390XRLLG(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (RLLG x (MOVDconst [c]))
- // result: (RISBGZ x {s390x.NewRotateParams(0, 63, int8(c&63))})
+ // result: (RISBGZ x {s390x.NewRotateParams(0, 63, uint8(c&63))})
for {
x := v_0
if v_1.Op != OpS390XMOVDconst {
@@ -13157,7 +13157,7 @@ func rewriteValueS390X_OpS390XRLLG(v *Value) bool {
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpS390XRISBGZ)
- v.Aux = s390xRotateParamsToAux(s390x.NewRotateParams(0, 63, int8(c&63)))
+ v.Aux = s390xRotateParamsToAux(s390x.NewRotateParams(0, 63, uint8(c&63)))
v.AddArg(x)
return true
}
@@ -13169,7 +13169,7 @@ func rewriteValueS390X_OpS390XSLD(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (SLD x (MOVDconst [c]))
- // result: (SLDconst x [int8(c&63)])
+ // result: (SLDconst x [uint8(c&63)])
for {
x := v_0
if v_1.Op != OpS390XMOVDconst {
@@ -13177,7 +13177,7 @@ func rewriteValueS390X_OpS390XSLD(v *Value) bool {
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpS390XSLDconst)
- v.AuxInt = int8ToAuxInt(int8(c & 63))
+ v.AuxInt = uint8ToAuxInt(uint8(c & 63))
v.AddArg(x)
return true
}
@@ -13317,16 +13317,16 @@ func rewriteValueS390X_OpS390XSLD(v *Value) bool {
func rewriteValueS390X_OpS390XSLDconst(v *Value) bool {
v_0 := v.Args[0]
// match: (SLDconst (SRDconst x [c]) [d])
- // result: (RISBGZ x {s390x.NewRotateParams(max8(0, c-d), 63-d, (d-c)&63)})
+ // result: (RISBGZ x {s390x.NewRotateParams(uint8(max8(0, int8(c-d))), 63-d, uint8(int8(d-c)&63))})
for {
- d := auxIntToInt8(v.AuxInt)
+ d := auxIntToUint8(v.AuxInt)
if v_0.Op != OpS390XSRDconst {
break
}
- c := auxIntToInt8(v_0.AuxInt)
+ c := auxIntToUint8(v_0.AuxInt)
x := v_0.Args[0]
v.reset(OpS390XRISBGZ)
- v.Aux = s390xRotateParamsToAux(s390x.NewRotateParams(max8(0, c-d), 63-d, (d-c)&63))
+ v.Aux = s390xRotateParamsToAux(s390x.NewRotateParams(uint8(max8(0, int8(c-d))), 63-d, uint8(int8(d-c)&63)))
v.AddArg(x)
return true
}
@@ -13334,7 +13334,7 @@ func rewriteValueS390X_OpS390XSLDconst(v *Value) bool {
// cond: s390x.NewRotateParams(0, 63-c, c).InMerge(r.OutMask()) != nil
// result: (RISBGZ x {(*s390x.NewRotateParams(0, 63-c, c).InMerge(r.OutMask())).RotateLeft(r.Amount)})
for {
- c := auxIntToInt8(v.AuxInt)
+ c := auxIntToUint8(v.AuxInt)
if v_0.Op != OpS390XRISBGZ {
break
}
@@ -13351,7 +13351,7 @@ func rewriteValueS390X_OpS390XSLDconst(v *Value) bool {
// match: (SLDconst x [0])
// result: x
for {
- if auxIntToInt8(v.AuxInt) != 0 {
+ if auxIntToUint8(v.AuxInt) != 0 {
break
}
x := v_0
@@ -13367,7 +13367,7 @@ func rewriteValueS390X_OpS390XSLW(v *Value) bool {
typ := &b.Func.Config.Types
// match: (SLW x (MOVDconst [c]))
// cond: c&32 == 0
- // result: (SLWconst x [int8(c&31)])
+ // result: (SLWconst x [uint8(c&31)])
for {
x := v_0
if v_1.Op != OpS390XMOVDconst {
@@ -13378,7 +13378,7 @@ func rewriteValueS390X_OpS390XSLW(v *Value) bool {
break
}
v.reset(OpS390XSLWconst)
- v.AuxInt = int8ToAuxInt(int8(c & 31))
+ v.AuxInt = uint8ToAuxInt(uint8(c & 31))
v.AddArg(x)
return true
}
@@ -13535,7 +13535,7 @@ func rewriteValueS390X_OpS390XSLWconst(v *Value) bool {
// match: (SLWconst x [0])
// result: x
for {
- if auxIntToInt8(v.AuxInt) != 0 {
+ if auxIntToUint8(v.AuxInt) != 0 {
break
}
x := v_0
@@ -13550,7 +13550,7 @@ func rewriteValueS390X_OpS390XSRAD(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (SRAD x (MOVDconst [c]))
- // result: (SRADconst x [int8(c&63)])
+ // result: (SRADconst x [uint8(c&63)])
for {
x := v_0
if v_1.Op != OpS390XMOVDconst {
@@ -13558,7 +13558,7 @@ func rewriteValueS390X_OpS390XSRAD(v *Value) bool {
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpS390XSRADconst)
- v.AuxInt = int8ToAuxInt(int8(c & 63))
+ v.AuxInt = uint8ToAuxInt(uint8(c & 63))
v.AddArg(x)
return true
}
@@ -13700,7 +13700,7 @@ func rewriteValueS390X_OpS390XSRADconst(v *Value) bool {
// match: (SRADconst x [0])
// result: x
for {
- if auxIntToInt8(v.AuxInt) != 0 {
+ if auxIntToUint8(v.AuxInt) != 0 {
break
}
x := v_0
@@ -13710,7 +13710,7 @@ func rewriteValueS390X_OpS390XSRADconst(v *Value) bool {
// match: (SRADconst [c] (MOVDconst [d]))
// result: (MOVDconst [d>>uint64(c)])
for {
- c := auxIntToInt8(v.AuxInt)
+ c := auxIntToUint8(v.AuxInt)
if v_0.Op != OpS390XMOVDconst {
break
}
@@ -13728,7 +13728,7 @@ func rewriteValueS390X_OpS390XSRAW(v *Value) bool {
typ := &b.Func.Config.Types
// match: (SRAW x (MOVDconst [c]))
// cond: c&32 == 0
- // result: (SRAWconst x [int8(c&31)])
+ // result: (SRAWconst x [uint8(c&31)])
for {
x := v_0
if v_1.Op != OpS390XMOVDconst {
@@ -13739,7 +13739,7 @@ func rewriteValueS390X_OpS390XSRAW(v *Value) bool {
break
}
v.reset(OpS390XSRAWconst)
- v.AuxInt = int8ToAuxInt(int8(c & 31))
+ v.AuxInt = uint8ToAuxInt(uint8(c & 31))
v.AddArg(x)
return true
}
@@ -13756,7 +13756,7 @@ func rewriteValueS390X_OpS390XSRAW(v *Value) bool {
break
}
v.reset(OpS390XSRAWconst)
- v.AuxInt = int8ToAuxInt(31)
+ v.AuxInt = uint8ToAuxInt(31)
v.AddArg(x)
return true
}
@@ -13898,7 +13898,7 @@ func rewriteValueS390X_OpS390XSRAWconst(v *Value) bool {
// match: (SRAWconst x [0])
// result: x
for {
- if auxIntToInt8(v.AuxInt) != 0 {
+ if auxIntToUint8(v.AuxInt) != 0 {
break
}
x := v_0
@@ -13908,7 +13908,7 @@ func rewriteValueS390X_OpS390XSRAWconst(v *Value) bool {
// match: (SRAWconst [c] (MOVDconst [d]))
// result: (MOVDconst [int64(int32(d))>>uint64(c)])
for {
- c := auxIntToInt8(v.AuxInt)
+ c := auxIntToUint8(v.AuxInt)
if v_0.Op != OpS390XMOVDconst {
break
}
@@ -13925,7 +13925,7 @@ func rewriteValueS390X_OpS390XSRD(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
// match: (SRD x (MOVDconst [c]))
- // result: (SRDconst x [int8(c&63)])
+ // result: (SRDconst x [uint8(c&63)])
for {
x := v_0
if v_1.Op != OpS390XMOVDconst {
@@ -13933,7 +13933,7 @@ func rewriteValueS390X_OpS390XSRD(v *Value) bool {
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpS390XSRDconst)
- v.AuxInt = int8ToAuxInt(int8(c & 63))
+ v.AuxInt = uint8ToAuxInt(uint8(c & 63))
v.AddArg(x)
return true
}
@@ -14073,16 +14073,16 @@ func rewriteValueS390X_OpS390XSRD(v *Value) bool {
func rewriteValueS390X_OpS390XSRDconst(v *Value) bool {
v_0 := v.Args[0]
// match: (SRDconst (SLDconst x [c]) [d])
- // result: (RISBGZ x {s390x.NewRotateParams(d, min8(63, 63-c+d), (c-d)&63)})
+ // result: (RISBGZ x {s390x.NewRotateParams(d, uint8(min8(63, int8(63-c+d))), uint8(int8(c-d)&63))})
for {
- d := auxIntToInt8(v.AuxInt)
+ d := auxIntToUint8(v.AuxInt)
if v_0.Op != OpS390XSLDconst {
break
}
- c := auxIntToInt8(v_0.AuxInt)
+ c := auxIntToUint8(v_0.AuxInt)
x := v_0.Args[0]
v.reset(OpS390XRISBGZ)
- v.Aux = s390xRotateParamsToAux(s390x.NewRotateParams(d, min8(63, 63-c+d), (c-d)&63))
+ v.Aux = s390xRotateParamsToAux(s390x.NewRotateParams(d, uint8(min8(63, int8(63-c+d))), uint8(int8(c-d)&63)))
v.AddArg(x)
return true
}
@@ -14090,7 +14090,7 @@ func rewriteValueS390X_OpS390XSRDconst(v *Value) bool {
// cond: s390x.NewRotateParams(c, 63, -c&63).InMerge(r.OutMask()) != nil
// result: (RISBGZ x {(*s390x.NewRotateParams(c, 63, -c&63).InMerge(r.OutMask())).RotateLeft(r.Amount)})
for {
- c := auxIntToInt8(v.AuxInt)
+ c := auxIntToUint8(v.AuxInt)
if v_0.Op != OpS390XRISBGZ {
break
}
@@ -14107,7 +14107,7 @@ func rewriteValueS390X_OpS390XSRDconst(v *Value) bool {
// match: (SRDconst x [0])
// result: x
for {
- if auxIntToInt8(v.AuxInt) != 0 {
+ if auxIntToUint8(v.AuxInt) != 0 {
break
}
x := v_0
@@ -14123,7 +14123,7 @@ func rewriteValueS390X_OpS390XSRW(v *Value) bool {
typ := &b.Func.Config.Types
// match: (SRW x (MOVDconst [c]))
// cond: c&32 == 0
- // result: (SRWconst x [int8(c&31)])
+ // result: (SRWconst x [uint8(c&31)])
for {
x := v_0
if v_1.Op != OpS390XMOVDconst {
@@ -14134,7 +14134,7 @@ func rewriteValueS390X_OpS390XSRW(v *Value) bool {
break
}
v.reset(OpS390XSRWconst)
- v.AuxInt = int8ToAuxInt(int8(c & 31))
+ v.AuxInt = uint8ToAuxInt(uint8(c & 31))
v.AddArg(x)
return true
}
@@ -14291,7 +14291,7 @@ func rewriteValueS390X_OpS390XSRWconst(v *Value) bool {
// match: (SRWconst x [0])
// result: x
for {
- if auxIntToInt8(v.AuxInt) != 0 {
+ if auxIntToUint8(v.AuxInt) != 0 {
break
}
x := v_0
@@ -14339,7 +14339,7 @@ func rewriteValueS390X_OpS390XSTM2(v *Value) bool {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
p := v_0
- if v_1.Op != OpS390XSRDconst || auxIntToInt8(v_1.AuxInt) != 32 {
+ if v_1.Op != OpS390XSRDconst || auxIntToUint8(v_1.AuxInt) != 32 {
break
}
x := v_1.Args[0]
@@ -14851,7 +14851,7 @@ func rewriteValueS390X_OpS390XSumBytes2(v *Value) bool {
x := v_0
v.reset(OpS390XADDW)
v0 := b.NewValue0(v.Pos, OpS390XSRWconst, typ.UInt8)
- v0.AuxInt = int8ToAuxInt(8)
+ v0.AuxInt = uint8ToAuxInt(8)
v0.AddArg(x)
v.AddArg2(v0, x)
return true
@@ -14868,7 +14868,7 @@ func rewriteValueS390X_OpS390XSumBytes4(v *Value) bool {
v.reset(OpS390XSumBytes2)
v0 := b.NewValue0(v.Pos, OpS390XADDW, typ.UInt16)
v1 := b.NewValue0(v.Pos, OpS390XSRWconst, typ.UInt16)
- v1.AuxInt = int8ToAuxInt(16)
+ v1.AuxInt = uint8ToAuxInt(16)
v1.AddArg(x)
v0.AddArg2(v1, x)
v.AddArg(v0)
@@ -14886,7 +14886,7 @@ func rewriteValueS390X_OpS390XSumBytes8(v *Value) bool {
v.reset(OpS390XSumBytes4)
v0 := b.NewValue0(v.Pos, OpS390XADDW, typ.UInt32)
v1 := b.NewValue0(v.Pos, OpS390XSRDconst, typ.UInt32)
- v1.AuxInt = int8ToAuxInt(32)
+ v1.AuxInt = uint8ToAuxInt(32)
v1.AddArg(x)
v0.AddArg2(v1, x)
v.AddArg(v0)
@@ -14923,9 +14923,9 @@ func rewriteValueS390X_OpS390XXOR(v *Value) bool {
if v_0.Op != OpS390XSLDconst {
continue
}
- c := auxIntToInt8(v_0.AuxInt)
+ c := auxIntToUint8(v_0.AuxInt)
x := v_0.Args[0]
- if v_1.Op != OpS390XSRDconst || auxIntToInt8(v_1.AuxInt) != 64-c || x != v_1.Args[0] {
+ if v_1.Op != OpS390XSRDconst || auxIntToUint8(v_1.AuxInt) != 64-c || x != v_1.Args[0] {
continue
}
v.reset(OpS390XRISBGZ)
@@ -15019,13 +15019,13 @@ func rewriteValueS390X_OpS390XXORW(v *Value) bool {
if v_0.Op != OpS390XSLWconst {
continue
}
- c := auxIntToInt8(v_0.AuxInt)
+ c := auxIntToUint8(v_0.AuxInt)
x := v_0.Args[0]
- if v_1.Op != OpS390XSRWconst || auxIntToInt8(v_1.AuxInt) != 32-c || x != v_1.Args[0] {
+ if v_1.Op != OpS390XSRWconst || auxIntToUint8(v_1.AuxInt) != 32-c || x != v_1.Args[0] {
continue
}
v.reset(OpS390XRLLconst)
- v.AuxInt = int8ToAuxInt(c)
+ v.AuxInt = uint8ToAuxInt(c)
v.AddArg(x)
return true
}
@@ -15649,7 +15649,7 @@ func rewriteValueS390X_OpSlicemask(v *Value) bool {
t := v.Type
x := v_0
v.reset(OpS390XSRADconst)
- v.AuxInt = int8ToAuxInt(63)
+ v.AuxInt = uint8ToAuxInt(63)
v0 := b.NewValue0(v.Pos, OpS390XNEG, t)
v0.AddArg(x)
v.AddArg(v0)
diff --git a/src/cmd/go.mod b/src/cmd/go.mod
index c7d43873ef..031b8d4ab7 100644
--- a/src/cmd/go.mod
+++ b/src/cmd/go.mod
@@ -8,5 +8,5 @@ require (
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
golang.org/x/mod v0.4.0
golang.org/x/sys v0.0.0-20201204225414-ed752295db88 // indirect
- golang.org/x/tools v0.0.0-20201208211828-de58e7c01d49
+ golang.org/x/tools v0.0.0-20201211025543-abf6a1d87e11
)
diff --git a/src/cmd/go.sum b/src/cmd/go.sum
index 30edf77282..2fde9445f6 100644
--- a/src/cmd/go.sum
+++ b/src/cmd/go.sum
@@ -31,8 +31,8 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20201208211828-de58e7c01d49 h1:K1QAOVIWIvmQ66F1Z3AEa9Wzp0bj+xU3YzLkvROk2Ds=
-golang.org/x/tools v0.0.0-20201208211828-de58e7c01d49/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201211025543-abf6a1d87e11 h1:9j/upNXDRpADUw2RpUfJ7E7GHtfhDih62kX6JM8vs2c=
+golang.org/x/tools v0.0.0-20201211025543-abf6a1d87e11/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go
index daa407197c..c4913ce695 100644
--- a/src/cmd/go/alldocs.go
+++ b/src/cmd/go/alldocs.go
@@ -164,6 +164,17 @@
// directory, but it is not accessed. When -modfile is specified, an
// alternate go.sum file is also used: its path is derived from the
// -modfile flag by trimming the ".mod" extension and appending ".sum".
+// -overlay file
+// read a JSON config file that provides an overlay for build operations.
+// The file is a JSON struct with a single field, named 'Replace', that
+// maps each disk file path (a string) to its backing file path, so that
+// a build will run as if the disk file path exists with the contents
+// given by the backing file paths, or as if the disk file path does not
+// exist if its backing file path is empty. Support for the -overlay flag
+// has some limitations:importantly, cgo files included from outside the
+// include path must be in the same directory as the Go package they are
+// included from, and overlays will not appear when binaries and tests are
+// run through go run and go test respectively.
// -pkgdir dir
// install and load all packages from dir instead of the usual locations.
// For example, when building with a non-standard configuration,
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index 19764bfc60..c472620db2 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -31,6 +31,7 @@ import (
"cmd/go/internal/cache"
"cmd/go/internal/cfg"
"cmd/go/internal/robustio"
+ "cmd/go/internal/work"
"cmd/internal/sys"
)
@@ -1365,6 +1366,30 @@ func TestLdflagsArgumentsWithSpacesIssue3941(t *testing.T) {
tg.grepStderr("^hello world", `ldflags -X "main.extern=hello world"' failed`)
}
+func TestLdFlagsLongArgumentsIssue42295(t *testing.T) {
+ // Test the extremely long command line arguments that contain '\n' characters
+ // get encoded and passed correctly.
+ skipIfGccgo(t, "gccgo does not support -ldflags -X")
+ tooSlow(t)
+ tg := testgo(t)
+ defer tg.cleanup()
+ tg.parallel()
+ tg.tempFile("main.go", `package main
+ var extern string
+ func main() {
+ print(extern)
+ }`)
+ testStr := "test test test test test \n\\ "
+ var buf bytes.Buffer
+ for buf.Len() < work.ArgLengthForResponseFile+1 {
+ buf.WriteString(testStr)
+ }
+ tg.run("run", "-ldflags", fmt.Sprintf(`-X "main.extern=%s"`, buf.String()), tg.path("main.go"))
+ if tg.stderr.String() != buf.String() {
+ t.Errorf("strings differ")
+ }
+}
+
func TestGoTestDashCDashOControlsBinaryLocation(t *testing.T) {
skipIfGccgo(t, "gccgo has no standard packages")
tooSlow(t)
diff --git a/src/cmd/go/internal/fix/fix.go b/src/cmd/go/internal/fix/fix.go
index 825624fcbb..c7588c66d3 100644
--- a/src/cmd/go/internal/fix/fix.go
+++ b/src/cmd/go/internal/fix/fix.go
@@ -33,8 +33,20 @@ See also: go fmt, go vet.
}
func runFix(ctx context.Context, cmd *base.Command, args []string) {
+ pkgs := load.PackagesAndErrors(ctx, args)
+ w := 0
+ for _, pkg := range pkgs {
+ if pkg.Error != nil {
+ base.Errorf("%v", pkg.Error)
+ continue
+ }
+ pkgs[w] = pkg
+ w++
+ }
+ pkgs = pkgs[:w]
+
printed := false
- for _, pkg := range load.Packages(ctx, args) {
+ for _, pkg := range pkgs {
if modload.Enabled() && pkg.Module != nil && !pkg.Module.Main {
if !printed {
fmt.Fprintf(os.Stderr, "go: not fixing packages in dependency modules\n")
diff --git a/src/cmd/go/internal/get/get.go b/src/cmd/go/internal/get/get.go
index 268962eca8..94a42c4f73 100644
--- a/src/cmd/go/internal/get/get.go
+++ b/src/cmd/go/internal/get/get.go
@@ -180,13 +180,14 @@ func runGet(ctx context.Context, cmd *base.Command, args []string) {
// everything.
load.ClearPackageCache()
- pkgs := load.PackagesForBuild(ctx, args)
+ pkgs := load.PackagesAndErrors(ctx, args)
+ load.CheckPackageErrors(pkgs)
// Phase 3. Install.
if *getD {
// Download only.
- // Check delayed until now so that importPaths
- // and packagesForBuild have a chance to print errors.
+ // Check delayed until now so that downloadPaths
+ // and CheckPackageErrors have a chance to print errors.
return
}
diff --git a/src/cmd/go/internal/list/list.go b/src/cmd/go/internal/list/list.go
index 9af9dbb856..ce6f579c05 100644
--- a/src/cmd/go/internal/list/list.go
+++ b/src/cmd/go/internal/list/list.go
@@ -471,11 +471,18 @@ func runList(ctx context.Context, cmd *base.Command, args []string) {
}
load.IgnoreImports = *listFind
- var pkgs []*load.Package
- if *listE {
- pkgs = load.PackagesAndErrors(ctx, args)
- } else {
- pkgs = load.Packages(ctx, args)
+ pkgs := load.PackagesAndErrors(ctx, args)
+ if !*listE {
+ w := 0
+ for _, pkg := range pkgs {
+ if pkg.Error != nil {
+ base.Errorf("%v", pkg.Error)
+ continue
+ }
+ pkgs[w] = pkg
+ w++
+ }
+ pkgs = pkgs[:w]
base.ExitIfErrors()
}
diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go
index 6f95af4f7e..855f9698a2 100644
--- a/src/cmd/go/internal/load/pkg.go
+++ b/src/cmd/go/internal/load/pkg.go
@@ -2314,30 +2314,14 @@ func LoadImportWithFlags(path, srcDir string, parent *Package, stk *ImportStack,
// argument where needed.
var ModResolveTests bool
-// Packages returns the packages named by the
-// command line arguments 'args'. If a named package
-// cannot be loaded at all (for example, if the directory does not exist),
-// then packages prints an error and does not include that
-// package in the results. However, if errors occur trying
-// to load dependencies of a named package, the named
-// package is still returned, with p.Incomplete = true
-// and details in p.DepsErrors.
-func Packages(ctx context.Context, args []string) []*Package {
- var pkgs []*Package
- for _, pkg := range PackagesAndErrors(ctx, args) {
- if pkg.Error != nil {
- base.Errorf("%v", pkg.Error)
- continue
- }
- pkgs = append(pkgs, pkg)
- }
- return pkgs
-}
-
-// PackagesAndErrors is like 'packages' but returns a
-// *Package for every argument, even the ones that
-// cannot be loaded at all.
-// The packages that fail to load will have p.Error != nil.
+// PackagesAndErrors returns the packages named by the command line arguments
+// 'patterns'. If a named package cannot be loaded, PackagesAndErrors returns
+// a *Package with the Error field describing the failure. If errors are found
+// loading imported packages, the DepsErrors field is set. The Incomplete field
+// may be set as well.
+//
+// To obtain a flat list of packages, use PackageList.
+// To report errors loading packages, use ReportPackageErrors.
func PackagesAndErrors(ctx context.Context, patterns []string) []*Package {
ctx, span := trace.StartSpan(ctx, "load.PackagesAndErrors")
defer span.Done()
@@ -2427,20 +2411,9 @@ func PackagesAndErrors(ctx context.Context, patterns []string) []*Package {
return pkgs
}
-func setToolFlags(pkgs ...*Package) {
- for _, p := range PackageList(pkgs) {
- p.Internal.Asmflags = BuildAsmflags.For(p)
- p.Internal.Gcflags = BuildGcflags.For(p)
- p.Internal.Ldflags = BuildLdflags.For(p)
- p.Internal.Gccgoflags = BuildGccgoflags.For(p)
- }
-}
-
-// PackagesForBuild is like Packages but exits
-// if any of the packages or their dependencies have errors
-// (cannot be built).
-func PackagesForBuild(ctx context.Context, args []string) []*Package {
- pkgs := PackagesAndErrors(ctx, args)
+// CheckPackageErrors prints errors encountered loading pkgs and their
+// dependencies, then exits with a non-zero status if any errors were found.
+func CheckPackageErrors(pkgs []*Package) {
printed := map[*PackageError]bool{}
for _, pkg := range pkgs {
if pkg.Error != nil {
@@ -2475,8 +2448,15 @@ func PackagesForBuild(ctx context.Context, args []string) []*Package {
seen[pkg.ImportPath] = true
}
base.ExitIfErrors()
+}
- return pkgs
+func setToolFlags(pkgs ...*Package) {
+ for _, p := range PackageList(pkgs) {
+ p.Internal.Asmflags = BuildAsmflags.For(p)
+ p.Internal.Gcflags = BuildGcflags.For(p)
+ p.Internal.Ldflags = BuildLdflags.For(p)
+ p.Internal.Gccgoflags = BuildGccgoflags.For(p)
+ }
}
// GoFilesPackage creates a package for building a collection of Go files
diff --git a/src/cmd/go/internal/modget/get.go b/src/cmd/go/internal/modget/get.go
index e5f55879ee..8463ec4e9c 100644
--- a/src/cmd/go/internal/modget/get.go
+++ b/src/cmd/go/internal/modget/get.go
@@ -434,11 +434,13 @@ func runGet(ctx context.Context, cmd *base.Command, args []string) {
// directory.
if !*getD && len(pkgPatterns) > 0 {
work.BuildInit()
- pkgs := load.PackagesForBuild(ctx, pkgPatterns)
+ pkgs := load.PackagesAndErrors(ctx, pkgPatterns)
+ load.CheckPackageErrors(pkgs)
work.InstallPackages(ctx, pkgPatterns, pkgs)
// TODO(#40276): After Go 1.16, print a deprecation notice when building
// and installing main packages. 'go install pkg' or
// 'go install pkg@version' should be used instead.
+ // Give the specific argument to use if possible.
}
if !modload.HasModRoot() {
diff --git a/src/cmd/go/internal/test/test.go b/src/cmd/go/internal/test/test.go
index e8a7aacb85..50fe2dbf39 100644
--- a/src/cmd/go/internal/test/test.go
+++ b/src/cmd/go/internal/test/test.go
@@ -595,7 +595,8 @@ func runTest(ctx context.Context, cmd *base.Command, args []string) {
work.VetFlags = testVet.flags
work.VetExplicit = testVet.explicit
- pkgs = load.PackagesForBuild(ctx, pkgArgs)
+ pkgs = load.PackagesAndErrors(ctx, pkgArgs)
+ load.CheckPackageErrors(pkgs)
if len(pkgs) == 0 {
base.Fatalf("no packages to test")
}
@@ -678,7 +679,9 @@ func runTest(ctx context.Context, cmd *base.Command, args []string) {
sort.Strings(all)
a := &work.Action{Mode: "go test -i"}
- for _, p := range load.PackagesForBuild(ctx, all) {
+ pkgs := load.PackagesAndErrors(ctx, all)
+ load.CheckPackageErrors(pkgs)
+ for _, p := range pkgs {
if cfg.BuildToolchainName == "gccgo" && p.Standard {
// gccgo's standard library packages
// can not be reinstalled.
diff --git a/src/cmd/go/internal/vet/vet.go b/src/cmd/go/internal/vet/vet.go
index b1bf806e46..4257c90c97 100644
--- a/src/cmd/go/internal/vet/vet.go
+++ b/src/cmd/go/internal/vet/vet.go
@@ -87,7 +87,8 @@ func runVet(ctx context.Context, cmd *base.Command, args []string) {
}
}
- pkgs := load.PackagesForBuild(ctx, pkgArgs)
+ pkgs := load.PackagesAndErrors(ctx, pkgArgs)
+ load.CheckPackageErrors(pkgs)
if len(pkgs) == 0 {
base.Fatalf("no packages to vet")
}
diff --git a/src/cmd/go/internal/work/build.go b/src/cmd/go/internal/work/build.go
index 21b2289dff..7f2617cf1c 100644
--- a/src/cmd/go/internal/work/build.go
+++ b/src/cmd/go/internal/work/build.go
@@ -124,6 +124,17 @@ and test commands:
directory, but it is not accessed. When -modfile is specified, an
alternate go.sum file is also used: its path is derived from the
-modfile flag by trimming the ".mod" extension and appending ".sum".
+ -overlay file
+ read a JSON config file that provides an overlay for build operations.
+ The file is a JSON struct with a single field, named 'Replace', that
+ maps each disk file path (a string) to its backing file path, so that
+ a build will run as if the disk file path exists with the contents
+ given by the backing file paths, or as if the disk file path does not
+ exist if its backing file path is empty. Support for the -overlay flag
+ has some limitations:importantly, cgo files included from outside the
+ include path must be in the same directory as the Go package they are
+ included from, and overlays will not appear when binaries and tests are
+ run through go run and go test respectively.
-pkgdir dir
install and load all packages from dir instead of the usual locations.
For example, when building with a non-standard configuration,
@@ -358,7 +369,8 @@ func runBuild(ctx context.Context, cmd *base.Command, args []string) {
var b Builder
b.Init()
- pkgs := load.PackagesForBuild(ctx, args)
+ pkgs := load.PackagesAndErrors(ctx, args)
+ load.CheckPackageErrors(pkgs)
explicitO := len(cfg.BuildO) > 0
@@ -388,7 +400,7 @@ func runBuild(ctx context.Context, cmd *base.Command, args []string) {
fmt.Fprint(os.Stderr, "go build: -i flag is deprecated\n")
}
- pkgs = omitTestOnly(pkgsFilter(load.Packages(ctx, args)))
+ pkgs = omitTestOnly(pkgsFilter(pkgs))
// Special case -o /dev/null by not writing at all.
if cfg.BuildO == os.DevNull {
@@ -571,8 +583,32 @@ func runInstall(ctx context.Context, cmd *base.Command, args []string) {
return
}
}
+
BuildInit()
- pkgs := load.PackagesForBuild(ctx, args)
+ pkgs := load.PackagesAndErrors(ctx, args)
+ if cfg.ModulesEnabled && !modload.HasModRoot() {
+ haveErrors := false
+ allMissingErrors := true
+ for _, pkg := range pkgs {
+ if pkg.Error == nil {
+ continue
+ }
+ haveErrors = true
+ if missingErr := (*modload.ImportMissingError)(nil); !errors.As(pkg.Error, &missingErr) {
+ allMissingErrors = false
+ break
+ }
+ }
+ if haveErrors && allMissingErrors {
+ latestArgs := make([]string, len(args))
+ for i := range args {
+ latestArgs[i] = args[i] + "@latest"
+ }
+ hint := strings.Join(latestArgs, " ")
+ base.Fatalf("go install: version is required when current directory is not in a module\n\tTry 'go install %s' to install the latest version", hint)
+ }
+ }
+ load.CheckPackageErrors(pkgs)
if cfg.BuildI {
allGoroot := true
for _, pkg := range pkgs {
@@ -585,6 +621,7 @@ func runInstall(ctx context.Context, cmd *base.Command, args []string) {
fmt.Fprint(os.Stderr, "go install: -i flag is deprecated\n")
}
}
+
InstallPackages(ctx, args, pkgs)
}
@@ -802,7 +839,7 @@ func installOutsideModule(ctx context.Context, args []string) {
// Load packages for all arguments. Ignore non-main packages.
// Print a warning if an argument contains "..." and matches no main packages.
- // PackagesForBuild already prints warnings for patterns that don't match any
+ // PackagesAndErrors already prints warnings for patterns that don't match any
// packages, so be careful not to double print.
matchers := make([]func(string) bool, len(patterns))
for i, p := range patterns {
@@ -813,7 +850,8 @@ func installOutsideModule(ctx context.Context, args []string) {
// TODO(golang.org/issue/40276): don't report errors loading non-main packages
// matched by a pattern.
- pkgs := load.PackagesForBuild(ctx, patterns)
+ pkgs := load.PackagesAndErrors(ctx, patterns)
+ load.CheckPackageErrors(pkgs)
mainPkgs := make([]*load.Package, 0, len(pkgs))
mainCount := make([]int, len(patterns))
nonMainCount := make([]int, len(patterns))
diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go
index 336751df27..feb2299d40 100644
--- a/src/cmd/go/internal/work/exec.go
+++ b/src/cmd/go/internal/work/exec.go
@@ -3236,7 +3236,7 @@ func passLongArgsInResponseFiles(cmd *exec.Cmd) (cleanup func()) {
cleanup = func() { os.Remove(tf.Name()) }
var buf bytes.Buffer
for _, arg := range cmd.Args[1:] {
- fmt.Fprintf(&buf, "%s\n", arg)
+ fmt.Fprintf(&buf, "%s\n", encodeArg(arg))
}
if _, err := tf.Write(buf.Bytes()); err != nil {
tf.Close()
@@ -3251,6 +3251,12 @@ func passLongArgsInResponseFiles(cmd *exec.Cmd) (cleanup func()) {
return cleanup
}
+// Windows has a limit of 32 KB arguments. To be conservative and not worry
+// about whether that includes spaces or not, just use 30 KB. Darwin's limit is
+// less clear. The OS claims 256KB, but we've seen failures with arglen as
+// small as 50KB.
+const ArgLengthForResponseFile = (30 << 10)
+
func useResponseFile(path string, argLen int) bool {
// Unless the program uses objabi.Flagparse, which understands
// response files, don't use response files.
@@ -3262,11 +3268,7 @@ func useResponseFile(path string, argLen int) bool {
return false
}
- // Windows has a limit of 32 KB arguments. To be conservative and not
- // worry about whether that includes spaces or not, just use 30 KB.
- // Darwin's limit is less clear. The OS claims 256KB, but we've seen
- // failures with arglen as small as 50KB.
- if argLen > (30 << 10) {
+ if argLen > ArgLengthForResponseFile {
return true
}
@@ -3279,3 +3281,25 @@ func useResponseFile(path string, argLen int) bool {
return false
}
+
+// encodeArg encodes an argument for response file writing.
+func encodeArg(arg string) string {
+ // If there aren't any characters we need to reencode, fastpath out.
+ if !strings.ContainsAny(arg, "\\\n") {
+ return arg
+ }
+ var b strings.Builder
+ for _, r := range arg {
+ switch r {
+ case '\\':
+ b.WriteByte('\\')
+ b.WriteByte('\\')
+ case '\n':
+ b.WriteByte('\\')
+ b.WriteByte('n')
+ default:
+ b.WriteRune(r)
+ }
+ }
+ return b.String()
+}
diff --git a/src/cmd/go/internal/work/exec_test.go b/src/cmd/go/internal/work/exec_test.go
new file mode 100644
index 0000000000..4eb762cb28
--- /dev/null
+++ b/src/cmd/go/internal/work/exec_test.go
@@ -0,0 +1,86 @@
+// Copyright 2011 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 work
+
+import (
+ "bytes"
+ "cmd/internal/objabi"
+ "fmt"
+ "math/rand"
+ "testing"
+ "time"
+ "unicode/utf8"
+)
+
+func TestEncodeArgs(t *testing.T) {
+ t.Parallel()
+ tests := []struct {
+ arg, want string
+ }{
+ {"", ""},
+ {"hello", "hello"},
+ {"hello\n", "hello\\n"},
+ {"hello\\", "hello\\\\"},
+ {"hello\nthere", "hello\\nthere"},
+ {"\\\n", "\\\\\\n"},
+ }
+ for _, test := range tests {
+ if got := encodeArg(test.arg); got != test.want {
+ t.Errorf("encodeArg(%q) = %q, want %q", test.arg, got, test.want)
+ }
+ }
+}
+
+func TestEncodeDecode(t *testing.T) {
+ t.Parallel()
+ tests := []string{
+ "",
+ "hello",
+ "hello\\there",
+ "hello\nthere",
+ "hello ä¸å›½",
+ "hello \nä¸\\国",
+ }
+ for _, arg := range tests {
+ if got := objabi.DecodeArg(encodeArg(arg)); got != arg {
+ t.Errorf("objabi.DecodeArg(encodeArg(%q)) = %q", arg, got)
+ }
+ }
+}
+
+func TestEncodeDecodeFuzz(t *testing.T) {
+ if testing.Short() {
+ t.Skip("fuzz test is slow")
+ }
+ t.Parallel()
+
+ nRunes := ArgLengthForResponseFile + 100
+ rBuffer := make([]rune, nRunes)
+ buf := bytes.NewBuffer([]byte(string(rBuffer)))
+
+ seed := time.Now().UnixNano()
+ t.Logf("rand seed: %v", seed)
+ rng := rand.New(rand.NewSource(seed))
+
+ for i := 0; i < 50; i++ {
+ // Generate a random string of runes.
+ buf.Reset()
+ for buf.Len() < ArgLengthForResponseFile+1 {
+ var r rune
+ for {
+ r = rune(rng.Intn(utf8.MaxRune + 1))
+ if utf8.ValidRune(r) {
+ break
+ }
+ }
+ fmt.Fprintf(buf, "%c", r)
+ }
+ arg := buf.String()
+
+ if got := objabi.DecodeArg(encodeArg(arg)); got != arg {
+ t.Errorf("[%d] objabi.DecodeArg(encodeArg(%q)) = %q [seed: %v]", i, arg, got, seed)
+ }
+ }
+}
diff --git a/src/cmd/go/internal/work/init.go b/src/cmd/go/internal/work/init.go
index 102def4838..ba7c7c2fbb 100644
--- a/src/cmd/go/internal/work/init.go
+++ b/src/cmd/go/internal/work/init.go
@@ -241,7 +241,8 @@ func buildModeInit() {
if gccgo {
codegenArg = "-fPIC"
} else {
- forcedAsmflags = append(forcedAsmflags, "-D=GOBUILDMODE_shared=1")
+ forcedAsmflags = append(forcedAsmflags, "-D=GOBUILDMODE_shared=1",
+ "-linkshared")
codegenArg = "-dynlink"
forcedGcflags = append(forcedGcflags, "-linkshared")
// TODO(mwhudson): remove -w when that gets fixed in linker.
diff --git a/src/cmd/go/testdata/script/mod_outside.txt b/src/cmd/go/testdata/script/mod_outside.txt
index 28379ab40d..8f01b5d242 100644
--- a/src/cmd/go/testdata/script/mod_outside.txt
+++ b/src/cmd/go/testdata/script/mod_outside.txt
@@ -189,13 +189,16 @@ exists $GOPATH/bin/printversion$GOEXE
# 'go install' should fail if a package argument must be resolved to a module.
! go install example.com/printversion
-stderr 'no required module provides package example.com/printversion: working directory is not part of a module'
+stderr '^go install: version is required when current directory is not in a module\n\tTry ''go install example.com/printversion@latest'' to install the latest version$'
# 'go install' should fail if a source file imports a package that must be
# resolved to a module.
! go install ./needmod/needmod.go
stderr 'needmod[/\\]needmod.go:10:2: no required module provides package example.com/version: working directory is not part of a module'
+# 'go install' should succeed with a package in GOROOT.
+go install cmd/addr2line
+! stderr .
# 'go run' with a verison should fail due to syntax.
! go run example.com/printversion@v1.0.0
diff --git a/src/cmd/internal/goobj/objfile.go b/src/cmd/internal/goobj/objfile.go
index 6e76bea111..e6447e455d 100644
--- a/src/cmd/internal/goobj/objfile.go
+++ b/src/cmd/internal/goobj/objfile.go
@@ -483,6 +483,11 @@ func (r *RefFlags) SetFlag2(x uint8) { r[9] = x }
func (r *RefFlags) Write(w *Writer) { w.Bytes(r[:]) }
+// Used to construct an artifically large array type when reading an
+// item from the object file relocs section or aux sym section (needs
+// to work on 32-bit as well as 64-bit). See issue 41621.
+const huge = (1<<31 - 1) / RelocSize
+
// Referenced symbol name.
//
// Serialized format:
@@ -792,7 +797,7 @@ func (r *Reader) Reloc(i uint32, j int) *Reloc {
func (r *Reader) Relocs(i uint32) []Reloc {
off := r.RelocOff(i, 0)
n := r.NReloc(i)
- return (*[1 << 20]Reloc)(unsafe.Pointer(&r.b[off]))[:n:n]
+ return (*[huge]Reloc)(unsafe.Pointer(&r.b[off]))[:n:n]
}
// NAux returns the number of aux symbols of the i-th symbol.
@@ -818,7 +823,7 @@ func (r *Reader) Aux(i uint32, j int) *Aux {
func (r *Reader) Auxs(i uint32) []Aux {
off := r.AuxOff(i, 0)
n := r.NAux(i)
- return (*[1 << 20]Aux)(unsafe.Pointer(&r.b[off]))[:n:n]
+ return (*[huge]Aux)(unsafe.Pointer(&r.b[off]))[:n:n]
}
// DataOff returns the offset of the i-th symbol's data.
diff --git a/src/cmd/internal/obj/s390x/rotate.go b/src/cmd/internal/obj/s390x/rotate.go
index c999880492..5407c8df11 100644
--- a/src/cmd/internal/obj/s390x/rotate.go
+++ b/src/cmd/internal/obj/s390x/rotate.go
@@ -28,9 +28,9 @@ import (
// input left by. Note that this rotation is performed
// before the masked region is used.
type RotateParams struct {
- Start int8 // big-endian start bit index [0..63]
- End int8 // big-endian end bit index [0..63]
- Amount int8 // amount to rotate left
+ Start uint8 // big-endian start bit index [0..63]
+ End uint8 // big-endian end bit index [0..63]
+ Amount uint8 // amount to rotate left
}
// NewRotateParams creates a set of parameters representing a
@@ -39,7 +39,7 @@ type RotateParams struct {
//
// The start and end indexes and the rotation amount must all
// be in the range 0-63 inclusive or this function will panic.
-func NewRotateParams(start, end, amount int8) RotateParams {
+func NewRotateParams(start, end, amount uint8) RotateParams {
if start&^63 != 0 {
panic("start out of bounds")
}
@@ -58,7 +58,7 @@ func NewRotateParams(start, end, amount int8) RotateParams {
// RotateLeft generates a new set of parameters with the rotation amount
// increased by the given value. The selected bits are left unchanged.
-func (r RotateParams) RotateLeft(amount int8) RotateParams {
+func (r RotateParams) RotateLeft(amount uint8) RotateParams {
r.Amount += amount
r.Amount &= 63
return r
@@ -100,8 +100,8 @@ func (r RotateParams) OutMerge(mask uint64) *RotateParams {
}
// update start and end positions (rotation amount remains the same)
- r.Start = int8(o+z) & 63
- r.End = (r.Start + int8(l) - 1) & 63
+ r.Start = uint8(o+z) & 63
+ r.End = (r.Start + uint8(l) - 1) & 63
return &r
}
diff --git a/src/cmd/internal/obj/s390x/rotate_test.go b/src/cmd/internal/obj/s390x/rotate_test.go
index fa5b5bdecd..88421b1b83 100644
--- a/src/cmd/internal/obj/s390x/rotate_test.go
+++ b/src/cmd/internal/obj/s390x/rotate_test.go
@@ -10,7 +10,7 @@ import (
func TestRotateParamsMask(t *testing.T) {
tests := []struct {
- start, end, amount int8
+ start, end, amount uint8
inMask, outMask uint64
}{
// start before end, no rotation
diff --git a/src/cmd/internal/objabi/flag.go b/src/cmd/internal/objabi/flag.go
index 79ad2ccf74..3fd73f3c57 100644
--- a/src/cmd/internal/objabi/flag.go
+++ b/src/cmd/internal/objabi/flag.go
@@ -5,6 +5,7 @@
package objabi
import (
+ "bytes"
"flag"
"fmt"
"io"
@@ -59,6 +60,9 @@ func expandArgs(in []string) (out []string) {
log.Fatal(err)
}
args := strings.Split(strings.TrimSpace(strings.Replace(string(slurp), "\r", "", -1)), "\n")
+ for i, arg := range args {
+ args[i] = DecodeArg(arg)
+ }
out = append(out, expandArgs(args)...)
} else if out != nil {
out = append(out, s)
@@ -160,3 +164,38 @@ func (f fn1) Set(s string) error {
}
func (f fn1) String() string { return "" }
+
+// DecodeArg decodes an argument.
+//
+// This function is public for testing with the parallel encoder.
+func DecodeArg(arg string) string {
+ // If no encoding, fastpath out.
+ if !strings.ContainsAny(arg, "\\\n") {
+ return arg
+ }
+
+ // We can't use strings.Builder as this must work at bootstrap.
+ var b bytes.Buffer
+ var wasBS bool
+ for _, r := range arg {
+ if wasBS {
+ switch r {
+ case '\\':
+ b.WriteByte('\\')
+ case 'n':
+ b.WriteByte('\n')
+ default:
+ // This shouldn't happen. The only backslashes that reach here
+ // should encode '\n' and '\\' exclusively.
+ panic("badly formatted input")
+ }
+ } else if r == '\\' {
+ wasBS = true
+ continue
+ } else {
+ b.WriteRune(r)
+ }
+ wasBS = false
+ }
+ return b.String()
+}
diff --git a/src/cmd/internal/objabi/flag_test.go b/src/cmd/internal/objabi/flag_test.go
new file mode 100644
index 0000000000..935b9c2193
--- /dev/null
+++ b/src/cmd/internal/objabi/flag_test.go
@@ -0,0 +1,26 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package objabi
+
+import "testing"
+
+func TestDecodeArg(t *testing.T) {
+ t.Parallel()
+ tests := []struct {
+ arg, want string
+ }{
+ {"", ""},
+ {"hello", "hello"},
+ {"hello\\n", "hello\n"},
+ {"hello\\nthere", "hello\nthere"},
+ {"hello\\\\there", "hello\\there"},
+ {"\\\\\\n", "\\\n"},
+ }
+ for _, test := range tests {
+ if got := DecodeArg(test.arg); got != test.want {
+ t.Errorf("decodoeArg(%q) = %q, want %q", test.arg, got, test.want)
+ }
+ }
+}
diff --git a/src/cmd/link/internal/arm64/asm.go b/src/cmd/link/internal/arm64/asm.go
index a7af855646..d6c25fac41 100644
--- a/src/cmd/link/internal/arm64/asm.go
+++ b/src/cmd/link/internal/arm64/asm.go
@@ -37,6 +37,7 @@ import (
"cmd/link/internal/loader"
"cmd/link/internal/sym"
"debug/elf"
+ "fmt"
"log"
)
@@ -463,12 +464,29 @@ func elfreloc1(ctxt *ld.Link, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym,
return true
}
+// sign-extends from 24-bit.
+func signext24(x int64) int64 { return x << 40 >> 40 }
+
func machoreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, r loader.ExtReloc, sectoff int64) bool {
var v uint32
rs := r.Xsym
rt := r.Type
siz := r.Size
+ xadd := r.Xadd
+
+ if xadd != signext24(xadd) {
+ // If the relocation target would overflow the addend, then target
+ // a linker-manufactured label symbol with a smaller addend instead.
+ label := ldr.Lookup(machoLabelName(ldr, rs, xadd), ldr.SymVersion(rs))
+ if label != 0 {
+ xadd = ldr.SymValue(rs) + xadd - ldr.SymValue(label)
+ rs = label
+ }
+ if xadd != signext24(xadd) {
+ ldr.Errorf(s, "internal error: relocation addend overflow: %s+0x%x", ldr.SymName(rs), xadd)
+ }
+ }
if ldr.SymType(rs) == sym.SHOSTOBJ || rt == objabi.R_CALLARM64 || rt == objabi.R_ADDRARM64 || rt == objabi.R_ARM64_GOTPCREL {
if ldr.SymDynid(rs) < 0 {
@@ -492,8 +510,8 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sy
case objabi.R_ADDR:
v |= ld.MACHO_ARM64_RELOC_UNSIGNED << 28
case objabi.R_CALLARM64:
- if r.Xadd != 0 {
- ldr.Errorf(s, "ld64 doesn't allow BR26 reloc with non-zero addend: %s+%d", ldr.SymName(rs), r.Xadd)
+ if xadd != 0 {
+ ldr.Errorf(s, "ld64 doesn't allow BR26 reloc with non-zero addend: %s+%d", ldr.SymName(rs), xadd)
}
v |= 1 << 24 // pc-relative bit
@@ -504,13 +522,13 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sy
// if r.Xadd is non-zero, add two MACHO_ARM64_RELOC_ADDEND.
if r.Xadd != 0 {
out.Write32(uint32(sectoff + 4))
- out.Write32((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(r.Xadd&0xffffff))
+ out.Write32((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(xadd&0xffffff))
}
out.Write32(uint32(sectoff + 4))
out.Write32(v | (ld.MACHO_ARM64_RELOC_PAGEOFF12 << 28) | (2 << 25))
if r.Xadd != 0 {
out.Write32(uint32(sectoff))
- out.Write32((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(r.Xadd&0xffffff))
+ out.Write32((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(xadd&0xffffff))
}
v |= 1 << 24 // pc-relative bit
v |= ld.MACHO_ARM64_RELOC_PAGE21 << 28
@@ -520,13 +538,13 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sy
// if r.Xadd is non-zero, add two MACHO_ARM64_RELOC_ADDEND.
if r.Xadd != 0 {
out.Write32(uint32(sectoff + 4))
- out.Write32((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(r.Xadd&0xffffff))
+ out.Write32((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(xadd&0xffffff))
}
out.Write32(uint32(sectoff + 4))
out.Write32(v | (ld.MACHO_ARM64_RELOC_GOT_LOAD_PAGEOFF12 << 28) | (2 << 25))
if r.Xadd != 0 {
out.Write32(uint32(sectoff))
- out.Write32((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(r.Xadd&0xffffff))
+ out.Write32((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(xadd&0xffffff))
}
v |= 1 << 24 // pc-relative bit
v |= ld.MACHO_ARM64_RELOC_GOT_LOAD_PAGE21 << 28
@@ -965,3 +983,66 @@ func addpltsym(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade
ldr.Errorf(s, "addpltsym: unsupported binary format")
}
}
+
+const machoRelocLimit = 1 << 23
+
+func gensymlate(ctxt *ld.Link, ldr *loader.Loader) {
+ // When external linking on darwin, Mach-O relocation has only signed 24-bit
+ // addend. For large symbols, we generate "label" symbols in the middle, so
+ // that relocations can target them with smaller addends.
+ if !ctxt.IsDarwin() || !ctxt.IsExternal() {
+ return
+ }
+
+ big := false
+ for _, seg := range ld.Segments {
+ if seg.Length >= machoRelocLimit {
+ big = true
+ break
+ }
+ }
+ if !big {
+ return // skip work if nothing big
+ }
+
+ // addLabelSyms adds "label" symbols at s+machoRelocLimit, s+2*machoRelocLimit, etc.
+ addLabelSyms := func(s loader.Sym, sz int64) {
+ v := ldr.SymValue(s)
+ for off := int64(machoRelocLimit); off < sz; off += machoRelocLimit {
+ p := ldr.LookupOrCreateSym(machoLabelName(ldr, s, off), ldr.SymVersion(s))
+ ldr.SetAttrReachable(p, true)
+ ldr.SetSymValue(p, v+off)
+ ldr.SetSymSect(p, ldr.SymSect(s))
+ ld.AddMachoSym(ldr, p)
+ //fmt.Printf("gensymlate %s %x\n", ldr.SymName(p), ldr.SymValue(p))
+ }
+ }
+
+ for s, n := loader.Sym(1), loader.Sym(ldr.NSym()); s < n; s++ {
+ if !ldr.AttrReachable(s) {
+ continue
+ }
+ if ldr.SymType(s) == sym.STEXT {
+ continue // we don't target the middle of a function
+ }
+ sz := ldr.SymSize(s)
+ if sz <= machoRelocLimit {
+ continue
+ }
+ addLabelSyms(s, sz)
+ }
+
+ // Also for carrier symbols (for which SymSize is 0)
+ for _, ss := range ld.CarrierSymByType {
+ if ss.Sym != 0 && ss.Size > machoRelocLimit {
+ addLabelSyms(ss.Sym, ss.Size)
+ }
+ }
+}
+
+// machoLabelName returns the name of the "label" symbol used for a
+// relocation targetting s+off. The label symbols is used on darwin
+// when external linking, so that the addend fits in a Mach-O relocation.
+func machoLabelName(ldr *loader.Loader, s loader.Sym, off int64) string {
+ return fmt.Sprintf("%s.%d", ldr.SymExtname(s), off/machoRelocLimit)
+}
diff --git a/src/cmd/link/internal/arm64/obj.go b/src/cmd/link/internal/arm64/obj.go
index ab3dfd99f7..bd13295e61 100644
--- a/src/cmd/link/internal/arm64/obj.go
+++ b/src/cmd/link/internal/arm64/obj.go
@@ -55,6 +55,7 @@ func Init() (*sys.Arch, ld.Arch) {
ElfrelocSize: 24,
Elfsetupplt: elfsetupplt,
Gentext: gentext,
+ GenSymsLate: gensymlate,
Machoreloc1: machoreloc1,
MachorelocSize: 8,
diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go
index 00130044ab..3c5091e6a0 100644
--- a/src/cmd/link/internal/ld/data.go
+++ b/src/cmd/link/internal/ld/data.go
@@ -1815,6 +1815,7 @@ func (state *dodataState) allocateDataSections(ctxt *Link) {
for _, symn := range sym.ReadOnly {
symnStartValue := state.datsize
state.assignToSection(sect, symn, sym.SRODATA)
+ setCarrierSize(symn, state.datsize-symnStartValue)
if ctxt.HeadType == objabi.Haix {
// Read-only symbols might be wrapped inside their outer
// symbol.
@@ -1902,6 +1903,7 @@ func (state *dodataState) allocateDataSections(ctxt *Link) {
}
}
state.assignToSection(sect, symn, sym.SRODATA)
+ setCarrierSize(symn, state.datsize-symnStartValue)
if ctxt.HeadType == objabi.Haix {
// Read-only symbols might be wrapped inside their outer
// symbol.
@@ -1949,6 +1951,7 @@ func (state *dodataState) allocateDataSections(ctxt *Link) {
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.pctab", 0), sect)
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.functab", 0), sect)
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.epclntab", 0), sect)
+ setCarrierSize(sym.SPCLNTAB, int64(sect.Length))
if ctxt.HeadType == objabi.Haix {
xcoffUpdateOuterSize(ctxt, int64(sect.Length), sym.SPCLNTAB)
}
diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go
index e1cc7184de..833b3eb9db 100644
--- a/src/cmd/link/internal/ld/lib.go
+++ b/src/cmd/link/internal/ld/lib.go
@@ -1458,7 +1458,7 @@ func (ctxt *Link) hostlink() {
}
const compressDWARF = "-Wl,--compress-debug-sections=zlib-gnu"
- if ctxt.compressDWARF && linkerFlagSupported(argv[0], altLinker, compressDWARF) {
+ if ctxt.compressDWARF && linkerFlagSupported(ctxt.Arch, argv[0], altLinker, compressDWARF) {
argv = append(argv, compressDWARF)
}
@@ -1548,7 +1548,7 @@ func (ctxt *Link) hostlink() {
if ctxt.BuildMode == BuildModeExe && !ctxt.linkShared && !(ctxt.IsDarwin() && ctxt.IsARM64()) {
// GCC uses -no-pie, clang uses -nopie.
for _, nopie := range []string{"-no-pie", "-nopie"} {
- if linkerFlagSupported(argv[0], altLinker, nopie) {
+ if linkerFlagSupported(ctxt.Arch, argv[0], altLinker, nopie) {
argv = append(argv, nopie)
break
}
@@ -1560,10 +1560,22 @@ func (ctxt *Link) hostlink() {
checkStatic(p)
}
if ctxt.HeadType == objabi.Hwindows {
+ // Determine which linker we're using. Add in the extldflags in
+ // case used has specified "-fuse-ld=...".
+ cmd := exec.Command(*flagExtld, *flagExtldflags, "-Wl,--version")
+ usingLLD := false
+ if out, err := cmd.CombinedOutput(); err == nil {
+ if bytes.Contains(out, []byte("LLD ")) {
+ usingLLD = true
+ }
+ }
+
// use gcc linker script to work around gcc bug
// (see https://golang.org/issue/20183 for details).
- p := writeGDBLinkerScript()
- argv = append(argv, "-Wl,-T,"+p)
+ if !usingLLD {
+ p := writeGDBLinkerScript()
+ argv = append(argv, "-Wl,-T,"+p)
+ }
// libmingw32 and libmingwex have some inter-dependencies,
// so must use linker groups.
argv = append(argv, "-Wl,--start-group", "-lmingwex", "-lmingw32", "-Wl,--end-group")
@@ -1657,7 +1669,7 @@ func (ctxt *Link) hostlink() {
var createTrivialCOnce sync.Once
-func linkerFlagSupported(linker, altLinker, flag string) bool {
+func linkerFlagSupported(arch *sys.Arch, linker, altLinker, flag string) bool {
createTrivialCOnce.Do(func() {
src := filepath.Join(*flagTmpdir, "trivial.c")
if err := ioutil.WriteFile(src, []byte("int main() { return 0; }"), 0666); err != nil {
@@ -1691,7 +1703,7 @@ func linkerFlagSupported(linker, altLinker, flag string) bool {
"-target",
}
- var flags []string
+ flags := hostlinkArchArgs(arch)
keep := false
skip := false
extldflags := strings.Fields(*flagExtldflags)
@@ -1801,7 +1813,7 @@ func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string,
return ldhostobj(ldmacho, ctxt.HeadType, f, pkg, length, pn, file)
}
- if c1 == 0x4c && c2 == 0x01 || c1 == 0x64 && c2 == 0x86 {
+ if /* x86 */ c1 == 0x4c && c2 == 0x01 || /* x86_64 */ c1 == 0x64 && c2 == 0x86 || /* armv7 */ c1 == 0xc4 && c2 == 0x01 {
ldpe := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
textp, rsrc, err := loadpe.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn)
if err != nil {
diff --git a/src/cmd/link/internal/ld/macho.go b/src/cmd/link/internal/ld/macho.go
index f459576420..3630e67c25 100644
--- a/src/cmd/link/internal/ld/macho.go
+++ b/src/cmd/link/internal/ld/macho.go
@@ -969,6 +969,15 @@ func machosymorder(ctxt *Link) {
}
}
+// AddMachoSym adds s to Mach-O symbol table, used in GenSymLate.
+// Currently only used on ARM64 when external linking.
+func AddMachoSym(ldr *loader.Loader, s loader.Sym) {
+ ldr.SetSymDynid(s, int32(nsortsym))
+ sortsym = append(sortsym, s)
+ nsortsym++
+ nkind[symkind(ldr, s)]++
+}
+
// machoShouldExport reports whether a symbol needs to be exported.
//
// When dynamically linking, all non-local variables and plugin-exported
@@ -1474,6 +1483,17 @@ func machoCodeSign(ctxt *Link, fname string) error {
// Skip.
return nil
}
+
+ fi, err := f.Stat()
+ if err != nil {
+ return err
+ }
+ if sigOff+sigSz != fi.Size() {
+ // We don't expect anything after the signature (this will invalidate
+ // the signature anyway.)
+ return fmt.Errorf("unexpected content after code signature")
+ }
+
sz := codesign.Size(sigOff, "a.out")
if sz != sigSz {
// Update the load command,
@@ -1500,5 +1520,9 @@ func machoCodeSign(ctxt *Link, fname string) error {
cs := make([]byte, sz)
codesign.Sign(cs, f, "a.out", sigOff, int64(textSeg.Offset), int64(textSeg.Filesz), ctxt.IsExe() || ctxt.IsPIE())
_, err = f.WriteAt(cs, sigOff)
+ if err != nil {
+ return err
+ }
+ err = f.Truncate(sigOff + sz)
return err
}
diff --git a/src/cmd/link/internal/ld/pcln.go b/src/cmd/link/internal/ld/pcln.go
index facb30fe15..72bf33e611 100644
--- a/src/cmd/link/internal/ld/pcln.go
+++ b/src/cmd/link/internal/ld/pcln.go
@@ -859,6 +859,7 @@ func (ctxt *Link) pclntab(container loader.Bitmap) *pclntab {
state.carrier = ldr.LookupOrCreateSym("runtime.pclntab", 0)
ldr.MakeSymbolUpdater(state.carrier).SetType(sym.SPCLNTAB)
ldr.SetAttrReachable(state.carrier, true)
+ setCarrierSym(sym.SPCLNTAB, state.carrier)
state.generatePCHeader(ctxt)
nameOffsets := state.generateFuncnametab(ctxt, funcs)
diff --git a/src/cmd/link/internal/ld/pe.go b/src/cmd/link/internal/ld/pe.go
index d60aa55c36..adbf516d5c 100644
--- a/src/cmd/link/internal/ld/pe.go
+++ b/src/cmd/link/internal/ld/pe.go
@@ -1524,7 +1524,7 @@ func addpersrc(ctxt *Link) {
data := ctxt.loader.Data(rsrcsym)
size := len(data)
h := pefile.addSection(".rsrc", size, size)
- h.characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_INITIALIZED_DATA
+ h.characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA
h.checkOffset(ctxt.Out.Offset())
// relocation
diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go
index 4971389613..c98e4de03f 100644
--- a/src/cmd/link/internal/ld/symtab.go
+++ b/src/cmd/link/internal/ld/symtab.go
@@ -483,6 +483,8 @@ func (ctxt *Link) symtab(pcln *pclntab) []sym.SymKind {
symtype = s.Sym()
symtyperel = s.Sym()
}
+ setCarrierSym(sym.STYPE, symtype)
+ setCarrierSym(sym.STYPERELRO, symtyperel)
}
groupSym := func(name string, t sym.SymKind) loader.Sym {
@@ -490,6 +492,7 @@ func (ctxt *Link) symtab(pcln *pclntab) []sym.SymKind {
s.SetType(t)
s.SetSize(0)
s.SetLocal(true)
+ setCarrierSym(t, s.Sym())
return s.Sym()
}
var (
@@ -800,3 +803,23 @@ func (ctxt *Link) symtab(pcln *pclntab) []sym.SymKind {
}
return symGroupType
}
+
+// CarrierSymByType tracks carrier symbols and their sizes.
+var CarrierSymByType [sym.SXREF]struct {
+ Sym loader.Sym
+ Size int64
+}
+
+func setCarrierSym(typ sym.SymKind, s loader.Sym) {
+ if CarrierSymByType[typ].Sym != 0 {
+ panic(fmt.Sprintf("carrier symbol for type %v already set", typ))
+ }
+ CarrierSymByType[typ].Sym = s
+}
+
+func setCarrierSize(typ sym.SymKind, sz int64) {
+ if CarrierSymByType[typ].Size != 0 {
+ panic(fmt.Sprintf("carrier symbol size for type %v already set", typ))
+ }
+ CarrierSymByType[typ].Size = sz
+}
diff --git a/src/cmd/link/internal/ld/xcoff.go b/src/cmd/link/internal/ld/xcoff.go
index 7bf06eaa46..ba818eaa96 100644
--- a/src/cmd/link/internal/ld/xcoff.go
+++ b/src/cmd/link/internal/ld/xcoff.go
@@ -574,6 +574,7 @@ func xcoffUpdateOuterSize(ctxt *Link, size int64, stype sym.SymKind) {
if size == 0 {
return
}
+ // TODO: use CarrierSymByType
ldr := ctxt.loader
switch stype {
diff --git a/src/cmd/link/internal/loadelf/ldelf.go b/src/cmd/link/internal/loadelf/ldelf.go
index db543a5e50..c698874b32 100644
--- a/src/cmd/link/internal/loadelf/ldelf.go
+++ b/src/cmd/link/internal/loadelf/ldelf.go
@@ -969,6 +969,8 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, error) {
case MIPS | uint32(elf.R_MIPS_HI16)<<16,
MIPS | uint32(elf.R_MIPS_LO16)<<16,
MIPS | uint32(elf.R_MIPS_GOT16)<<16,
+ MIPS | uint32(elf.R_MIPS_GOT_HI16)<<16,
+ MIPS | uint32(elf.R_MIPS_GOT_LO16)<<16,
MIPS | uint32(elf.R_MIPS_GPREL16)<<16,
MIPS | uint32(elf.R_MIPS_GOT_PAGE)<<16,
MIPS | uint32(elf.R_MIPS_JALR)<<16,
@@ -976,6 +978,8 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, error) {
MIPS64 | uint32(elf.R_MIPS_HI16)<<16,
MIPS64 | uint32(elf.R_MIPS_LO16)<<16,
MIPS64 | uint32(elf.R_MIPS_GOT16)<<16,
+ MIPS64 | uint32(elf.R_MIPS_GOT_HI16)<<16,
+ MIPS64 | uint32(elf.R_MIPS_GOT_LO16)<<16,
MIPS64 | uint32(elf.R_MIPS_GPREL16)<<16,
MIPS64 | uint32(elf.R_MIPS_GOT_PAGE)<<16,
MIPS64 | uint32(elf.R_MIPS_JALR)<<16,
diff --git a/src/cmd/link/internal/loadpe/ldpe.go b/src/cmd/link/internal/loadpe/ldpe.go
index 7677278ec5..1e6f978531 100644
--- a/src/cmd/link/internal/loadpe/ldpe.go
+++ b/src/cmd/link/internal/loadpe/ldpe.go
@@ -6,6 +6,7 @@
package loadpe
import (
+ "bytes"
"cmd/internal/bio"
"cmd/internal/objabi"
"cmd/internal/sys"
@@ -308,7 +309,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
rAdd = int64(int32(binary.LittleEndian.Uint32(sectdata[rsect][rOff:])))
- case IMAGE_REL_ARM_ADDR32:
+ case IMAGE_REL_ARM_ADDR32, IMAGE_REL_ARM_ADDR32NB:
rType = objabi.R_ADDR
rAdd = int64(int32(binary.LittleEndian.Uint32(sectdata[rsect][rOff:])))
@@ -359,6 +360,20 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
if pesym.SectionNumber == IMAGE_SYM_DEBUG {
continue
}
+ if pesym.SectionNumber == IMAGE_SYM_ABSOLUTE && bytes.Equal(pesym.Name[:], []byte("@feat.00")) {
+ // Microsoft's linker looks at whether all input objects have an empty
+ // section called @feat.00. If all of them do, then it enables SEH;
+ // otherwise it doesn't enable that feature. So, since around the Windows
+ // XP SP2 era, most tools that make PE objects just tack on that section,
+ // so that it won't gimp Microsoft's linker logic. Go doesn't support SEH,
+ // so in theory, none of this really matters to us. But actually, if the
+ // linker tries to ingest an object with @feat.00 -- which are produced by
+ // LLVM's resource compiler, for example -- it chokes because of the
+ // IMAGE_SYM_ABSOLUTE section that it doesn't know how to deal with. Since
+ // @feat.00 is just a marking anyway, skip IMAGE_SYM_ABSOLUTE sections that
+ // are called @feat.00.
+ continue
+ }
var sect *pe.Section
if pesym.SectionNumber > 0 {
sect = f.Sections[pesym.SectionNumber-1]
diff --git a/src/cmd/link/link_test.go b/src/cmd/link/link_test.go
index 158c670739..4eb02c9e8a 100644
--- a/src/cmd/link/link_test.go
+++ b/src/cmd/link/link_test.go
@@ -925,3 +925,57 @@ func TestIssue42396(t *testing.T) {
t.Fatalf("error message incorrect: expected it to contain %q but instead got:\n%s\n", want, out)
}
}
+
+const testLargeRelocSrc = `
+package main
+
+var x = [1<<25]byte{1<<23: 23, 1<<24: 24}
+
+func main() {
+ check(x[1<<23-1], 0)
+ check(x[1<<23], 23)
+ check(x[1<<23+1], 0)
+ check(x[1<<24-1], 0)
+ check(x[1<<24], 24)
+ check(x[1<<24+1], 0)
+}
+
+func check(x, y byte) {
+ if x != y {
+ panic("FAIL")
+ }
+}
+`
+
+func TestLargeReloc(t *testing.T) {
+ // Test that large relocation addend is handled correctly.
+ // In particular, on darwin/arm64 when external linking,
+ // Mach-O relocation has only 24-bit addend. See issue #42738.
+ testenv.MustHaveGoBuild(t)
+ t.Parallel()
+
+ tmpdir, err := ioutil.TempDir("", "TestIssue42396")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.RemoveAll(tmpdir)
+
+ src := filepath.Join(tmpdir, "x.go")
+ err = ioutil.WriteFile(src, []byte(testLargeRelocSrc), 0666)
+ if err != nil {
+ t.Fatalf("failed to write source file: %v", err)
+ }
+ cmd := exec.Command(testenv.GoToolPath(t), "run", src)
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ t.Errorf("build failed: %v. output:\n%s", err, out)
+ }
+
+ if testenv.HasCGO() { // currently all targets that support cgo can external link
+ cmd = exec.Command(testenv.GoToolPath(t), "run", "-ldflags=-linkmode=external", src)
+ out, err = cmd.CombinedOutput()
+ if err != nil {
+ t.Fatalf("build failed: %v. output:\n%s", err, out)
+ }
+ }
+}
diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/structtag/structtag.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/structtag/structtag.go
index f0b15051c5..02555648a0 100644
--- a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/structtag/structtag.go
+++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/structtag/structtag.go
@@ -207,12 +207,12 @@ var (
)
// validateStructTag parses the struct tag and returns an error if it is not
-// in the canonical format, which is a space-separated list of key:"value"
-// settings. The value may contain spaces.
+// in the canonical format, as defined by reflect.StructTag.
func validateStructTag(tag string) error {
// This code is based on the StructTag.Get code in package reflect.
n := 0
+ var keys []string
for ; tag != ""; n++ {
if n > 0 && tag != "" && tag[0] != ' ' {
// More restrictive than reflect, but catches likely mistakes
@@ -240,14 +240,27 @@ func validateStructTag(tag string) error {
if i == 0 {
return errTagKeySyntax
}
- if i+1 >= len(tag) || tag[i] != ':' {
+ if i+1 >= len(tag) || tag[i] < ' ' || tag[i] == 0x7f {
return errTagSyntax
}
- if tag[i+1] != '"' {
+ key := tag[:i]
+ keys = append(keys, key)
+ tag = tag[i:]
+
+ // If we found a space char here - assume that we have a tag with
+ // multiple keys.
+ if tag[0] == ' ' {
+ continue
+ }
+
+ // Spaces were filtered above so we assume that here we have
+ // only valid tag value started with `:"`.
+ if tag[0] != ':' || tag[1] != '"' {
return errTagValueSyntax
}
- key := tag[:i]
- tag = tag[i+1:]
+
+ // Remove the colon leaving tag at the start of the quoted string.
+ tag = tag[1:]
// Scan quoted string to find value.
i = 1
@@ -263,51 +276,56 @@ func validateStructTag(tag string) error {
qvalue := tag[:i+1]
tag = tag[i+1:]
- value, err := strconv.Unquote(qvalue)
+ wholeValue, err := strconv.Unquote(qvalue)
if err != nil {
return errTagValueSyntax
}
- if !checkTagSpaces[key] {
- continue
- }
-
- switch key {
- case "xml":
- // If the first or last character in the XML tag is a space, it is
- // suspicious.
- if strings.Trim(value, " ") != value {
- return errTagValueSpace
- }
-
- // If there are multiple spaces, they are suspicious.
- if strings.Count(value, " ") > 1 {
- return errTagValueSpace
- }
-
- // If there is no comma, skip the rest of the checks.
- comma := strings.IndexRune(value, ',')
- if comma < 0 {
+ for _, key := range keys {
+ if !checkTagSpaces[key] {
continue
}
- // If the character before a comma is a space, this is suspicious.
- if comma > 0 && value[comma-1] == ' ' {
+ value := wholeValue
+ switch key {
+ case "xml":
+ // If the first or last character in the XML tag is a space, it is
+ // suspicious.
+ if strings.Trim(value, " ") != value {
+ return errTagValueSpace
+ }
+
+ // If there are multiple spaces, they are suspicious.
+ if strings.Count(value, " ") > 1 {
+ return errTagValueSpace
+ }
+
+ // If there is no comma, skip the rest of the checks.
+ comma := strings.IndexRune(value, ',')
+ if comma < 0 {
+ continue
+ }
+
+ // If the character before a comma is a space, this is suspicious.
+ if comma > 0 && value[comma-1] == ' ' {
+ return errTagValueSpace
+ }
+ value = value[comma+1:]
+ case "json":
+ // JSON allows using spaces in the name, so skip it.
+ comma := strings.IndexRune(value, ',')
+ if comma < 0 {
+ continue
+ }
+ value = value[comma+1:]
+ }
+
+ if strings.IndexByte(value, ' ') >= 0 {
return errTagValueSpace
}
- value = value[comma+1:]
- case "json":
- // JSON allows using spaces in the name, so skip it.
- comma := strings.IndexRune(value, ',')
- if comma < 0 {
- continue
- }
- value = value[comma+1:]
}
- if strings.IndexByte(value, ' ') >= 0 {
- return errTagValueSpace
- }
+ keys = keys[:0]
}
return nil
}
diff --git a/src/cmd/vendor/modules.txt b/src/cmd/vendor/modules.txt
index b549258cfa..4e47f41855 100644
--- a/src/cmd/vendor/modules.txt
+++ b/src/cmd/vendor/modules.txt
@@ -44,7 +44,7 @@ golang.org/x/mod/zip
golang.org/x/sys/internal/unsafeheader
golang.org/x/sys/unix
golang.org/x/sys/windows
-# golang.org/x/tools v0.0.0-20201208211828-de58e7c01d49
+# golang.org/x/tools v0.0.0-20201211025543-abf6a1d87e11
## explicit
golang.org/x/tools/go/analysis
golang.org/x/tools/go/analysis/internal/analysisflags
diff --git a/src/crypto/tls/common.go b/src/crypto/tls/common.go
index 5b68742975..eec6e1ebbd 100644
--- a/src/crypto/tls/common.go
+++ b/src/crypto/tls/common.go
@@ -7,7 +7,6 @@ package tls
import (
"bytes"
"container/list"
- "context"
"crypto"
"crypto/ecdsa"
"crypto/ed25519"
@@ -444,16 +443,6 @@ type ClientHelloInfo struct {
// config is embedded by the GetCertificate or GetConfigForClient caller,
// for use with SupportsCertificate.
config *Config
-
- // ctx is the context of the handshake that is in progress.
- ctx context.Context
-}
-
-// Context returns the context of the handshake that is in progress.
-// This context is a child of the context passed to HandshakeContext,
-// if any, and is canceled when the handshake concludes.
-func (c *ClientHelloInfo) Context() context.Context {
- return c.ctx
}
// CertificateRequestInfo contains information from a server's
@@ -472,16 +461,6 @@ type CertificateRequestInfo struct {
// Version is the TLS version that was negotiated for this connection.
Version uint16
-
- // ctx is the context of the handshake that is in progress.
- ctx context.Context
-}
-
-// Context returns the context of the handshake that is in progress.
-// This context is a child of the context passed to HandshakeContext,
-// if any, and is canceled when the handshake concludes.
-func (c *CertificateRequestInfo) Context() context.Context {
- return c.ctx
}
// RenegotiationSupport enumerates the different levels of support for TLS
diff --git a/src/crypto/tls/conn.go b/src/crypto/tls/conn.go
index 969f357834..72ad52c194 100644
--- a/src/crypto/tls/conn.go
+++ b/src/crypto/tls/conn.go
@@ -8,7 +8,6 @@ package tls
import (
"bytes"
- "context"
"crypto/cipher"
"crypto/subtle"
"crypto/x509"
@@ -28,7 +27,7 @@ type Conn struct {
// constant
conn net.Conn
isClient bool
- handshakeFn func(context.Context) error // (*Conn).clientHandshake or serverHandshake
+ handshakeFn func() error // (*Conn).clientHandshake or serverHandshake
// handshakeStatus is 1 if the connection is currently transferring
// application data (i.e. is not currently processing a handshake).
@@ -1191,7 +1190,7 @@ func (c *Conn) handleRenegotiation() error {
defer c.handshakeMutex.Unlock()
atomic.StoreUint32(&c.handshakeStatus, 0)
- if c.handshakeErr = c.clientHandshake(context.Background()); c.handshakeErr == nil {
+ if c.handshakeErr = c.clientHandshake(); c.handshakeErr == nil {
c.handshakes++
}
return c.handshakeErr
@@ -1374,61 +1373,8 @@ func (c *Conn) closeNotify() error {
// first Read or Write will call it automatically.
//
// For control over canceling or setting a timeout on a handshake, use
-// HandshakeContext or the Dialer's DialContext method instead.
+// the Dialer's DialContext method.
func (c *Conn) Handshake() error {
- return c.HandshakeContext(context.Background())
-}
-
-// HandshakeContext runs the client or server handshake
-// protocol if it has not yet been run.
-//
-// The provided Context must be non-nil. If the context is canceled before
-// the handshake is complete, the handshake is interrupted and an error is returned.
-// Once the handshake has completed, cancellation of the context will not affect the
-// connection.
-//
-// Most uses of this package need not call HandshakeContext explicitly: the
-// first Read or Write will call it automatically.
-func (c *Conn) HandshakeContext(ctx context.Context) error {
- // Delegate to unexported method for named return
- // without confusing documented signature.
- return c.handshakeContext(ctx)
-}
-
-func (c *Conn) handshakeContext(ctx context.Context) (ret error) {
- handshakeCtx, cancel := context.WithCancel(ctx)
- // Note: defer this before starting the "interrupter" goroutine
- // so that we can tell the difference between the input being canceled and
- // this cancellation. In the former case, we need to close the connection.
- defer cancel()
-
- // Start the "interrupter" goroutine, if this context might be canceled.
- // (The background context cannot).
- //
- // The interrupter goroutine waits for the input context to be done and
- // closes the connection if this happens before the function returns.
- if ctx.Done() != nil {
- done := make(chan struct{})
- interruptRes := make(chan error, 1)
- defer func() {
- close(done)
- if ctxErr := <-interruptRes; ctxErr != nil {
- // Return context error to user.
- ret = ctxErr
- }
- }()
- go func() {
- select {
- case <-handshakeCtx.Done():
- // Close the connection, discarding the error
- _ = c.conn.Close()
- interruptRes <- handshakeCtx.Err()
- case <-done:
- interruptRes <- nil
- }
- }()
- }
-
c.handshakeMutex.Lock()
defer c.handshakeMutex.Unlock()
@@ -1442,7 +1388,7 @@ func (c *Conn) handshakeContext(ctx context.Context) (ret error) {
c.in.Lock()
defer c.in.Unlock()
- c.handshakeErr = c.handshakeFn(handshakeCtx)
+ c.handshakeErr = c.handshakeFn()
if c.handshakeErr == nil {
c.handshakes++
} else {
diff --git a/src/crypto/tls/handshake_client.go b/src/crypto/tls/handshake_client.go
index 92e33e7169..e684b21d52 100644
--- a/src/crypto/tls/handshake_client.go
+++ b/src/crypto/tls/handshake_client.go
@@ -6,7 +6,6 @@ package tls
import (
"bytes"
- "context"
"crypto"
"crypto/ecdsa"
"crypto/ed25519"
@@ -25,7 +24,6 @@ import (
type clientHandshakeState struct {
c *Conn
- ctx context.Context
serverHello *serverHelloMsg
hello *clientHelloMsg
suite *cipherSuite
@@ -136,7 +134,7 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, ecdheParameters, error) {
return hello, params, nil
}
-func (c *Conn) clientHandshake(ctx context.Context) (err error) {
+func (c *Conn) clientHandshake() (err error) {
if c.config == nil {
c.config = defaultConfig()
}
@@ -200,7 +198,6 @@ func (c *Conn) clientHandshake(ctx context.Context) (err error) {
if c.vers == VersionTLS13 {
hs := &clientHandshakeStateTLS13{
c: c,
- ctx: ctx,
serverHello: serverHello,
hello: hello,
ecdheParams: ecdheParams,
@@ -215,7 +212,6 @@ func (c *Conn) clientHandshake(ctx context.Context) (err error) {
hs := &clientHandshakeState{
c: c,
- ctx: ctx,
serverHello: serverHello,
hello: hello,
session: session,
@@ -544,7 +540,7 @@ func (hs *clientHandshakeState) doFullHandshake() error {
certRequested = true
hs.finishedHash.Write(certReq.marshal())
- cri := certificateRequestInfoFromMsg(hs.ctx, c.vers, certReq)
+ cri := certificateRequestInfoFromMsg(c.vers, certReq)
if chainToSend, err = c.getClientCertificate(cri); err != nil {
c.sendAlert(alertInternalError)
return err
@@ -884,11 +880,10 @@ func (c *Conn) verifyServerCertificate(certificates [][]byte) error {
// certificateRequestInfoFromMsg generates a CertificateRequestInfo from a TLS
// <= 1.2 CertificateRequest, making an effort to fill in missing information.
-func certificateRequestInfoFromMsg(ctx context.Context, vers uint16, certReq *certificateRequestMsg) *CertificateRequestInfo {
+func certificateRequestInfoFromMsg(vers uint16, certReq *certificateRequestMsg) *CertificateRequestInfo {
cri := &CertificateRequestInfo{
AcceptableCAs: certReq.certificateAuthorities,
Version: vers,
- ctx: ctx,
}
var rsaAvail, ecAvail bool
diff --git a/src/crypto/tls/handshake_client_test.go b/src/crypto/tls/handshake_client_test.go
index 8889e2c8c3..12b0254123 100644
--- a/src/crypto/tls/handshake_client_test.go
+++ b/src/crypto/tls/handshake_client_test.go
@@ -6,7 +6,6 @@ package tls
import (
"bytes"
- "context"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
@@ -21,7 +20,6 @@ import (
"os/exec"
"path/filepath"
"reflect"
- "runtime"
"strconv"
"strings"
"testing"
@@ -2513,37 +2511,3 @@ func testResumptionKeepsOCSPAndSCT(t *testing.T, ver uint16) {
serverConfig.Certificates[0].SignedCertificateTimestamps, ccs.SignedCertificateTimestamps)
}
}
-
-func TestClientHandshakeContextCancellation(t *testing.T) {
- c, s := localPipe(t)
- serverConfig := testConfig.Clone()
- serverErr := make(chan error, 1)
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
- go func() {
- defer close(serverErr)
- defer s.Close()
- conn := Server(s, serverConfig)
- _, err := conn.readClientHello(ctx)
- cancel()
- serverErr <- err
- }()
- cli := Client(c, testConfig)
- err := cli.HandshakeContext(ctx)
- if err == nil {
- t.Fatal("Client handshake did not error when the context was canceled")
- }
- if err != context.Canceled {
- t.Errorf("Unexpected client handshake error: %v", err)
- }
- if err := <-serverErr; err != nil {
- t.Errorf("Unexpected server error: %v", err)
- }
- if runtime.GOARCH == "wasm" {
- t.Skip("conn.Close does not error as expected when called multiple times on WASM")
- }
- err = cli.Close()
- if err == nil {
- t.Error("Client connection was not closed when the context was canceled")
- }
-}
diff --git a/src/crypto/tls/handshake_client_tls13.go b/src/crypto/tls/handshake_client_tls13.go
index be37c681c6..daa5d97fd3 100644
--- a/src/crypto/tls/handshake_client_tls13.go
+++ b/src/crypto/tls/handshake_client_tls13.go
@@ -6,7 +6,6 @@ package tls
import (
"bytes"
- "context"
"crypto"
"crypto/hmac"
"crypto/rsa"
@@ -18,7 +17,6 @@ import (
type clientHandshakeStateTLS13 struct {
c *Conn
- ctx context.Context
serverHello *serverHelloMsg
hello *clientHelloMsg
ecdheParams ecdheParameters
@@ -557,7 +555,6 @@ func (hs *clientHandshakeStateTLS13) sendClientCertificate() error {
AcceptableCAs: hs.certReq.certificateAuthorities,
SignatureSchemes: hs.certReq.supportedSignatureAlgorithms,
Version: c.vers,
- ctx: hs.ctx,
})
if err != nil {
return err
diff --git a/src/crypto/tls/handshake_server.go b/src/crypto/tls/handshake_server.go
index 5a572a9db1..9c3e0f636e 100644
--- a/src/crypto/tls/handshake_server.go
+++ b/src/crypto/tls/handshake_server.go
@@ -5,7 +5,6 @@
package tls
import (
- "context"
"crypto"
"crypto/ecdsa"
"crypto/ed25519"
@@ -24,7 +23,6 @@ import (
// It's discarded once the handshake has completed.
type serverHandshakeState struct {
c *Conn
- ctx context.Context
clientHello *clientHelloMsg
hello *serverHelloMsg
suite *cipherSuite
@@ -39,8 +37,8 @@ type serverHandshakeState struct {
}
// serverHandshake performs a TLS handshake as a server.
-func (c *Conn) serverHandshake(ctx context.Context) error {
- clientHello, err := c.readClientHello(ctx)
+func (c *Conn) serverHandshake() error {
+ clientHello, err := c.readClientHello()
if err != nil {
return err
}
@@ -48,7 +46,6 @@ func (c *Conn) serverHandshake(ctx context.Context) error {
if c.vers == VersionTLS13 {
hs := serverHandshakeStateTLS13{
c: c,
- ctx: ctx,
clientHello: clientHello,
}
return hs.handshake()
@@ -56,7 +53,6 @@ func (c *Conn) serverHandshake(ctx context.Context) error {
hs := serverHandshakeState{
c: c,
- ctx: ctx,
clientHello: clientHello,
}
return hs.handshake()
@@ -128,7 +124,7 @@ func (hs *serverHandshakeState) handshake() error {
}
// readClientHello reads a ClientHello message and selects the protocol version.
-func (c *Conn) readClientHello(ctx context.Context) (*clientHelloMsg, error) {
+func (c *Conn) readClientHello() (*clientHelloMsg, error) {
msg, err := c.readHandshake()
if err != nil {
return nil, err
@@ -142,7 +138,7 @@ func (c *Conn) readClientHello(ctx context.Context) (*clientHelloMsg, error) {
var configForClient *Config
originalConfig := c.config
if c.config.GetConfigForClient != nil {
- chi := clientHelloInfo(ctx, c, clientHello)
+ chi := clientHelloInfo(c, clientHello)
if configForClient, err = c.config.GetConfigForClient(chi); err != nil {
c.sendAlert(alertInternalError)
return nil, err
@@ -224,7 +220,7 @@ func (hs *serverHandshakeState) processClientHello() error {
}
}
- hs.cert, err = c.config.getCertificate(clientHelloInfo(hs.ctx, c, hs.clientHello))
+ hs.cert, err = c.config.getCertificate(clientHelloInfo(c, hs.clientHello))
if err != nil {
if err == errNoCertificates {
c.sendAlert(alertUnrecognizedName)
@@ -832,7 +828,7 @@ func (c *Conn) processCertsFromClient(certificate Certificate) error {
return nil
}
-func clientHelloInfo(ctx context.Context, c *Conn, clientHello *clientHelloMsg) *ClientHelloInfo {
+func clientHelloInfo(c *Conn, clientHello *clientHelloMsg) *ClientHelloInfo {
supportedVersions := clientHello.supportedVersions
if len(clientHello.supportedVersions) == 0 {
supportedVersions = supportedVersionsFromMax(clientHello.vers)
@@ -848,6 +844,5 @@ func clientHelloInfo(ctx context.Context, c *Conn, clientHello *clientHelloMsg)
SupportedVersions: supportedVersions,
Conn: c.conn,
config: c.config,
- ctx: ctx,
}
}
diff --git a/src/crypto/tls/handshake_server_test.go b/src/crypto/tls/handshake_server_test.go
index ad851b6edf..d6bf9e439b 100644
--- a/src/crypto/tls/handshake_server_test.go
+++ b/src/crypto/tls/handshake_server_test.go
@@ -6,7 +6,6 @@ package tls
import (
"bytes"
- "context"
"crypto"
"crypto/elliptic"
"crypto/x509"
@@ -18,7 +17,6 @@ import (
"os"
"os/exec"
"path/filepath"
- "runtime"
"strings"
"testing"
"time"
@@ -40,12 +38,10 @@ func testClientHelloFailure(t *testing.T, serverConfig *Config, m handshakeMessa
cli.writeRecord(recordTypeHandshake, m.marshal())
c.Close()
}()
- ctx := context.Background()
conn := Server(s, serverConfig)
- ch, err := conn.readClientHello(ctx)
+ ch, err := conn.readClientHello()
hs := serverHandshakeState{
c: conn,
- ctx: ctx,
clientHello: ch,
}
if err == nil {
@@ -1425,11 +1421,9 @@ func TestSNIGivenOnFailure(t *testing.T) {
c.Close()
}()
conn := Server(s, serverConfig)
- ctx := context.Background()
- ch, err := conn.readClientHello(ctx)
+ ch, err := conn.readClientHello()
hs := serverHandshakeState{
c: conn,
- ctx: ctx,
clientHello: ch,
}
if err == nil {
@@ -1683,46 +1677,6 @@ func TestMultipleCertificates(t *testing.T) {
}
}
-func TestServerHandshakeContextCancellation(t *testing.T) {
- c, s := localPipe(t)
- clientConfig := testConfig.Clone()
- clientErr := make(chan error, 1)
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
- go func() {
- defer close(clientErr)
- defer c.Close()
- clientHello := &clientHelloMsg{
- vers: VersionTLS10,
- random: make([]byte, 32),
- cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
- compressionMethods: []uint8{compressionNone},
- }
- cli := Client(c, clientConfig)
- _, err := cli.writeRecord(recordTypeHandshake, clientHello.marshal())
- cancel()
- clientErr <- err
- }()
- conn := Server(s, testConfig)
- err := conn.HandshakeContext(ctx)
- if err == nil {
- t.Fatal("Server handshake did not error when the context was canceled")
- }
- if err != context.Canceled {
- t.Errorf("Unexpected server handshake error: %v", err)
- }
- if err := <-clientErr; err != nil {
- t.Errorf("Unexpected client error: %v", err)
- }
- if runtime.GOARCH == "wasm" {
- t.Skip("conn.Close does not error as expected when called multiple times on WASM")
- }
- err = conn.Close()
- if err == nil {
- t.Error("Server connection was not closed when the context was canceled")
- }
-}
-
func TestAESCipherReordering(t *testing.T) {
currentAESSupport := hasAESGCMHardwareSupport
defer func() { hasAESGCMHardwareSupport = currentAESSupport; initDefaultCipherSuites() }()
diff --git a/src/crypto/tls/handshake_server_tls13.go b/src/crypto/tls/handshake_server_tls13.go
index c7837d2955..c2c288aed4 100644
--- a/src/crypto/tls/handshake_server_tls13.go
+++ b/src/crypto/tls/handshake_server_tls13.go
@@ -6,7 +6,6 @@ package tls
import (
"bytes"
- "context"
"crypto"
"crypto/hmac"
"crypto/rsa"
@@ -24,7 +23,6 @@ const maxClientPSKIdentities = 5
type serverHandshakeStateTLS13 struct {
c *Conn
- ctx context.Context
clientHello *clientHelloMsg
hello *serverHelloMsg
sentDummyCCS bool
@@ -376,7 +374,7 @@ func (hs *serverHandshakeStateTLS13) pickCertificate() error {
return c.sendAlert(alertMissingExtension)
}
- certificate, err := c.config.getCertificate(clientHelloInfo(hs.ctx, c, hs.clientHello))
+ certificate, err := c.config.getCertificate(clientHelloInfo(c, hs.clientHello))
if err != nil {
if err == errNoCertificates {
c.sendAlert(alertUnrecognizedName)
diff --git a/src/crypto/tls/tls.go b/src/crypto/tls/tls.go
index 19884f96e7..a389873d32 100644
--- a/src/crypto/tls/tls.go
+++ b/src/crypto/tls/tls.go
@@ -25,6 +25,7 @@ import (
"net"
"os"
"strings"
+ "time"
)
// Server returns a new TLS server side connection
@@ -115,16 +116,28 @@ func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config) (*
}
func dial(ctx context.Context, netDialer *net.Dialer, network, addr string, config *Config) (*Conn, error) {
- if netDialer.Timeout != 0 {
- var cancel context.CancelFunc
- ctx, cancel = context.WithTimeout(ctx, netDialer.Timeout)
- defer cancel()
- }
+ // We want the Timeout and Deadline values from dialer to cover the
+ // whole process: TCP connection and TLS handshake. This means that we
+ // also need to start our own timers now.
+ timeout := netDialer.Timeout
if !netDialer.Deadline.IsZero() {
- var cancel context.CancelFunc
- ctx, cancel = context.WithDeadline(ctx, netDialer.Deadline)
- defer cancel()
+ deadlineTimeout := time.Until(netDialer.Deadline)
+ if timeout == 0 || deadlineTimeout < timeout {
+ timeout = deadlineTimeout
+ }
+ }
+
+ // hsErrCh is non-nil if we might not wait for Handshake to complete.
+ var hsErrCh chan error
+ if timeout != 0 || ctx.Done() != nil {
+ hsErrCh = make(chan error, 2)
+ }
+ if timeout != 0 {
+ timer := time.AfterFunc(timeout, func() {
+ hsErrCh <- timeoutError{}
+ })
+ defer timer.Stop()
}
rawConn, err := netDialer.DialContext(ctx, network, addr)
@@ -151,10 +164,34 @@ func dial(ctx context.Context, netDialer *net.Dialer, network, addr string, conf
}
conn := Client(rawConn, config)
- if err := conn.HandshakeContext(ctx); err != nil {
+
+ if hsErrCh == nil {
+ err = conn.Handshake()
+ } else {
+ go func() {
+ hsErrCh <- conn.Handshake()
+ }()
+
+ select {
+ case <-ctx.Done():
+ err = ctx.Err()
+ case err = <-hsErrCh:
+ if err != nil {
+ // If the error was due to the context
+ // closing, prefer the context's error, rather
+ // than some random network teardown error.
+ if e := ctx.Err(); e != nil {
+ err = e
+ }
+ }
+ }
+ }
+
+ if err != nil {
rawConn.Close()
return nil, err
}
+
return conn, nil
}
diff --git a/src/database/sql/sql.go b/src/database/sql/sql.go
index d8f19520c8..726aadb899 100644
--- a/src/database/sql/sql.go
+++ b/src/database/sql/sql.go
@@ -1141,7 +1141,7 @@ func (db *DB) connectionOpener(ctx context.Context) {
// Open one new connection
func (db *DB) openNewConnection(ctx context.Context) {
- // maybeOpenNewConnctions has already executed db.numOpen++ before it sent
+ // maybeOpenNewConnections has already executed db.numOpen++ before it sent
// on db.openerCh. This function must execute db.numOpen-- if the
// connection fails or is closed before returning.
ci, err := db.connector.Connect(ctx)
diff --git a/src/debug/dwarf/dwarf5ranges_test.go b/src/debug/dwarf/dwarf5ranges_test.go
index 0ff1a55bc9..8bc50bcab6 100644
--- a/src/debug/dwarf/dwarf5ranges_test.go
+++ b/src/debug/dwarf/dwarf5ranges_test.go
@@ -22,7 +22,12 @@ func TestDwarf5Ranges(t *testing.T) {
if err := d.AddSection(".debug_rnglists", rngLists); err != nil {
t.Fatal(err)
}
- ret, err := d.dwarf5Ranges(nil, 0x5fbd, 0xc, [][2]uint64{})
+ u := &unit{
+ asize: 8,
+ vers: 5,
+ is64: true,
+ }
+ ret, err := d.dwarf5Ranges(u, nil, 0x5fbd, 0xc, [][2]uint64{})
if err != nil {
t.Fatalf("could not read rnglist: %v", err)
}
diff --git a/src/debug/dwarf/entry.go b/src/debug/dwarf/entry.go
index bc05d7ef31..3fc73b8ead 100644
--- a/src/debug/dwarf/entry.go
+++ b/src/debug/dwarf/entry.go
@@ -423,6 +423,47 @@ func (b *buf) entry(cu *Entry, atab abbrevTable, ubase Offset, vers int) *Entry
Children: a.children,
Field: make([]Field, len(a.field)),
}
+
+ // If we are currently parsing the compilation unit,
+ // we can't evaluate Addrx or Strx until we've seen the
+ // relevant base entry.
+ type delayed struct {
+ idx int
+ off uint64
+ fmt format
+ }
+ var delay []delayed
+
+ resolveStrx := func(strBase, off uint64) string {
+ off += strBase
+ if uint64(int(off)) != off {
+ b.error("DW_FORM_strx offset out of range")
+ }
+
+ b1 := makeBuf(b.dwarf, b.format, "str_offsets", 0, b.dwarf.strOffsets)
+ b1.skip(int(off))
+ is64, _ := b.format.dwarf64()
+ if is64 {
+ off = b1.uint64()
+ } else {
+ off = uint64(b1.uint32())
+ }
+ if b1.err != nil {
+ b.err = b1.err
+ return ""
+ }
+ if uint64(int(off)) != off {
+ b.error("DW_FORM_strx indirect offset out of range")
+ }
+ b1 = makeBuf(b.dwarf, b.format, "str", 0, b.dwarf.str)
+ b1.skip(int(off))
+ val := b1.string()
+ if b1.err != nil {
+ b.err = b1.err
+ }
+ return val
+ }
+
for i := range e.Field {
e.Field[i].Attr = a.field[i].attr
e.Field[i].Class = a.field[i].class
@@ -467,10 +508,13 @@ func (b *buf) entry(cu *Entry, atab abbrevTable, ubase Offset, vers int) *Entry
var addrBase int64
if cu != nil {
addrBase, _ = cu.Val(AttrAddrBase).(int64)
+ } else if a.tag == TagCompileUnit {
+ delay = append(delay, delayed{i, off, formAddrx})
+ break
}
var err error
- val, err = b.dwarf.debugAddr(uint64(addrBase), off)
+ val, err = b.dwarf.debugAddr(b.format, uint64(addrBase), off)
if err != nil {
if b.err == nil {
b.err = err
@@ -611,38 +655,16 @@ func (b *buf) entry(cu *Entry, atab abbrevTable, ubase Offset, vers int) *Entry
// compilation unit. This won't work if the
// program uses Reader.Seek to skip over the
// unit. Not much we can do about that.
+ var strBase int64
if cu != nil {
- cuOff, ok := cu.Val(AttrStrOffsetsBase).(int64)
- if ok {
- off += uint64(cuOff)
- }
+ strBase, _ = cu.Val(AttrStrOffsetsBase).(int64)
+ } else if a.tag == TagCompileUnit {
+ delay = append(delay, delayed{i, off, formStrx})
+ break
}
- if uint64(int(off)) != off {
- b.error("DW_FORM_strx offset out of range")
- }
+ val = resolveStrx(uint64(strBase), off)
- b1 := makeBuf(b.dwarf, b.format, "str_offsets", 0, b.dwarf.strOffsets)
- b1.skip(int(off))
- if is64 {
- off = b1.uint64()
- } else {
- off = uint64(b1.uint32())
- }
- if b1.err != nil {
- b.err = b1.err
- return nil
- }
- if uint64(int(off)) != off {
- b.error("DW_FORM_strx indirect offset out of range")
- }
- b1 = makeBuf(b.dwarf, b.format, "str", 0, b.dwarf.str)
- b1.skip(int(off))
- val = b1.string()
- if b1.err != nil {
- b.err = b1.err
- return nil
- }
case formStrpSup:
is64, known := b.format.dwarf64()
if !known {
@@ -689,11 +711,32 @@ func (b *buf) entry(cu *Entry, atab abbrevTable, ubase Offset, vers int) *Entry
case formRnglistx:
val = b.uint()
}
+
e.Field[i].Val = val
}
if b.err != nil {
return nil
}
+
+ for _, del := range delay {
+ switch del.fmt {
+ case formAddrx:
+ addrBase, _ := e.Val(AttrAddrBase).(int64)
+ val, err := b.dwarf.debugAddr(b.format, uint64(addrBase), del.off)
+ if err != nil {
+ b.err = err
+ return nil
+ }
+ e.Field[del.idx].Val = val
+ case formStrx:
+ strBase, _ := e.Val(AttrStrOffsetsBase).(int64)
+ e.Field[del.idx].Val = resolveStrx(uint64(strBase), del.off)
+ if b.err != nil {
+ return nil
+ }
+ }
+ }
+
return e
}
@@ -877,6 +920,7 @@ func (r *Reader) SeekPC(pc uint64) (*Entry, error) {
r.err = nil
r.lastChildren = false
r.unit = unit
+ r.cu = nil
u := &r.d.unit[unit]
r.b = makeBuf(r.d, u, "info", u.off, u.data)
e, err := r.Next()
@@ -946,7 +990,7 @@ func (d *Data) Ranges(e *Entry) ([][2]uint64, error) {
if err != nil {
return nil, err
}
- return d.dwarf5Ranges(cu, base, ranges, ret)
+ return d.dwarf5Ranges(u, cu, base, ranges, ret)
case ClassRngList:
// TODO: support DW_FORM_rnglistx
@@ -1023,13 +1067,13 @@ func (d *Data) dwarf2Ranges(u *unit, base uint64, ranges int64, ret [][2]uint64)
// dwarf5Ranges interpets a debug_rnglists sequence, see DWARFv5 section
// 2.17.3 (page 53).
-func (d *Data) dwarf5Ranges(cu *Entry, base uint64, ranges int64, ret [][2]uint64) ([][2]uint64, error) {
+func (d *Data) dwarf5Ranges(u *unit, cu *Entry, base uint64, ranges int64, ret [][2]uint64) ([][2]uint64, error) {
var addrBase int64
if cu != nil {
addrBase, _ = cu.Val(AttrAddrBase).(int64)
}
- buf := makeBuf(d, d.rngLists, "rnglists", 0, d.rngLists.data)
+ buf := makeBuf(d, u, "rnglists", 0, d.rngLists)
buf.skip(int(ranges))
for {
opcode := buf.uint8()
@@ -1043,7 +1087,7 @@ func (d *Data) dwarf5Ranges(cu *Entry, base uint64, ranges int64, ret [][2]uint6
case rleBaseAddressx:
baseIdx := buf.uint()
var err error
- base, err = d.debugAddr(uint64(addrBase), baseIdx)
+ base, err = d.debugAddr(u, uint64(addrBase), baseIdx)
if err != nil {
return nil, err
}
@@ -1052,11 +1096,11 @@ func (d *Data) dwarf5Ranges(cu *Entry, base uint64, ranges int64, ret [][2]uint6
startIdx := buf.uint()
endIdx := buf.uint()
- start, err := d.debugAddr(uint64(addrBase), startIdx)
+ start, err := d.debugAddr(u, uint64(addrBase), startIdx)
if err != nil {
return nil, err
}
- end, err := d.debugAddr(uint64(addrBase), endIdx)
+ end, err := d.debugAddr(u, uint64(addrBase), endIdx)
if err != nil {
return nil, err
}
@@ -1065,7 +1109,7 @@ func (d *Data) dwarf5Ranges(cu *Entry, base uint64, ranges int64, ret [][2]uint6
case rleStartxLength:
startIdx := buf.uint()
len := buf.uint()
- start, err := d.debugAddr(uint64(addrBase), startIdx)
+ start, err := d.debugAddr(u, uint64(addrBase), startIdx)
if err != nil {
return nil, err
}
@@ -1093,19 +1137,18 @@ func (d *Data) dwarf5Ranges(cu *Entry, base uint64, ranges int64, ret [][2]uint6
}
// debugAddr returns the address at idx in debug_addr
-func (d *Data) debugAddr(addrBase, idx uint64) (uint64, error) {
- off := idx*uint64(d.addr.addrsize()) + addrBase
+func (d *Data) debugAddr(format dataFormat, addrBase, idx uint64) (uint64, error) {
+ off := idx*uint64(format.addrsize()) + addrBase
if uint64(int(off)) != off {
return 0, errors.New("offset out of range")
}
- b := makeBuf(d, d.addr, "addr", 0, d.addr.data)
+ b := makeBuf(d, format, "addr", 0, d.addr)
b.skip(int(off))
val := b.addr()
if b.err != nil {
return 0, b.err
}
-
return val, nil
}
diff --git a/src/debug/dwarf/entry_test.go b/src/debug/dwarf/entry_test.go
index 2e6ee048aa..b54f8b4f8d 100644
--- a/src/debug/dwarf/entry_test.go
+++ b/src/debug/dwarf/entry_test.go
@@ -55,6 +55,20 @@ func TestReaderSeek(t *testing.T) {
{0x400611, nil},
}
testRanges(t, "testdata/line-gcc.elf", want)
+
+ want = []wantRange{
+ {0x401122, [][2]uint64{{0x401122, 0x401166}}},
+ {0x401165, [][2]uint64{{0x401122, 0x401166}}},
+ {0x401166, [][2]uint64{{0x401166, 0x401179}}},
+ }
+ testRanges(t, "testdata/line-gcc-dwarf5.elf", want)
+
+ want = []wantRange{
+ {0x401130, [][2]uint64{{0x401130, 0x40117e}}},
+ {0x40117d, [][2]uint64{{0x401130, 0x40117e}}},
+ {0x40117e, nil},
+ }
+ testRanges(t, "testdata/line-clang-dwarf5.elf", want)
}
func TestRangesSection(t *testing.T) {
@@ -97,44 +111,72 @@ func testRanges(t *testing.T, name string, want []wantRange) {
}
func TestReaderRanges(t *testing.T) {
- d := elfData(t, "testdata/line-gcc.elf")
-
- subprograms := []struct {
+ type subprograms []struct {
name string
ranges [][2]uint64
+ }
+ tests := []struct {
+ filename string
+ subprograms subprograms
}{
- {"f1", [][2]uint64{{0x40059d, 0x4005e7}}},
- {"main", [][2]uint64{{0x4005e7, 0x400601}}},
- {"f2", [][2]uint64{{0x400601, 0x400611}}},
+ {
+ "testdata/line-gcc.elf",
+ subprograms{
+ {"f1", [][2]uint64{{0x40059d, 0x4005e7}}},
+ {"main", [][2]uint64{{0x4005e7, 0x400601}}},
+ {"f2", [][2]uint64{{0x400601, 0x400611}}},
+ },
+ },
+ {
+ "testdata/line-gcc-dwarf5.elf",
+ subprograms{
+ {"main", [][2]uint64{{0x401147, 0x401166}}},
+ {"f1", [][2]uint64{{0x401122, 0x401147}}},
+ {"f2", [][2]uint64{{0x401166, 0x401179}}},
+ },
+ },
+ {
+ "testdata/line-clang-dwarf5.elf",
+ subprograms{
+ {"main", [][2]uint64{{0x401130, 0x401144}}},
+ {"f1", [][2]uint64{{0x401150, 0x40117e}}},
+ {"f2", [][2]uint64{{0x401180, 0x401197}}},
+ },
+ },
}
- r := d.Reader()
- i := 0
- for entry, err := r.Next(); entry != nil && err == nil; entry, err = r.Next() {
- if entry.Tag != TagSubprogram {
- continue
+ for _, test := range tests {
+ d := elfData(t, test.filename)
+ subprograms := test.subprograms
+
+ r := d.Reader()
+ i := 0
+ for entry, err := r.Next(); entry != nil && err == nil; entry, err = r.Next() {
+ if entry.Tag != TagSubprogram {
+ continue
+ }
+
+ if i > len(subprograms) {
+ t.Fatalf("%s: too many subprograms (expected at most %d)", test.filename, i)
+ }
+
+ if got := entry.Val(AttrName).(string); got != subprograms[i].name {
+ t.Errorf("%s: subprogram %d name is %s, expected %s", test.filename, i, got, subprograms[i].name)
+ }
+ ranges, err := d.Ranges(entry)
+ if err != nil {
+ t.Errorf("%s: subprogram %d: %v", test.filename, i, err)
+ continue
+ }
+ if !reflect.DeepEqual(ranges, subprograms[i].ranges) {
+ t.Errorf("%s: subprogram %d ranges are %x, expected %x", test.filename, i, ranges, subprograms[i].ranges)
+ }
+ i++
}
- if i > len(subprograms) {
- t.Fatalf("too many subprograms (expected at most %d)", i)
+ if i < len(subprograms) {
+ t.Errorf("%s: saw only %d subprograms, expected %d", test.filename, i, len(subprograms))
}
-
- if got := entry.Val(AttrName).(string); got != subprograms[i].name {
- t.Errorf("subprogram %d name is %s, expected %s", i, got, subprograms[i].name)
- }
- ranges, err := d.Ranges(entry)
- if err != nil {
- t.Errorf("subprogram %d: %v", i, err)
- continue
- }
- if !reflect.DeepEqual(ranges, subprograms[i].ranges) {
- t.Errorf("subprogram %d ranges are %x, expected %x", i, ranges, subprograms[i].ranges)
- }
- i++
- }
-
- if i < len(subprograms) {
- t.Errorf("saw only %d subprograms, expected %d", i, len(subprograms))
}
}
diff --git a/src/debug/dwarf/open.go b/src/debug/dwarf/open.go
index 617b8c56dd..e94103a1d7 100644
--- a/src/debug/dwarf/open.go
+++ b/src/debug/dwarf/open.go
@@ -26,10 +26,10 @@ type Data struct {
str []byte
// New sections added in DWARF 5.
- addr *debugAddr
+ addr []byte
lineStr []byte
strOffsets []byte
- rngLists *rngLists
+ rngLists []byte
// parsed data
abbrevCache map[uint64]abbrevTable
@@ -40,21 +40,6 @@ type Data struct {
unit []unit
}
-// rngLists represents the contents of a debug_rnglists section (DWARFv5).
-type rngLists struct {
- is64 bool
- asize uint8
- data []byte
- ver uint16
-}
-
-// debugAddr represents the contents of a debug_addr section (DWARFv5).
-type debugAddr struct {
- is64 bool
- asize uint8
- data []byte
-}
-
var errSegmentSelector = errors.New("non-zero segment_selector size not supported")
// New returns a new Data object initialized from the given parameters.
@@ -132,76 +117,14 @@ func (d *Data) AddSection(name string, contents []byte) error {
var err error
switch name {
case ".debug_addr":
- d.addr, err = d.parseAddrHeader(contents)
+ d.addr = contents
case ".debug_line_str":
d.lineStr = contents
case ".debug_str_offsets":
d.strOffsets = contents
case ".debug_rnglists":
- d.rngLists, err = d.parseRngListsHeader(contents)
+ d.rngLists = contents
}
// Just ignore names that we don't yet support.
return err
}
-
-// parseRngListsHeader reads the header of a debug_rnglists section, see
-// DWARFv5 section 7.28 (page 242).
-func (d *Data) parseRngListsHeader(bytes []byte) (*rngLists, error) {
- rngLists := &rngLists{data: bytes}
-
- buf := makeBuf(d, unknownFormat{}, "rnglists", 0, bytes)
- _, rngLists.is64 = buf.unitLength()
-
- rngLists.ver = buf.uint16() // version
-
- rngLists.asize = buf.uint8()
- segsize := buf.uint8()
- if segsize != 0 {
- return nil, errSegmentSelector
- }
-
- // Header fields not read: offset_entry_count, offset table
-
- return rngLists, nil
-}
-
-func (rngLists *rngLists) version() int {
- return int(rngLists.ver)
-}
-
-func (rngLists *rngLists) dwarf64() (bool, bool) {
- return rngLists.is64, true
-}
-
-func (rngLists *rngLists) addrsize() int {
- return int(rngLists.asize)
-}
-
-// parseAddrHeader reads the header of a debug_addr section, see DWARFv5
-// section 7.27 (page 241).
-func (d *Data) parseAddrHeader(bytes []byte) (*debugAddr, error) {
- addr := &debugAddr{data: bytes}
-
- buf := makeBuf(d, unknownFormat{}, "addr", 0, bytes)
- _, addr.is64 = buf.unitLength()
-
- addr.asize = buf.uint8()
- segsize := buf.uint8()
- if segsize != 0 {
- return nil, errSegmentSelector
- }
-
- return addr, nil
-}
-
-func (addr *debugAddr) version() int {
- return 5
-}
-
-func (addr *debugAddr) dwarf64() (bool, bool) {
- return addr.is64, true
-}
-
-func (addr *debugAddr) addrsize() int {
- return int(addr.asize)
-}
diff --git a/src/debug/dwarf/testdata/line-clang-dwarf5.elf b/src/debug/dwarf/testdata/line-clang-dwarf5.elf
new file mode 100644
index 0000000000..7b80c9c5da
Binary files /dev/null and b/src/debug/dwarf/testdata/line-clang-dwarf5.elf differ
diff --git a/src/debug/dwarf/testdata/line-gcc-dwarf5.elf b/src/debug/dwarf/testdata/line-gcc-dwarf5.elf
new file mode 100644
index 0000000000..34ce17cc42
Binary files /dev/null and b/src/debug/dwarf/testdata/line-gcc-dwarf5.elf differ
diff --git a/src/go.mod b/src/go.mod
index 1fcd02f9ba..4ae14eea5c 100644
--- a/src/go.mod
+++ b/src/go.mod
@@ -4,7 +4,7 @@ go 1.16
require (
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
- golang.org/x/net v0.0.0-20201029221708-28c70e62bb1d
+ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11
golang.org/x/sys v0.0.0-20201204225414-ed752295db88 // indirect
golang.org/x/text v0.3.4 // indirect
)
diff --git a/src/go.sum b/src/go.sum
index 913e6ea68d..5586aa9a4e 100644
--- a/src/go.sum
+++ b/src/go.sum
@@ -1,15 +1,15 @@
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E=
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20201029221708-28c70e62bb1d h1:dOiJ2n2cMwGLce/74I/QHMbnpk5GfY7InR8rczoMqRM=
-golang.org/x/net v0.0.0-20201029221708-28c70e62bb1d/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201209123823-ac852fbbde11 h1:lwlPPsmjDKK0J6eG6xDWd5XPehI0R024zxjDnw3esPA=
+golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88 h1:KmZPnMocC93w341XZp26yTJg8Za7lhb2KhkYmixoeso=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go
index 56942c0fd2..aa651af718 100644
--- a/src/go/build/deps_test.go
+++ b/src/go/build/deps_test.go
@@ -10,6 +10,7 @@ package build
import (
"bytes"
"fmt"
+ "go/token"
"internal/testenv"
"io/fs"
"os"
@@ -162,6 +163,9 @@ var depsRules = `
< os
< os/signal;
+ io/fs
+ < embed;
+
unicode, fmt !< os, os/signal;
os/signal, STR
@@ -602,6 +606,7 @@ func findImports(pkg string) ([]string, error) {
}
var imports []string
var haveImport = map[string]bool{}
+ fset := token.NewFileSet()
for _, file := range files {
name := file.Name()
if name == "slice_go14.go" || name == "slice_go18.go" {
@@ -611,8 +616,10 @@ func findImports(pkg string) ([]string, error) {
if !strings.HasSuffix(name, ".go") || strings.HasSuffix(name, "_test.go") {
continue
}
- var info fileInfo
- info.name = filepath.Join(dir, name)
+ info := fileInfo{
+ name: filepath.Join(dir, name),
+ fset: fset,
+ }
f, err := os.Open(info.name)
if err != nil {
return nil, err
@@ -840,3 +847,22 @@ func TestStdlibLowercase(t *testing.T) {
}
}
}
+
+// TestFindImports tests that findImports works. See #43249.
+func TestFindImports(t *testing.T) {
+ imports, err := findImports("go/build")
+ if err != nil {
+ t.Fatal(err)
+ }
+ t.Logf("go/build imports %q", imports)
+ want := []string{"bytes", "os", "path/filepath", "strings"}
+wantLoop:
+ for _, w := range want {
+ for _, imp := range imports {
+ if imp == w {
+ continue wantLoop
+ }
+ }
+ t.Errorf("expected to find %q in import list", w)
+ }
+}
diff --git a/src/go/types/call.go b/src/go/types/call.go
index 992598d08c..6765b17bf3 100644
--- a/src/go/types/call.go
+++ b/src/go/types/call.go
@@ -33,6 +33,10 @@ func (check *Checker) call(x *operand, e *ast.CallExpr) exprKind {
case 1:
check.expr(x, e.Args[0])
if x.mode != invalid {
+ if e.Ellipsis.IsValid() {
+ check.errorf(e.Args[0], _BadDotDotDotSyntax, "invalid use of ... in conversion to %s", T)
+ break
+ }
check.conversion(x, T)
}
default:
diff --git a/src/go/types/errorcodes.go b/src/go/types/errorcodes.go
index e4c8311d62..c01a12c346 100644
--- a/src/go/types/errorcodes.go
+++ b/src/go/types/errorcodes.go
@@ -1207,6 +1207,16 @@ const (
// }
_InvalidTypeSwitch
+ // _InvalidExprSwitch occurs when a switch expression is not comparable.
+ //
+ // Example:
+ // func _() {
+ // var a struct{ _ func() }
+ // switch a /* ERROR cannot switch on a */ {
+ // }
+ // }
+ _InvalidExprSwitch
+
/* control flow > select */
// _InvalidSelectCase occurs when a select case is not a channel send or
diff --git a/src/go/types/fixedbugs/issue43110.src b/src/go/types/fixedbugs/issue43110.src
new file mode 100644
index 0000000000..4a46945239
--- /dev/null
+++ b/src/go/types/fixedbugs/issue43110.src
@@ -0,0 +1,43 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type P *struct{}
+
+func _() {
+ // want an error even if the switch is empty
+ var a struct{ _ func() }
+ switch a /* ERROR cannot switch on a */ {
+ }
+
+ switch a /* ERROR cannot switch on a */ {
+ case a: // no follow-on error here
+ }
+
+ // this is ok because f can be compared to nil
+ var f func()
+ switch f {
+ }
+
+ switch f {
+ case nil:
+ }
+
+ switch (func())(nil) {
+ case nil:
+ }
+
+ switch (func())(nil) {
+ case f /* ERROR cannot compare */ :
+ }
+
+ switch nil /* ERROR use of untyped nil in switch expression */ {
+ }
+
+ // this is ok
+ switch P(nil) {
+ case P(nil):
+ }
+}
diff --git a/src/go/types/fixedbugs/issue43124.src b/src/go/types/fixedbugs/issue43124.src
new file mode 100644
index 0000000000..f429f74a74
--- /dev/null
+++ b/src/go/types/fixedbugs/issue43124.src
@@ -0,0 +1,16 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+var _ = int(0 /* ERROR invalid use of \.\.\. in conversion to int */ ...)
+
+// test case from issue
+
+type M []string
+
+var (
+ x = []string{"a", "b"}
+ _ = M(x /* ERROR invalid use of \.\.\. in conversion to M */ ...)
+)
diff --git a/src/go/types/stmt.go b/src/go/types/stmt.go
index 7b3f322ced..d88e47170c 100644
--- a/src/go/types/stmt.go
+++ b/src/go/types/stmt.go
@@ -528,6 +528,10 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
// By checking assignment of x to an invisible temporary
// (as a compiler would), we get all the relevant checks.
check.assignment(&x, nil, "switch expression")
+ if x.mode != invalid && !Comparable(x.typ) && !hasNil(x.typ) {
+ check.errorf(&x, _InvalidExprSwitch, "cannot switch on %s (%s is not comparable)", &x, x.typ)
+ x.mode = invalid
+ }
} else {
// spec: "A missing switch expression is
// equivalent to the boolean value true."
diff --git a/src/html/template/exec_test.go b/src/html/template/exec_test.go
index 232945a0bb..eb00824260 100644
--- a/src/html/template/exec_test.go
+++ b/src/html/template/exec_test.go
@@ -14,6 +14,7 @@ import (
"io"
"reflect"
"strings"
+ "sync"
"testing"
"text/template"
)
@@ -1706,3 +1707,72 @@ func TestIssue31810(t *testing.T) {
t.Errorf("%s got %q, expected %q", textCall, b.String(), "result")
}
}
+
+// Issue 39807. There was a race applying escapeTemplate.
+
+const raceText = `
+{{- define "jstempl" -}}
+var v = "v";
+{{- end -}}
+
+`
+
+func TestEscapeRace(t *testing.T) {
+ tmpl := New("")
+ _, err := tmpl.New("templ.html").Parse(raceText)
+ if err != nil {
+ t.Fatal(err)
+ }
+ const count = 20
+ for i := 0; i < count; i++ {
+ _, err := tmpl.New(fmt.Sprintf("x%d.html", i)).Parse(`{{ template "templ.html" .}}`)
+ if err != nil {
+ t.Fatal(err)
+ }
+ }
+
+ var wg sync.WaitGroup
+ for i := 0; i < 10; i++ {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ for j := 0; j < count; j++ {
+ sub := tmpl.Lookup(fmt.Sprintf("x%d.html", j))
+ if err := sub.Execute(io.Discard, nil); err != nil {
+ t.Error(err)
+ }
+ }
+ }()
+ }
+ wg.Wait()
+}
+
+func TestRecursiveExecute(t *testing.T) {
+ tmpl := New("")
+
+ recur := func() (HTML, error) {
+ var sb strings.Builder
+ if err := tmpl.ExecuteTemplate(&sb, "subroutine", nil); err != nil {
+ t.Fatal(err)
+ }
+ return HTML(sb.String()), nil
+ }
+
+ m := FuncMap{
+ "recur": recur,
+ }
+
+ top, err := tmpl.New("x.html").Funcs(m).Parse(`{{recur}}`)
+ if err != nil {
+ t.Fatal(err)
+ }
+ _, err = tmpl.New("subroutine").Parse(``)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err := top.Execute(io.Discard, nil); err != nil {
+ t.Fatal(err)
+ }
+}
diff --git a/src/html/template/template.go b/src/html/template/template.go
index 69312d36fd..09d71d43e2 100644
--- a/src/html/template/template.go
+++ b/src/html/template/template.go
@@ -11,6 +11,7 @@ import (
"os"
"path"
"path/filepath"
+ "reflect"
"sync"
"text/template"
"text/template/parse"
@@ -26,7 +27,9 @@ type Template struct {
// template's in sync.
text *template.Template
// The underlying template's parse tree, updated to be HTML-safe.
- Tree *parse.Tree
+ Tree *parse.Tree
+ // The original functions, before wrapping.
+ funcMap FuncMap
*nameSpace // common to all associated templates
}
@@ -35,7 +38,7 @@ var escapeOK = fmt.Errorf("template escaped correctly")
// nameSpace is the data structure shared by all templates in an association.
type nameSpace struct {
- mu sync.Mutex
+ mu sync.RWMutex
set map[string]*Template
escaped bool
esc escaper
@@ -45,8 +48,8 @@ type nameSpace struct {
// itself.
func (t *Template) Templates() []*Template {
ns := t.nameSpace
- ns.mu.Lock()
- defer ns.mu.Unlock()
+ ns.mu.RLock()
+ defer ns.mu.RUnlock()
// Return a slice so we don't expose the map.
m := make([]*Template, 0, len(ns.set))
for _, v := range ns.set {
@@ -84,8 +87,8 @@ func (t *Template) checkCanParse() error {
if t == nil {
return nil
}
- t.nameSpace.mu.Lock()
- defer t.nameSpace.mu.Unlock()
+ t.nameSpace.mu.RLock()
+ defer t.nameSpace.mu.RUnlock()
if t.nameSpace.escaped {
return fmt.Errorf("html/template: cannot Parse after Execute")
}
@@ -94,6 +97,16 @@ func (t *Template) checkCanParse() error {
// escape escapes all associated templates.
func (t *Template) escape() error {
+ t.nameSpace.mu.RLock()
+ escapeErr := t.escapeErr
+ t.nameSpace.mu.RUnlock()
+ if escapeErr != nil {
+ if escapeErr == escapeOK {
+ return nil
+ }
+ return escapeErr
+ }
+
t.nameSpace.mu.Lock()
defer t.nameSpace.mu.Unlock()
t.nameSpace.escaped = true
@@ -121,6 +134,8 @@ func (t *Template) Execute(wr io.Writer, data interface{}) error {
if err := t.escape(); err != nil {
return err
}
+ t.nameSpace.mu.RLock()
+ defer t.nameSpace.mu.RUnlock()
return t.text.Execute(wr, data)
}
@@ -136,6 +151,8 @@ func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{})
if err != nil {
return err
}
+ t.nameSpace.mu.RLock()
+ defer t.nameSpace.mu.RUnlock()
return tmpl.text.Execute(wr, data)
}
@@ -143,13 +160,27 @@ func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{})
// is escaped, or returns an error if it cannot be. It returns the named
// template.
func (t *Template) lookupAndEscapeTemplate(name string) (tmpl *Template, err error) {
- t.nameSpace.mu.Lock()
- defer t.nameSpace.mu.Unlock()
- t.nameSpace.escaped = true
+ t.nameSpace.mu.RLock()
tmpl = t.set[name]
+ var escapeErr error
+ if tmpl != nil {
+ escapeErr = tmpl.escapeErr
+ }
+ t.nameSpace.mu.RUnlock()
+
if tmpl == nil {
return nil, fmt.Errorf("html/template: %q is undefined", name)
}
+ if escapeErr != nil {
+ if escapeErr != escapeOK {
+ return nil, escapeErr
+ }
+ return tmpl, nil
+ }
+
+ t.nameSpace.mu.Lock()
+ defer t.nameSpace.mu.Unlock()
+ t.nameSpace.escaped = true
if tmpl.escapeErr != nil && tmpl.escapeErr != escapeOK {
return nil, tmpl.escapeErr
}
@@ -229,6 +260,7 @@ func (t *Template) AddParseTree(name string, tree *parse.Tree) (*Template, error
nil,
text,
text.Tree,
+ nil,
t.nameSpace,
}
t.set[name] = ret
@@ -259,8 +291,10 @@ func (t *Template) Clone() (*Template, error) {
nil,
textClone,
textClone.Tree,
+ t.funcMap,
ns,
}
+ ret.wrapFuncs()
ret.set[ret.Name()] = ret
for _, x := range textClone.Templates() {
name := x.Name()
@@ -269,12 +303,15 @@ func (t *Template) Clone() (*Template, error) {
return nil, fmt.Errorf("html/template: cannot Clone %q after it has executed", t.Name())
}
x.Tree = x.Tree.Copy()
- ret.set[name] = &Template{
+ tc := &Template{
nil,
x,
x.Tree,
+ src.funcMap,
ret.nameSpace,
}
+ tc.wrapFuncs()
+ ret.set[name] = tc
}
// Return the template associated with the name of this template.
return ret.set[ret.Name()], nil
@@ -288,6 +325,7 @@ func New(name string) *Template {
nil,
template.New(name),
nil,
+ nil,
ns,
}
tmpl.set[name] = tmpl
@@ -313,6 +351,7 @@ func (t *Template) new(name string) *Template {
nil,
t.text.New(name),
nil,
+ nil,
t.nameSpace,
}
if existing, ok := tmpl.set[name]; ok {
@@ -343,10 +382,35 @@ type FuncMap map[string]interface{}
// type. However, it is legal to overwrite elements of the map. The return
// value is the template, so calls can be chained.
func (t *Template) Funcs(funcMap FuncMap) *Template {
- t.text.Funcs(template.FuncMap(funcMap))
+ t.funcMap = funcMap
+ t.wrapFuncs()
return t
}
+// wrapFuncs records the functions with text/template. We wrap them to
+// unlock the nameSpace. See TestRecursiveExecute for a test case.
+func (t *Template) wrapFuncs() {
+ if len(t.funcMap) == 0 {
+ return
+ }
+ tfuncs := make(template.FuncMap, len(t.funcMap))
+ for name, fn := range t.funcMap {
+ fnv := reflect.ValueOf(fn)
+ wrapper := func(args []reflect.Value) []reflect.Value {
+ t.nameSpace.mu.RUnlock()
+ defer t.nameSpace.mu.RLock()
+ if fnv.Type().IsVariadic() {
+ return fnv.CallSlice(args)
+ } else {
+ return fnv.Call(args)
+ }
+ }
+ wrapped := reflect.MakeFunc(fnv.Type(), wrapper)
+ tfuncs[name] = wrapped.Interface()
+ }
+ t.text.Funcs(tfuncs)
+}
+
// Delims sets the action delimiters to the specified strings, to be used in
// subsequent calls to Parse, ParseFiles, or ParseGlob. Nested template
// definitions will inherit the settings. An empty delimiter stands for the
@@ -360,8 +424,8 @@ func (t *Template) Delims(left, right string) *Template {
// Lookup returns the template with the given name that is associated with t,
// or nil if there is no such template.
func (t *Template) Lookup(name string) *Template {
- t.nameSpace.mu.Lock()
- defer t.nameSpace.mu.Unlock()
+ t.nameSpace.mu.RLock()
+ defer t.nameSpace.mu.RUnlock()
return t.set[name]
}
diff --git a/src/io/fs/fs.go b/src/io/fs/fs.go
index d9f89fc6ee..b691a86049 100644
--- a/src/io/fs/fs.go
+++ b/src/io/fs/fs.go
@@ -16,8 +16,7 @@ import (
//
// The FS interface is the minimum implementation required of the file system.
// A file system may implement additional interfaces,
-// such as fsutil.ReadFileFS, to provide additional or optimized functionality.
-// See io/fsutil for details.
+// such as ReadFileFS, to provide additional or optimized functionality.
type FS interface {
// Open opens the named file.
//
diff --git a/src/math/big/nat_test.go b/src/math/big/nat_test.go
index 89e913fc16..0850818932 100644
--- a/src/math/big/nat_test.go
+++ b/src/math/big/nat_test.go
@@ -804,3 +804,13 @@ func TestIssue37499(t *testing.T) {
t.Fatalf("incorrect quotient: %s", s)
}
}
+
+// TestIssue42552 triggers an edge case of recursive division
+// where the first division loop is never entered, and correcting
+// the remainder takes exactly two iterations in the final loop.
+func TestIssue42552(t *testing.T) {
+ u := natFromString("0xc23b166884c3869092a520eceedeced2b00847bd256c9cf3b2c5e2227c15bd5e6ee7ef8a2f49236ad0eedf2c8a3b453cf6e0706f64285c526b372c4b1321245519d430540804a50b7ca8b6f1b34a2ec05cdbc24de7599af112d3e3c8db347e8799fe70f16e43c6566ba3aeb169463a3ecc486172deb2d9b80a3699c776e44fef20036bd946f1b4d054dd88a2c1aeb986199b0b2b7e58c42288824b74934d112fe1fc06e06b4d99fe1c5e725946b23210521e209cd507cce90b5f39a523f27e861f9e232aee50c3f585208b4573dcc0b897b6177f2ba20254fd5c50a033e849dee1b3a93bd2dc44ba8ca836cab2c2ae50e50b126284524fa0187af28628ff0face68d87709200329db1392852c8b8963fbe3d05fb1efe19f0ed5ca9fadc2f96f82187c24bb2512b2e85a66333a7e176605695211e1c8e0b9b9e82813e50654964945b1e1e66a90840396c7d10e23e47f364d2d3f660fa54598e18d1ca2ea4fe4f35a40a11f69f201c80b48eaee3e2e9b0eda63decf92bec08a70f731587d4ed0f218d5929285c8b2ccbc497e20db42de73885191fa453350335990184d8df805072f958d5354debda38f5421effaaafd6cb9b721ace74be0892d77679f62a4a126697cd35797f6858193da4ba1770c06aea2e5c59ec04b8ea26749e61b72ecdde403f3bc7e5e546cd799578cc939fa676dfd5e648576d4a06cbadb028adc2c0b461f145b2321f42e5e0f3b4fb898ecd461df07a6f5154067787bf74b5cc5c03704a1ce47494961931f0263b0aac32505102595957531a2de69dd71aac51f8a49902f81f21283dbe8e21e01e5d82517868826f86acf338d935aa6b4d5a25c8d540389b277dd9d64569d68baf0f71bd03dba45b92a7fc052601d1bd011a2fc6790a23f97c6fa5caeea040ab86841f268d39ce4f7caf01069df78bba098e04366492f0c2ac24f1bf16828752765fa523c9a4d42b71109d123e6be8c7b1ab3ccf8ea03404075fe1a9596f1bba1d267f9a7879ceece514818316c9c0583469d2367831fc42b517ea028a28df7c18d783d16ea2436cee2b15d52db68b5dfdee6b4d26f0905f9b030c911a04d078923a4136afea96eed6874462a482917353264cc9bee298f167ac65a6db4e4eda88044b39cc0b33183843eaa946564a00c3a0ab661f2c915e70bf0bb65bfbb6fa2eea20aed16bf2c1a1d00ec55fb4ff2f76b8e462ea70c19efa579c9ee78194b86708fdae66a9ce6e2cf3d366037798cfb50277ba6d2fd4866361022fd788ab7735b40b8b61d55e32243e06719e53992e9ac16c9c4b6e6933635c3c47c8f7e73e17dd54d0dd8aeba5d76de46894e7b3f9d3ec25ad78ee82297ba69905ea0fa094b8667faa2b8885e2187b3da80268aa1164761d7b0d6de206b676777348152b8ae1d4afed753bc63c739a5ca8ce7afb2b241a226bd9e502baba391b5b13f5054f070b65a9cf3a67063bfaa803ba390732cd03888f664023f888741d04d564e0b5674b0a183ace81452001b3fbb4214c77d42ca75376742c471e58f67307726d56a1032bd236610cbcbcd03d0d7a452900136897dc55bb3ce959d10d4e6a10fb635006bd8c41cd9ded2d3dfdd8f2e229590324a7370cb2124210b2330f4c56155caa09a2564932ceded8d92c79664dcdeb87faad7d3da006cc2ea267ee3df41e9677789cc5a8cc3b83add6491561b3047919e0648b1b2e97d7ad6f6c2aa80cab8e9ae10e1f75b1fdd0246151af709d259a6a0ed0b26bd711024965ecad7c41387de45443defce53f66612948694a6032279131c257119ed876a8e805dfb49576ef5c563574115ee87050d92d191bc761ef51d966918e2ef925639400069e3959d8fe19f36136e947ff430bf74e71da0aa5923b00000000")
+ v := natFromString("0x838332321d443a3d30373d47301d47073847473a383d3030f25b3d3d3e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e00000000000000000041603038331c3d32f5303441e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e01c0a5459bfc7b9be9fcbb9d2383840464319434707303030f43a32f53034411c0a5459413820878787878787878787878787878787878787878787878787878787878787878787870630303a3a30334036605b923a6101f83638413943413960204337602043323801526040523241846038414143015238604060328452413841413638523c0240384141364036605b923a6101f83638413943413960204334602043323801526040523241846038414143015238604060328452413841413638523c02403841413638433030f25a8b83838383838383838383838383838383837d838383ffffffffffffffff838383838383838383000000000000000000030000007d26e27c7c8b83838383838383838383838383838383837d838383ffffffffffffffff83838383838383838383838383838383838383838383435960f535073030f3343200000000000000011881301938343030fa398383300000002300000000000000000000f11af4600c845252904141364138383c60406032414443095238010241414303364443434132305b595a15434160b042385341ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff47476043410536613603593a6005411c437405fcfcfcfcfcfcfc0000000000005a3b075815054359000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
+ q := nat(nil).make(16)
+ q.div(q, u, v)
+}
diff --git a/src/net/conn_test.go b/src/net/conn_test.go
index 6854898da2..771cabcd3c 100644
--- a/src/net/conn_test.go
+++ b/src/net/conn_test.go
@@ -32,7 +32,7 @@ func TestConnAndListener(t *testing.T) {
}
defer ls.teardown()
ch := make(chan error, 1)
- handler := func(ls *localServer, ln Listener) { transponder(ln, ch) }
+ handler := func(ls *localServer, ln Listener) { ls.transponder(ln, ch) }
if err := ls.buildup(handler); err != nil {
t.Fatal(err)
}
diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go
index e52903ffe9..6bef310feb 100644
--- a/src/net/http/h2_bundle.go
+++ b/src/net/http/h2_bundle.go
@@ -7651,6 +7651,9 @@ func (cc *http2ClientConn) roundTrip(req *Request) (res *Response, gotErrAfterRe
// we can keep it.
bodyWriter.cancel()
cs.abortRequestBodyWrite(http2errStopReqBodyWrite)
+ if hasBody && !bodyWritten {
+ <-bodyWriter.resc
+ }
}
if re.err != nil {
cc.forgetStreamID(cs.ID)
@@ -7671,6 +7674,7 @@ func (cc *http2ClientConn) roundTrip(req *Request) (res *Response, gotErrAfterRe
} else {
bodyWriter.cancel()
cs.abortRequestBodyWrite(http2errStopReqBodyWriteAndCancel)
+ <-bodyWriter.resc
}
cc.forgetStreamID(cs.ID)
return nil, cs.getStartedWrite(), http2errTimeout
@@ -7680,6 +7684,7 @@ func (cc *http2ClientConn) roundTrip(req *Request) (res *Response, gotErrAfterRe
} else {
bodyWriter.cancel()
cs.abortRequestBodyWrite(http2errStopReqBodyWriteAndCancel)
+ <-bodyWriter.resc
}
cc.forgetStreamID(cs.ID)
return nil, cs.getStartedWrite(), ctx.Err()
@@ -7689,6 +7694,7 @@ func (cc *http2ClientConn) roundTrip(req *Request) (res *Response, gotErrAfterRe
} else {
bodyWriter.cancel()
cs.abortRequestBodyWrite(http2errStopReqBodyWriteAndCancel)
+ <-bodyWriter.resc
}
cc.forgetStreamID(cs.ID)
return nil, cs.getStartedWrite(), http2errRequestCanceled
@@ -7698,6 +7704,7 @@ func (cc *http2ClientConn) roundTrip(req *Request) (res *Response, gotErrAfterRe
// forgetStreamID.
return nil, cs.getStartedWrite(), cs.resetErr
case err := <-bodyWriter.resc:
+ bodyWritten = true
// Prefer the read loop's response, if available. Issue 16102.
select {
case re := <-readLoopResCh:
@@ -7708,7 +7715,6 @@ func (cc *http2ClientConn) roundTrip(req *Request) (res *Response, gotErrAfterRe
cc.forgetStreamID(cs.ID)
return nil, cs.getStartedWrite(), err
}
- bodyWritten = true
if d := cc.responseHeaderTimeout(); d != 0 {
timer := time.NewTimer(d)
defer timer.Stop()
@@ -9130,7 +9136,9 @@ func (t *http2Transport) getBodyWriterState(cs *http2clientStream, body io.Reade
func (s http2bodyWriterState) cancel() {
if s.timer != nil {
- s.timer.Stop()
+ if s.timer.Stop() {
+ s.resc <- nil
+ }
}
}
diff --git a/src/net/http/pprof/pprof.go b/src/net/http/pprof/pprof.go
index 2bfcfb9545..5389a388c1 100644
--- a/src/net/http/pprof/pprof.go
+++ b/src/net/http/pprof/pprof.go
@@ -91,7 +91,7 @@ func init() {
func Cmdline(w http.ResponseWriter, r *http.Request) {
w.Header().Set("X-Content-Type-Options", "nosniff")
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
- fmt.Fprintf(w, strings.Join(os.Args, "\x00"))
+ fmt.Fprint(w, strings.Join(os.Args, "\x00"))
}
func sleep(r *http.Request, d time.Duration) {
diff --git a/src/net/http/response.go b/src/net/http/response.go
index b95abae646..b8985da3c8 100644
--- a/src/net/http/response.go
+++ b/src/net/http/response.go
@@ -361,7 +361,12 @@ func (r *Response) isProtocolSwitch() bool {
// isProtocolSwitchResponse reports whether the response code and
// response header indicate a successful protocol upgrade response.
func isProtocolSwitchResponse(code int, h Header) bool {
- return code == StatusSwitchingProtocols &&
- h.Get("Upgrade") != "" &&
+ return code == StatusSwitchingProtocols && isProtocolSwitchHeader(h)
+}
+
+// isProtocolSwitchHeader reports whether the request or response header
+// is for a protocol switch.
+func isProtocolSwitchHeader(h Header) bool {
+ return h.Get("Upgrade") != "" &&
httpguts.HeaderValuesContainsToken(h["Connection"], "Upgrade")
}
diff --git a/src/net/http/serve_test.go b/src/net/http/serve_test.go
index b1bf8e6c5e..95e6bf4adb 100644
--- a/src/net/http/serve_test.go
+++ b/src/net/http/serve_test.go
@@ -6481,6 +6481,10 @@ func TestDisableKeepAliveUpgrade(t *testing.T) {
}
defer resp.Body.Close()
+ if resp.StatusCode != StatusSwitchingProtocols {
+ t.Fatalf("unexpected status code: %v", resp.StatusCode)
+ }
+
rwc, ok := resp.Body.(io.ReadWriteCloser)
if !ok {
t.Fatalf("Response.Body is not a io.ReadWriteCloser: %T", resp.Body)
diff --git a/src/net/http/server.go b/src/net/http/server.go
index 102e893d5f..ad99741177 100644
--- a/src/net/http/server.go
+++ b/src/net/http/server.go
@@ -1837,7 +1837,7 @@ func (c *conn) serve(ctx context.Context) {
if d := c.server.WriteTimeout; d != 0 {
c.rwc.SetWriteDeadline(time.Now().Add(d))
}
- if err := tlsConn.HandshakeContext(ctx); err != nil {
+ if err := tlsConn.Handshake(); err != nil {
// If the handshake failed due to the client not speaking
// TLS, assume they're speaking plaintext HTTP and write a
// 400 response on the TLS conn's underlying net.Conn.
diff --git a/src/net/http/transport.go b/src/net/http/transport.go
index a5830703af..0aa48273dd 100644
--- a/src/net/http/transport.go
+++ b/src/net/http/transport.go
@@ -1505,7 +1505,7 @@ func (t *Transport) decConnsPerHost(key connectMethodKey) {
// Add TLS to a persistent connection, i.e. negotiate a TLS session. If pconn is already a TLS
// tunnel, this function establishes a nested TLS session inside the encrypted channel.
// The remote endpoint's name may be overridden by TLSClientConfig.ServerName.
-func (pconn *persistConn) addTLS(ctx context.Context, name string, trace *httptrace.ClientTrace) error {
+func (pconn *persistConn) addTLS(name string, trace *httptrace.ClientTrace) error {
// Initiate TLS and check remote host name against certificate.
cfg := cloneTLSConfig(pconn.t.TLSClientConfig)
if cfg.ServerName == "" {
@@ -1527,7 +1527,7 @@ func (pconn *persistConn) addTLS(ctx context.Context, name string, trace *httptr
if trace != nil && trace.TLSHandshakeStart != nil {
trace.TLSHandshakeStart()
}
- err := tlsConn.HandshakeContext(ctx)
+ err := tlsConn.Handshake()
if timer != nil {
timer.Stop()
}
@@ -1583,7 +1583,7 @@ func (t *Transport) dialConn(ctx context.Context, cm connectMethod) (pconn *pers
if trace != nil && trace.TLSHandshakeStart != nil {
trace.TLSHandshakeStart()
}
- if err := tc.HandshakeContext(ctx); err != nil {
+ if err := tc.Handshake(); err != nil {
go pconn.conn.Close()
if trace != nil && trace.TLSHandshakeDone != nil {
trace.TLSHandshakeDone(tls.ConnectionState{}, err)
@@ -1607,7 +1607,7 @@ func (t *Transport) dialConn(ctx context.Context, cm connectMethod) (pconn *pers
if firstTLSHost, _, err = net.SplitHostPort(cm.addr()); err != nil {
return nil, wrapErr(err)
}
- if err = pconn.addTLS(ctx, firstTLSHost, trace); err != nil {
+ if err = pconn.addTLS(firstTLSHost, trace); err != nil {
return nil, wrapErr(err)
}
}
@@ -1721,7 +1721,7 @@ func (t *Transport) dialConn(ctx context.Context, cm connectMethod) (pconn *pers
}
if cm.proxyURL != nil && cm.targetScheme == "https" {
- if err := pconn.addTLS(ctx, cm.tlsHost(), trace); err != nil {
+ if err := pconn.addTLS(cm.tlsHost(), trace); err != nil {
return nil, err
}
}
@@ -2566,7 +2566,9 @@ func (pc *persistConn) roundTrip(req *transportRequest) (resp *Response, err err
continueCh = make(chan struct{}, 1)
}
- if pc.t.DisableKeepAlives && !req.wantsClose() {
+ if pc.t.DisableKeepAlives &&
+ !req.wantsClose() &&
+ !isProtocolSwitchHeader(req.Header) {
req.extraHeaders().Set("Connection", "close")
}
diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go
index 7f6e0938c2..ba85a61683 100644
--- a/src/net/http/transport_test.go
+++ b/src/net/http/transport_test.go
@@ -3734,7 +3734,7 @@ func TestTransportDialTLSContext(t *testing.T) {
if err != nil {
return nil, err
}
- return c, c.HandshakeContext(ctx)
+ return c, c.Handshake()
}
req, err := NewRequest("GET", ts.URL, nil)
diff --git a/src/net/mockserver_test.go b/src/net/mockserver_test.go
index 9faf173679..867e31e9ae 100644
--- a/src/net/mockserver_test.go
+++ b/src/net/mockserver_test.go
@@ -87,6 +87,7 @@ type localServer struct {
lnmu sync.RWMutex
Listener
done chan bool // signal that indicates server stopped
+ cl []Conn // accepted connection list
}
func (ls *localServer) buildup(handler func(*localServer, Listener)) error {
@@ -99,10 +100,16 @@ func (ls *localServer) buildup(handler func(*localServer, Listener)) error {
func (ls *localServer) teardown() error {
ls.lnmu.Lock()
+ defer ls.lnmu.Unlock()
if ls.Listener != nil {
network := ls.Listener.Addr().Network()
address := ls.Listener.Addr().String()
ls.Listener.Close()
+ for _, c := range ls.cl {
+ if err := c.Close(); err != nil {
+ return err
+ }
+ }
<-ls.done
ls.Listener = nil
switch network {
@@ -110,7 +117,6 @@ func (ls *localServer) teardown() error {
os.Remove(address)
}
}
- ls.lnmu.Unlock()
return nil
}
@@ -203,7 +209,7 @@ func newDualStackServer() (*dualStackServer, error) {
}, nil
}
-func transponder(ln Listener, ch chan<- error) {
+func (ls *localServer) transponder(ln Listener, ch chan<- error) {
defer close(ch)
switch ln := ln.(type) {
@@ -220,7 +226,7 @@ func transponder(ln Listener, ch chan<- error) {
ch <- err
return
}
- defer c.Close()
+ ls.cl = append(ls.cl, c)
network := ln.Addr().Network()
if c.LocalAddr().Network() != network || c.RemoteAddr().Network() != network {
diff --git a/src/net/protoconn_test.go b/src/net/protoconn_test.go
index 9f6772c7d1..6f83f52681 100644
--- a/src/net/protoconn_test.go
+++ b/src/net/protoconn_test.go
@@ -72,7 +72,7 @@ func TestTCPConnSpecificMethods(t *testing.T) {
t.Fatal(err)
}
ch := make(chan error, 1)
- handler := func(ls *localServer, ln Listener) { transponder(ls.Listener, ch) }
+ handler := func(ls *localServer, ln Listener) { ls.transponder(ls.Listener, ch) }
ls, err := (&streamListener{Listener: ln}).newLocalServer()
if err != nil {
t.Fatal(err)
diff --git a/src/net/server_test.go b/src/net/server_test.go
index 2673b87718..4ac5443e6a 100644
--- a/src/net/server_test.go
+++ b/src/net/server_test.go
@@ -86,7 +86,7 @@ func TestTCPServer(t *testing.T) {
}
for i := 0; i < N; i++ {
ch := tpchs[i]
- handler := func(ls *localServer, ln Listener) { transponder(ln, ch) }
+ handler := func(ls *localServer, ln Listener) { ls.transponder(ln, ch) }
if err := lss[i].buildup(handler); err != nil {
t.Fatal(err)
}
@@ -178,7 +178,7 @@ func TestUnixAndUnixpacketServer(t *testing.T) {
}
for i := 0; i < N; i++ {
ch := tpchs[i]
- handler := func(ls *localServer, ln Listener) { transponder(ln, ch) }
+ handler := func(ls *localServer, ln Listener) { ls.transponder(ln, ch) }
if err := lss[i].buildup(handler); err != nil {
t.Fatal(err)
}
diff --git a/src/net/tcpsock_test.go b/src/net/tcpsock_test.go
index 6e905aa091..d6172bc503 100644
--- a/src/net/tcpsock_test.go
+++ b/src/net/tcpsock_test.go
@@ -393,7 +393,7 @@ func TestIPv6LinkLocalUnicastTCP(t *testing.T) {
}
defer ls.teardown()
ch := make(chan error, 1)
- handler := func(ls *localServer, ln Listener) { transponder(ln, ch) }
+ handler := func(ls *localServer, ln Listener) { ls.transponder(ln, ch) }
if err := ls.buildup(handler); err != nil {
t.Fatal(err)
}
diff --git a/src/os/file_plan9.go b/src/os/file_plan9.go
index bbc732838a..4f384e9211 100644
--- a/src/os/file_plan9.go
+++ b/src/os/file_plan9.go
@@ -336,16 +336,6 @@ func hasPrefix(s, prefix string) bool {
return len(s) >= len(prefix) && s[0:len(prefix)] == prefix
}
-// LastIndexByte from the strings package.
-func lastIndex(s string, sep byte) int {
- for i := len(s) - 1; i >= 0; i-- {
- if s[i] == sep {
- return i
- }
- }
- return -1
-}
-
func rename(oldname, newname string) error {
dirname := oldname[:lastIndex(oldname, '/')+1]
if hasPrefix(newname, dirname) {
diff --git a/src/os/signal/signal_test.go b/src/os/signal/signal_test.go
index 8945cbfccb..bbc68af9fb 100644
--- a/src/os/signal/signal_test.go
+++ b/src/os/signal/signal_test.go
@@ -675,22 +675,68 @@ func TestTime(t *testing.T) {
<-done
}
-func TestNotifyContext(t *testing.T) {
- c, stop := NotifyContext(context.Background(), syscall.SIGINT)
- defer stop()
+var (
+ checkNotifyContext = flag.Bool("check_notify_ctx", false, "if true, TestNotifyContext will fail if SIGINT is not received.")
+ ctxNotifyTimes = flag.Int("ctx_notify_times", 1, "number of times a SIGINT signal should be received")
+)
- if want, got := "signal.NotifyContext(context.Background, [interrupt])", fmt.Sprint(c); want != got {
- t.Errorf("c.String() = %q, want %q", got, want)
+func TestNotifyContextNotifications(t *testing.T) {
+ if *checkNotifyContext {
+ ctx, _ := NotifyContext(context.Background(), syscall.SIGINT)
+ // We want to make sure not to be calling Stop() internally on NotifyContext() when processing a received signal.
+ // Being able to wait for a number of received system signals allows us to do so.
+ var wg sync.WaitGroup
+ n := *ctxNotifyTimes
+ wg.Add(n)
+ for i := 0; i < n; i++ {
+ go func() {
+ syscall.Kill(syscall.Getpid(), syscall.SIGINT)
+ wg.Done()
+ }()
+ }
+ wg.Wait()
+ <-ctx.Done()
+ fmt.Print("received SIGINT")
+ // Sleep to give time to simultaneous signals to reach the process.
+ // These signals must be ignored given stop() is not called on this code.
+ // We want to guarantee a SIGINT doesn't cause a premature termination of the program.
+ time.Sleep(settleTime)
+ return
}
- syscall.Kill(syscall.Getpid(), syscall.SIGINT)
- select {
- case <-c.Done():
- if got := c.Err(); got != context.Canceled {
- t.Errorf("c.Err() = %q, want %q", got, context.Canceled)
- }
- case <-time.After(time.Second):
- t.Errorf("timed out waiting for context to be done after SIGINT")
+ t.Parallel()
+ testCases := []struct {
+ name string
+ n int // number of times a SIGINT should be notified.
+ }{
+ {"once", 1},
+ {"multiple", 10},
+ }
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ var subTimeout time.Duration
+ if deadline, ok := t.Deadline(); ok {
+ subTimeout := time.Until(deadline)
+ subTimeout -= subTimeout / 10 // Leave 10% headroom for cleaning up subprocess.
+ }
+
+ args := []string{
+ "-test.v",
+ "-test.run=TestNotifyContextNotifications$",
+ "-check_notify_ctx",
+ fmt.Sprintf("-ctx_notify_times=%d", tc.n),
+ }
+ if subTimeout != 0 {
+ args = append(args, fmt.Sprintf("-test.timeout=%v", subTimeout))
+ }
+ out, err := exec.Command(os.Args[0], args...).CombinedOutput()
+ if err != nil {
+ t.Errorf("ran test with -check_notify_ctx_notification and it failed with %v.\nOutput:\n%s", err, out)
+ }
+ if want := []byte("received SIGINT"); !bytes.Contains(out, want) {
+ t.Errorf("got %q, wanted %q", out, want)
+ }
+ })
}
}
@@ -768,34 +814,6 @@ func TestNotifyContextPrematureCancelParent(t *testing.T) {
}
}
-func TestNotifyContextSimultaneousNotifications(t *testing.T) {
- c, stop := NotifyContext(context.Background(), syscall.SIGINT)
- defer stop()
-
- if want, got := "signal.NotifyContext(context.Background, [interrupt])", fmt.Sprint(c); want != got {
- t.Errorf("c.String() = %q, want %q", got, want)
- }
-
- var wg sync.WaitGroup
- n := 10
- wg.Add(n)
- for i := 0; i < n; i++ {
- go func() {
- syscall.Kill(syscall.Getpid(), syscall.SIGINT)
- wg.Done()
- }()
- }
- wg.Wait()
- select {
- case <-c.Done():
- if got := c.Err(); got != context.Canceled {
- t.Errorf("c.Err() = %q, want %q", got, context.Canceled)
- }
- case <-time.After(time.Second):
- t.Errorf("expected context to be canceled")
- }
-}
-
func TestNotifyContextSimultaneousStop(t *testing.T) {
c, stop := NotifyContext(context.Background(), syscall.SIGINT)
defer stop()
diff --git a/src/os/tempfile.go b/src/os/tempfile.go
index 2728485c32..4f90fcf8e8 100644
--- a/src/os/tempfile.go
+++ b/src/os/tempfile.go
@@ -4,10 +4,7 @@
package os
-import (
- "errors"
- "strings"
-)
+import "errors"
// fastrand provided by runtime.
// We generate random temporary file names so that there's a good
@@ -62,7 +59,7 @@ func prefixAndSuffix(pattern string) (prefix, suffix string, err error) {
return "", "", errPatternHasSeparator
}
}
- if pos := strings.LastIndex(pattern, "*"); pos != -1 {
+ if pos := lastIndex(pattern, '*'); pos != -1 {
prefix, suffix = pattern[:pos], pattern[pos+1:]
} else {
prefix = pattern
@@ -116,3 +113,13 @@ func joinPath(dir, name string) string {
}
return dir + string(PathSeparator) + name
}
+
+// LastIndexByte from the strings package.
+func lastIndex(s string, sep byte) int {
+ for i := len(s) - 1; i >= 0; i-- {
+ if s[i] == sep {
+ return i
+ }
+ }
+ return -1
+}
diff --git a/src/runtime/metrics/description_test.go b/src/runtime/metrics/description_test.go
index 448639ee77..fd1fd46efc 100644
--- a/src/runtime/metrics/description_test.go
+++ b/src/runtime/metrics/description_test.go
@@ -43,7 +43,7 @@ func extractMetricDocs(t *testing.T) map[string]string {
line := strings.TrimSpace(s.Text())
switch state {
case stateSearch:
- if line == "Supported metrics" {
+ if line == "Below is the full list of supported metrics, ordered lexicographically." {
state = stateNextMetric
}
case stateNextMetric:
diff --git a/src/runtime/metrics/doc.go b/src/runtime/metrics/doc.go
index 42b5bc3724..a68184ee82 100644
--- a/src/runtime/metrics/doc.go
+++ b/src/runtime/metrics/doc.go
@@ -42,8 +42,16 @@ did also, and a new key should be introduced.
For more details on the precise definition of the metric key's path and unit formats, see
the documentation of the Name field of the Description struct.
+A note about floats
+
+This package supports metrics whose values have a floating-point representation. In
+order to improve ease-of-use, this package promises to never produce the following
+classes of floating-point values: NaN, infinity.
+
Supported metrics
+Below is the full list of supported metrics, ordered lexicographically.
+
/gc/cycles/automatic:gc-cycles
Count of completed GC cycles generated by the Go runtime.
diff --git a/src/runtime/metrics/sample.go b/src/runtime/metrics/sample.go
index 60189cb334..35534dd70d 100644
--- a/src/runtime/metrics/sample.go
+++ b/src/runtime/metrics/sample.go
@@ -30,6 +30,16 @@ func runtime_readMetrics(unsafe.Pointer, int, int)
// The user of this API is encouraged to re-use the same slice between calls for
// efficiency, but is not required to do so.
//
+// Note that re-use has some caveats. Notably, Values should not be read or
+// manipulated while a Read with that value is outstanding; that is a data race.
+// This property includes pointer-typed Values (e.g. Float64Histogram) whose
+// underlying storage will be reused by Read when possible. To safely use such
+// values in a concurrent setting, all data must be deep-copied.
+//
+// It is safe to execute multiple Read calls concurrently, but their arguments
+// must share no underlying memory. When in doubt, create a new []Sample from
+// scratch, which is always safe, though may be inefficient.
+//
// Sample values with names not appearing in All will have their Value populated
// as KindBad to indicate that the name is unknown.
func Read(m []Sample) {
diff --git a/src/runtime/race/output_test.go b/src/runtime/race/output_test.go
index 986667332f..69496874c6 100644
--- a/src/runtime/race/output_test.go
+++ b/src/runtime/race/output_test.go
@@ -284,32 +284,31 @@ static inline void startThread(cb* c) {
*/
import "C"
-import "time"
-
+var done chan bool
var racy int
//export goCallback
func goCallback() {
racy++
+ done <- true
}
func main() {
+ done = make(chan bool)
var c C.cb
C.startThread(&c)
- time.Sleep(time.Second)
racy++
+ <- done
}
`, `==================
WARNING: DATA RACE
-Read at 0x[0-9,a-f]+ by main goroutine:
- main\.main\(\)
- .*/main\.go:34 \+0x[0-9,a-f]+
+Read at 0x[0-9,a-f]+ by .*:
+ main\..*
+ .*/main\.go:[0-9]+ \+0x[0-9,a-f]+(?s).*
-Previous write at 0x[0-9,a-f]+ by goroutine [0-9]:
- main\.goCallback\(\)
- .*/main\.go:27 \+0x[0-9,a-f]+
- _cgoexp_[0-9a-z]+_goCallback\(\)
- .*_cgo_gotypes\.go:[0-9]+ \+0x[0-9,a-f]+
+Previous write at 0x[0-9,a-f]+ by .*:
+ main\..*
+ .*/main\.go:[0-9]+ \+0x[0-9,a-f]+(?s).*
Goroutine [0-9] \(running\) created at:
runtime\.newextram\(\)
diff --git a/src/syscall/syscall.go b/src/syscall/syscall.go
index 2e7a3ae5f2..91173033ee 100644
--- a/src/syscall/syscall.go
+++ b/src/syscall/syscall.go
@@ -77,24 +77,22 @@ func BytePtrFromString(s string) (*byte, error) {
// See mksyscall.pl.
var _zero uintptr
-// Unix returns ts as the number of seconds and nanoseconds elapsed since the
-// Unix epoch.
+// Unix returns the time stored in ts as seconds plus nanoseconds.
func (ts *Timespec) Unix() (sec int64, nsec int64) {
return int64(ts.Sec), int64(ts.Nsec)
}
-// Unix returns tv as the number of seconds and nanoseconds elapsed since the
-// Unix epoch.
+// Unix returns the time stored in tv as seconds plus nanoseconds.
func (tv *Timeval) Unix() (sec int64, nsec int64) {
return int64(tv.Sec), int64(tv.Usec) * 1000
}
-// Nano returns ts as the number of nanoseconds elapsed since the Unix epoch.
+// Nano returns the time stored in ts as nanoseconds.
func (ts *Timespec) Nano() int64 {
return int64(ts.Sec)*1e9 + int64(ts.Nsec)
}
-// Nano returns tv as the number of nanoseconds elapsed since the Unix epoch.
+// Nano returns the time stored in tv as nanoseconds.
func (tv *Timeval) Nano() int64 {
return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000
}
diff --git a/src/syscall/timestruct.go b/src/syscall/timestruct.go
index 682c68cf9b..bca51df08d 100644
--- a/src/syscall/timestruct.go
+++ b/src/syscall/timestruct.go
@@ -6,12 +6,10 @@
package syscall
-// TimespecToNsec converts a Timespec value into a number of
-// nanoseconds since the Unix epoch.
+// TimespecToNSec returns the time stored in ts as nanoseconds.
func TimespecToNsec(ts Timespec) int64 { return ts.Nano() }
-// NsecToTimespec takes a number of nanoseconds since the Unix epoch
-// and returns the corresponding Timespec value.
+// NsecToTimespec converts a number of nanoseconds into a Timespec.
func NsecToTimespec(nsec int64) Timespec {
sec := nsec / 1e9
nsec = nsec % 1e9
@@ -22,12 +20,10 @@ func NsecToTimespec(nsec int64) Timespec {
return setTimespec(sec, nsec)
}
-// TimevalToNsec converts a Timeval value into a number of nanoseconds
-// since the Unix epoch.
+// TimevalToNsec returns the time stored in tv as nanoseconds.
func TimevalToNsec(tv Timeval) int64 { return tv.Nano() }
-// NsecToTimeval takes a number of nanoseconds since the Unix epoch
-// and returns the corresponding Timeval value.
+// NsecToTimeval converts a number of nanoseconds into a Timeval.
func NsecToTimeval(nsec int64) Timeval {
nsec += 999 // round up to microsecond
usec := nsec % 1e9 / 1e3
diff --git a/src/text/template/exec.go b/src/text/template/exec.go
index 7ac5175006..19154fc640 100644
--- a/src/text/template/exec.go
+++ b/src/text/template/exec.go
@@ -373,6 +373,10 @@ func (s *state) walkRange(dot reflect.Value, r *parse.RangeNode) {
if val.IsNil() {
break
}
+ if val.Type().ChanDir() == reflect.SendDir {
+ s.errorf("range over send-only channel %v", val)
+ break
+ }
i := 0
for ; ; i++ {
elem, ok := val.Recv()
diff --git a/src/text/template/exec_test.go b/src/text/template/exec_test.go
index 1611ee054f..1a129ed5af 100644
--- a/src/text/template/exec_test.go
+++ b/src/text/template/exec_test.go
@@ -1697,3 +1697,16 @@ func TestIssue31810(t *testing.T) {
t.Errorf("%s got %q, expected %q", textCall, b.String(), "result")
}
}
+
+// Issue 43065, range over send only channel
+func TestIssue43065(t *testing.T) {
+ var b bytes.Buffer
+ tmp := Must(New("").Parse(`{{range .}}{{end}}`))
+ ch := make(chan<- int)
+ err := tmp.Execute(&b, ch)
+ if err == nil {
+ t.Error("expected err got nil")
+ } else if !strings.Contains(err.Error(), "range over send-only channel") {
+ t.Errorf("%s", err)
+ }
+}
diff --git a/src/vendor/modules.txt b/src/vendor/modules.txt
index de727ef71f..04bb67e58d 100644
--- a/src/vendor/modules.txt
+++ b/src/vendor/modules.txt
@@ -8,7 +8,7 @@ golang.org/x/crypto/curve25519
golang.org/x/crypto/hkdf
golang.org/x/crypto/internal/subtle
golang.org/x/crypto/poly1305
-# golang.org/x/net v0.0.0-20201029221708-28c70e62bb1d
+# golang.org/x/net v0.0.0-20201209123823-ac852fbbde11
## explicit
golang.org/x/net/dns/dnsmessage
golang.org/x/net/http/httpguts
diff --git a/test/fixedbugs/bug13343.go b/test/fixedbugs/bug13343.go
index 5dc736d443..a7febeae7e 100644
--- a/test/fixedbugs/bug13343.go
+++ b/test/fixedbugs/bug13343.go
@@ -7,8 +7,8 @@
package main
var (
- a, b = f() // ERROR "initialization loop|depends upon itself"
- c = b
+ a, b = f() // ERROR "initialization loop|depends upon itself|depend upon each other"
+ c = b // GCCGO_ERROR "depends upon itself|depend upon each other"
)
func f() (int, int) {
diff --git a/test/fixedbugs/bug195.go b/test/fixedbugs/bug195.go
index aef7bd2d89..94f61fff7f 100644
--- a/test/fixedbugs/bug195.go
+++ b/test/fixedbugs/bug195.go
@@ -19,7 +19,7 @@ type I4 interface { // GC_ERROR "invalid recursive type I4\n\tLINE: I4 refers to
}
type I5 interface { // GC_ERROR "invalid recursive type I5\n\tLINE: I5 refers to\n\tLINE+4: I6 refers to\n\tLINE: I5$"
- I6 // GCCGO_ERROR "interface"
+ I6
}
type I6 interface {
diff --git a/test/fixedbugs/bug251.go b/test/fixedbugs/bug251.go
index 706bb8d690..977aa49e6a 100644
--- a/test/fixedbugs/bug251.go
+++ b/test/fixedbugs/bug251.go
@@ -8,7 +8,7 @@ package main
type I1 interface { // GC_ERROR "invalid recursive type"
m() I2
- I2 // GCCGO_ERROR "loop|interface"
+ I2
}
type I2 interface {
diff --git a/test/fixedbugs/bug302.go b/test/fixedbugs/bug302.go
index 87f9d4ef70..a2ab661277 100644
--- a/test/fixedbugs/bug302.go
+++ b/test/fixedbugs/bug302.go
@@ -1,4 +1,4 @@
-// +build !nacl,!js
+// +build !nacl,!js,gc
// run
// Copyright 2010 The Go Authors. All rights reserved.
diff --git a/test/fixedbugs/bug369.go b/test/fixedbugs/bug369.go
index 9316f7aad0..83f638d046 100644
--- a/test/fixedbugs/bug369.go
+++ b/test/fixedbugs/bug369.go
@@ -1,4 +1,4 @@
-// +build !nacl,!js,!windows
+// +build !nacl,!js,!windows,gc
// run
// Copyright 2011 The Go Authors. All rights reserved.
diff --git a/test/fixedbugs/bug429.go b/test/fixedbugs/bug429.go
deleted file mode 100644
index 2c31f32da7..0000000000
--- a/test/fixedbugs/bug429.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// skip
-
-// Copyright 2012 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.
-
-// Should print deadlock message, not hang.
-// This test is run by bug429_run.go.
-
-package main
-
-func main() {
- select {}
-}
diff --git a/test/fixedbugs/bug429_run.go b/test/fixedbugs/bug429_run.go
deleted file mode 100644
index c2bb1b85cb..0000000000
--- a/test/fixedbugs/bug429_run.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// run
-
-// +build !nacl,!js
-
-// Copyright 2014 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.
-
-// Run the bug429.go test.
-
-package main
-
-import (
- "fmt"
- "os"
- "os/exec"
- "path/filepath"
- "strings"
-)
-
-func main() {
- cmd := exec.Command("go", "run", filepath.Join("fixedbugs", "bug429.go"))
- out, err := cmd.CombinedOutput()
- if err == nil {
- fmt.Println("expected deadlock")
- os.Exit(1)
- }
-
- want := "fatal error: all goroutines are asleep - deadlock!"
- got := string(out)
- if !strings.Contains(got, want) {
- fmt.Printf("got:\n%q\nshould contain:\n%q\n", got, want)
- os.Exit(1)
- }
-}
diff --git a/test/fixedbugs/issue10607.go b/test/fixedbugs/issue10607.go
index 6f4717d820..448a37dcac 100644
--- a/test/fixedbugs/issue10607.go
+++ b/test/fixedbugs/issue10607.go
@@ -1,4 +1,4 @@
-// +build linux,!ppc64,!riscv64
+// +build linux,!ppc64,!riscv64,gc
// run
// Copyright 2015 The Go Authors. All rights reserved.
diff --git a/test/fixedbugs/issue10700.dir/test.go b/test/fixedbugs/issue10700.dir/test.go
index 2033efc9d8..2dfc24af07 100644
--- a/test/fixedbugs/issue10700.dir/test.go
+++ b/test/fixedbugs/issue10700.dir/test.go
@@ -21,27 +21,27 @@ func (me *HasAMethod) Do() {
}
func InMyCode(x *Imported, y *HasAMethod, z *other.Exported) {
- x.Do() // ERROR "x\.Do undefined \(type \*Imported is pointer to interface, not interface\)"
- x.do() // ERROR "x\.do undefined \(type \*Imported is pointer to interface, not interface\)"
+ x.Do() // ERROR "x\.Do undefined \(type \*Imported is pointer to interface, not interface\)|type that is pointer to interface"
+ x.do() // ERROR "x\.do undefined \(type \*Imported is pointer to interface, not interface\)|type that is pointer to interface"
(*x).Do()
- x.Dont() // ERROR "x\.Dont undefined \(type \*Imported is pointer to interface, not interface\)"
- (*x).Dont() // ERROR "\(\*x\)\.Dont undefined \(type Imported has no field or method Dont\)"
+ x.Dont() // ERROR "x\.Dont undefined \(type \*Imported is pointer to interface, not interface\)|type that is pointer to interface"
+ (*x).Dont() // ERROR "\(\*x\)\.Dont undefined \(type Imported has no field or method Dont\)|reference to undefined field or method"
y.Do()
- y.do() // ERROR "y\.do undefined \(type \*HasAMethod has no field or method do, but does have Do\)"
+ y.do() // ERROR "y\.do undefined \(type \*HasAMethod has no field or method do, but does have Do\)|reference to undefined field or method"
(*y).Do()
- (*y).do() // ERROR "\(\*y\)\.do undefined \(type HasAMethod has no field or method do, but does have Do\)"
- y.Dont() // ERROR "y\.Dont undefined \(type \*HasAMethod has no field or method Dont\)"
- (*y).Dont() // ERROR "\(\*y\)\.Dont undefined \(type HasAMethod has no field or method Dont\)"
+ (*y).do() // ERROR "\(\*y\)\.do undefined \(type HasAMethod has no field or method do, but does have Do\)|reference to undefined field or method"
+ y.Dont() // ERROR "y\.Dont undefined \(type \*HasAMethod has no field or method Dont\)|reference to undefined field or method"
+ (*y).Dont() // ERROR "\(\*y\)\.Dont undefined \(type HasAMethod has no field or method Dont\)|reference to undefined field or method"
- z.Do() // ERROR "z\.Do undefined \(type \*other\.Exported is pointer to interface, not interface\)"
- z.do() // ERROR "z\.do undefined \(type \*other\.Exported is pointer to interface, not interface\)"
+ z.Do() // ERROR "z\.Do undefined \(type \*other\.Exported is pointer to interface, not interface\)|type that is pointer to interface"
+ z.do() // ERROR "z\.do undefined \(type \*other\.Exported is pointer to interface, not interface\)|type that is pointer to interface"
(*z).Do()
- (*z).do() // ERROR "\(\*z\)\.do undefined \(type other.Exported has no field or method do, but does have Do\)"
- z.Dont() // ERROR "z\.Dont undefined \(type \*other\.Exported is pointer to interface, not interface\)"
- (*z).Dont() // ERROR "\(\*z\)\.Dont undefined \(type other\.Exported has no field or method Dont\)"
- z.secret() // ERROR "z\.secret undefined \(type \*other\.Exported is pointer to interface, not interface\)"
- (*z).secret() // ERROR "\(\*z\)\.secret undefined \(cannot refer to unexported field or method secret\)"
+ (*z).do() // ERROR "\(\*z\)\.do undefined \(type other.Exported has no field or method do, but does have Do\)|reference to undefined field or method"
+ z.Dont() // ERROR "z\.Dont undefined \(type \*other\.Exported is pointer to interface, not interface\)|type that is pointer to interface"
+ (*z).Dont() // ERROR "\(\*z\)\.Dont undefined \(type other\.Exported has no field or method Dont\)|reference to undefined field or method"
+ z.secret() // ERROR "z\.secret undefined \(type \*other\.Exported is pointer to interface, not interface\)|type that is pointer to interface"
+ (*z).secret() // ERROR "\(\*z\)\.secret undefined \(cannot refer to unexported field or method secret\)|reference to unexported field or method"
}
diff --git a/test/fixedbugs/issue10975.go b/test/fixedbugs/issue10975.go
index b5f043f0a7..933badfd2f 100644
--- a/test/fixedbugs/issue10975.go
+++ b/test/fixedbugs/issue10975.go
@@ -10,7 +10,7 @@
package main
type I interface {
- int // ERROR "interface contains embedded non-interface int"
+ int // ERROR "interface contains embedded non-interface"
}
func New() I {
diff --git a/test/fixedbugs/issue11326.go b/test/fixedbugs/issue11326.go
index 82754c73fb..e0c6a9f0ba 100644
--- a/test/fixedbugs/issue11326.go
+++ b/test/fixedbugs/issue11326.go
@@ -18,14 +18,14 @@ func main() {
// Any implementation must be able to handle these constants at
// compile time (even though they cannot be assigned to a float64).
- var _ = 1e646456992 // ERROR "1e\+646456992 overflows float64"
- var _ = 1e64645699 // ERROR "1e\+64645699 overflows float64"
- var _ = 1e6464569 // ERROR "1e\+6464569 overflows float64"
- var _ = 1e646456 // ERROR "1e\+646456 overflows float64"
- var _ = 1e64645 // ERROR "1e\+64645 overflows float64"
- var _ = 1e6464 // ERROR "1e\+6464 overflows float64"
- var _ = 1e646 // ERROR "1e\+646 overflows float64"
- var _ = 1e309 // ERROR "1e\+309 overflows float64"
+ var _ = 1e646456992 // ERROR "1e\+646456992 overflows float64|floating-point constant overflow|exponent too large"
+ var _ = 1e64645699 // ERROR "1e\+64645699 overflows float64|floating-point constant overflow|exponent too large"
+ var _ = 1e6464569 // ERROR "1e\+6464569 overflows float64|floating-point constant overflow|exponent too large"
+ var _ = 1e646456 // ERROR "1e\+646456 overflows float64|floating-point constant overflow|exponent too large"
+ var _ = 1e64645 // ERROR "1e\+64645 overflows float64|floating-point constant overflow|exponent too large"
+ var _ = 1e6464 // ERROR "1e\+6464 overflows float64|floating-point constant overflow"
+ var _ = 1e646 // ERROR "1e\+646 overflows float64|floating-point constant overflow"
+ var _ = 1e309 // ERROR "1e\+309 overflows float64|floating-point constant overflow"
var _ = 1e308
}
diff --git a/test/fixedbugs/issue11326b.go b/test/fixedbugs/issue11326b.go
index 8aba4d9121..b5f933bfea 100644
--- a/test/fixedbugs/issue11326b.go
+++ b/test/fixedbugs/issue11326b.go
@@ -1,5 +1,9 @@
// run
+// Does not work with gccgo, which uses a smaller (but still permitted)
+// exponent size.
+// +build !gccgo
+
// Copyright 2015 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.
diff --git a/test/fixedbugs/issue11361.go b/test/fixedbugs/issue11361.go
index 1260ea89c9..63dbf05d73 100644
--- a/test/fixedbugs/issue11361.go
+++ b/test/fixedbugs/issue11361.go
@@ -6,6 +6,6 @@
package a
-import "fmt" // ERROR "imported and not used"
+import "fmt" // GC_ERROR "imported and not used"
-const n = fmt // ERROR "fmt without selector"
+const n = fmt // ERROR "fmt without selector|unexpected reference to package"
diff --git a/test/fixedbugs/issue11362.go b/test/fixedbugs/issue11362.go
index 9e9e599595..964e5fdf6b 100644
--- a/test/fixedbugs/issue11362.go
+++ b/test/fixedbugs/issue11362.go
@@ -8,7 +8,7 @@
package main
-import _ "unicode//utf8" // ERROR "non-canonical import path .unicode//utf8. \(should be .unicode/utf8.\)" "can't find import: .unicode//utf8."
+import _ "unicode//utf8" // GC_ERROR "non-canonical import path .unicode//utf8. \(should be .unicode/utf8.\)" "can't find import: .unicode//utf8."
func main() {
}
diff --git a/test/fixedbugs/issue11371.go b/test/fixedbugs/issue11371.go
index b2d966fac8..8acd18fccb 100644
--- a/test/fixedbugs/issue11371.go
+++ b/test/fixedbugs/issue11371.go
@@ -9,9 +9,9 @@
package issue11371
-const a int = 1.1 // ERROR "constant 1.1 truncated to integer"
-const b int = 1e20 // ERROR "overflows int"
-const c int = 1 + 1e-100 // ERROR "constant truncated to integer"
-const d int = 1 - 1e-100 // ERROR "constant truncated to integer"
+const a int = 1.1 // ERROR "constant 1.1 truncated to integer|floating-point constant truncated to integer"
+const b int = 1e20 // ERROR "overflows int|integer constant overflow"
+const c int = 1 + 1e-70 // ERROR "constant truncated to integer"
+const d int = 1 - 1e-70 // ERROR "constant truncated to integer"
const e int = 1.00000001 // ERROR "constant truncated to integer"
-const f int = 0.00000001 // ERROR "constant 1e-08 truncated to integer"
+const f int = 0.00000001 // ERROR "constant 1e-08 truncated to integer|floating-point constant truncated to integer"
diff --git a/test/fixedbugs/issue11590.go b/test/fixedbugs/issue11590.go
index 09345473fb..f2a955f96d 100644
--- a/test/fixedbugs/issue11590.go
+++ b/test/fixedbugs/issue11590.go
@@ -6,6 +6,6 @@
package p
-var _ = int8(4) * 300 // ERROR "constant 300 overflows int8" "constant 1200 overflows int8"
-var _ = complex64(1) * 1e200 // ERROR "constant 1e\+200 overflows complex64"
-var _ = complex128(1) * 1e500 // ERROR "constant 1e\+500 overflows complex128"
+var _ = int8(4) * 300 // ERROR "constant 300 overflows int8" "constant 1200 overflows int8|integer constant overflow"
+var _ = complex64(1) * 1e200 // ERROR "constant 1e\+200 overflows complex64|complex real part overflow"
+var _ = complex128(1) * 1e500 // ERROR "constant 1e\+500 overflows complex128|complex real part overflow"
diff --git a/test/fixedbugs/issue11610.go b/test/fixedbugs/issue11610.go
index 8ca31bf394..7ebfae6709 100644
--- a/test/fixedbugs/issue11610.go
+++ b/test/fixedbugs/issue11610.go
@@ -9,9 +9,9 @@
package a
import"" // ERROR "import path is empty"
-var? // ERROR "invalid character U\+003F '\?'"
+var? // ERROR "invalid character U\+003F '\?'|invalid character 0x3f in input file"
-var x int // ERROR "unexpected var"
+var x int // ERROR "unexpected var|expected identifier|expected type"
func main() {
}
diff --git a/test/fixedbugs/issue11614.go b/test/fixedbugs/issue11614.go
index 91f134d44a..de15f9827f 100644
--- a/test/fixedbugs/issue11614.go
+++ b/test/fixedbugs/issue11614.go
@@ -11,7 +11,7 @@
package main
type I interface {
- int // ERROR "interface contains embedded non-interface int"
+ int // ERROR "interface contains embedded non-interface"
}
func n() {
@@ -19,7 +19,7 @@ func n() {
}
func m() {
- (interface{int}) // ERROR "interface contains embedded non-interface int" "type interface { int } is not an expression"
+ (interface{int}) // ERROR "interface contains embedded non-interface" "type interface { int } is not an expression"
}
func main() {
diff --git a/test/fixedbugs/issue11656.go b/test/fixedbugs/issue11656.go
index 451ae6348f..62b36cf790 100644
--- a/test/fixedbugs/issue11656.go
+++ b/test/fixedbugs/issue11656.go
@@ -12,6 +12,11 @@
// wasm does not work, because the linear memory is not executable.
// +build !wasm
+// This test doesn't work on gccgo/GoLLVM, because they will not find
+// any unwind information for the artificial function, and will not be
+// able to unwind past that point.
+// +build !gccgo
+
package main
import (
@@ -75,6 +80,7 @@ func f(n int) {
}
f.x = uintptr(unsafe.Pointer(&ill[0]))
- fn := *(*func())(unsafe.Pointer(&f))
+ p := &f
+ fn := *(*func())(unsafe.Pointer(&p))
fn()
}
diff --git a/test/fixedbugs/issue11674.go b/test/fixedbugs/issue11674.go
index e7d0bf298b..b43032deac 100644
--- a/test/fixedbugs/issue11674.go
+++ b/test/fixedbugs/issue11674.go
@@ -13,28 +13,28 @@ const x complex64 = 0
const y complex128 = 0
var _ = x / 1e-20
-var _ = x / 1e-50 // ERROR "complex division by zero"
-var _ = x / 1e-1000 // ERROR "complex division by zero"
+var _ = x / 1e-50 // GC_ERROR "complex division by zero"
+var _ = x / 1e-1000 // GC_ERROR "complex division by zero"
var _ = x / 1e-20i
-var _ = x / 1e-50i // ERROR "complex division by zero"
-var _ = x / 1e-1000i // ERROR "complex division by zero"
+var _ = x / 1e-50i // GC_ERROR "complex division by zero"
+var _ = x / 1e-1000i // GC_ERROR "complex division by zero"
var _ = x / 1e-45 // smallest positive float32
var _ = x / (1e-20 + 1e-20i)
var _ = x / (1e-50 + 1e-20i)
var _ = x / (1e-20 + 1e-50i)
-var _ = x / (1e-50 + 1e-50i) // ERROR "complex division by zero"
-var _ = x / (1e-1000 + 1e-1000i) // ERROR "complex division by zero"
+var _ = x / (1e-50 + 1e-50i) // GC_ERROR "complex division by zero"
+var _ = x / (1e-1000 + 1e-1000i) // GC_ERROR "complex division by zero"
var _ = y / 1e-50
-var _ = y / 1e-1000 // ERROR "complex division by zero"
+var _ = y / 1e-1000 // GC_ERROR "complex division by zero"
var _ = y / 1e-50i
-var _ = y / 1e-1000i // ERROR "complex division by zero"
+var _ = y / 1e-1000i // GC_ERROR "complex division by zero"
var _ = y / 5e-324 // smallest positive float64
var _ = y / (1e-50 + 1e-50)
var _ = y / (1e-1000 + 1e-50i)
var _ = y / (1e-50 + 1e-1000i)
-var _ = y / (1e-1000 + 1e-1000i) // ERROR "complex division by zero"
+var _ = y / (1e-1000 + 1e-1000i) // GC_ERROR "complex division by zero"
diff --git a/test/fixedbugs/issue11771.go b/test/fixedbugs/issue11771.go
index 99d7060d44..c95dd6ba39 100644
--- a/test/fixedbugs/issue11771.go
+++ b/test/fixedbugs/issue11771.go
@@ -1,4 +1,4 @@
-// +build !nacl,!js
+// +build !nacl,!js,gc
// run
// Copyright 2015 The Go Authors. All rights reserved.
diff --git a/test/fixedbugs/issue13248.go b/test/fixedbugs/issue13248.go
index 524628159c..e23ba47b58 100644
--- a/test/fixedbugs/issue13248.go
+++ b/test/fixedbugs/issue13248.go
@@ -9,5 +9,5 @@
package main
func main() {
- foo(
-} // ERROR "unexpected }"
+ foo( // GCCGO_ERROR "undefined name"
+} // ERROR "unexpected }|expected operand|missing"
diff --git a/test/fixedbugs/issue13266.go b/test/fixedbugs/issue13266.go
index 37c5594a24..73c9e16bcc 100644
--- a/test/fixedbugs/issue13266.go
+++ b/test/fixedbugs/issue13266.go
@@ -7,4 +7,4 @@
// Offending character % must not be interpreted as
// start of format verb when emitting error message.
-package% // ERROR "unexpected %"
+package% // ERROR "unexpected %|package name must be an identifier|after package clause|expected declaration"
diff --git a/test/fixedbugs/issue13268.go b/test/fixedbugs/issue13268.go
index fcb69c9068..53a82d5074 100644
--- a/test/fixedbugs/issue13268.go
+++ b/test/fixedbugs/issue13268.go
@@ -1,3 +1,4 @@
+// +build gc
// run
// Copyright 2015 The Go Authors. All rights reserved.
diff --git a/test/fixedbugs/issue13273.go b/test/fixedbugs/issue13273.go
index f8f679daab..2498da4d47 100644
--- a/test/fixedbugs/issue13273.go
+++ b/test/fixedbugs/issue13273.go
@@ -47,9 +47,9 @@ func f() {
<-(<-chan (<-chan (<-chan (<-chan int))))(nil)
<-(<-chan (<-chan (<-chan (<-chan (<-chan int)))))(nil)
- type _ <-<-chan int // ERROR "unexpected <-, expecting chan"
+ type _ <-<-chan int // ERROR "unexpected <-, expecting chan|expected .*chan.*"
<-<-chan int // ERROR "unexpected <-, expecting chan|expecting {" (new parser: same error as for type decl)
- type _ <-chan<-int // ERROR "unexpected int, expecting chan|expecting chan"
+ type _ <-chan<-int // ERROR "unexpected int, expecting chan|expected .*chan.*|expecting chan|expected .*;.* or .*}.* or newline"
<-chan<-int // ERROR "unexpected int, expecting chan|expecting {" (new parser: same error as for type decl)
}
diff --git a/test/fixedbugs/issue13274.go b/test/fixedbugs/issue13274.go
index 480f5bcc11..816bd9b8f2 100644
--- a/test/fixedbugs/issue13274.go
+++ b/test/fixedbugs/issue13274.go
@@ -8,4 +8,4 @@
package p
-var f = func() { // ERROR "unexpected EOF"
\ No newline at end of file
+var f = func() { // ERROR "unexpected EOF|expected .*}.*"
\ No newline at end of file
diff --git a/test/fixedbugs/issue13365.go b/test/fixedbugs/issue13365.go
index 4bd103e38d..31a663eb1f 100644
--- a/test/fixedbugs/issue13365.go
+++ b/test/fixedbugs/issue13365.go
@@ -11,15 +11,15 @@ package main
var t struct{}
func main() {
- _ = []int{-1: 0} // ERROR "index must be non\-negative integer constant"
- _ = [10]int{-1: 0} // ERROR "index must be non\-negative integer constant"
- _ = [...]int{-1: 0} // ERROR "index must be non\-negative integer constant"
+ _ = []int{-1: 0} // ERROR "index must be non\-negative integer constant|index expression is negative"
+ _ = [10]int{-1: 0} // ERROR "index must be non\-negative integer constant|index expression is negative"
+ _ = [...]int{-1: 0} // ERROR "index must be non\-negative integer constant|index expression is negative"
_ = []int{100: 0}
- _ = [10]int{100: 0} // ERROR "array index 100 out of bounds"
+ _ = [10]int{100: 0} // ERROR "array index 100 out of bounds|out of range"
_ = [...]int{100: 0}
- _ = []int{t} // ERROR "cannot use .* as type int in slice literal"
- _ = [10]int{t} // ERROR "cannot use .* as type int in array literal"
- _ = [...]int{t} // ERROR "cannot use .* as type int in array literal"
+ _ = []int{t} // ERROR "cannot use .* as type int in slice literal|incompatible type"
+ _ = [10]int{t} // ERROR "cannot use .* as type int in array literal|incompatible type"
+ _ = [...]int{t} // ERROR "cannot use .* as type int in array literal|incompatible type"
}
diff --git a/test/fixedbugs/issue13415.go b/test/fixedbugs/issue13415.go
index 989a1ed50f..4c4655e547 100644
--- a/test/fixedbugs/issue13415.go
+++ b/test/fixedbugs/issue13415.go
@@ -11,7 +11,7 @@ package p
func f() {
select {
- case x, x := <-func() chan int { // ERROR "x repeated on left side of :="
+ case x, x := <-func() chan int { // ERROR "x repeated on left side of :=|redefinition|declared but not used"
c := make(chan int)
return c
}():
diff --git a/test/fixedbugs/issue13471.go b/test/fixedbugs/issue13471.go
index 0bfed42616..9069412ffa 100644
--- a/test/fixedbugs/issue13471.go
+++ b/test/fixedbugs/issue13471.go
@@ -9,17 +9,17 @@
package main
func main() {
- const _ int64 = 1e646456992 // ERROR "integer too large"
- const _ int32 = 1e64645699 // ERROR "integer too large"
- const _ int16 = 1e6464569 // ERROR "integer too large"
- const _ int8 = 1e646456 // ERROR "integer too large"
- const _ int = 1e64645 // ERROR "integer too large"
+ const _ int64 = 1e646456992 // ERROR "integer too large|floating-point constant truncated to integer|exponent too large"
+ const _ int32 = 1e64645699 // ERROR "integer too large|floating-point constant truncated to integer|exponent too large"
+ const _ int16 = 1e6464569 // ERROR "integer too large|floating-point constant truncated to integer|exponent too large"
+ const _ int8 = 1e646456 // ERROR "integer too large|floating-point constant truncated to integer|exponent too large"
+ const _ int = 1e64645 // ERROR "integer too large|floating-point constant truncated to integer|exponent too large"
- const _ uint64 = 1e646456992 // ERROR "integer too large"
- const _ uint32 = 1e64645699 // ERROR "integer too large"
- const _ uint16 = 1e6464569 // ERROR "integer too large"
- const _ uint8 = 1e646456 // ERROR "integer too large"
- const _ uint = 1e64645 // ERROR "integer too large"
+ const _ uint64 = 1e646456992 // ERROR "integer too large|floating-point constant truncated to integer|exponent too large"
+ const _ uint32 = 1e64645699 // ERROR "integer too large|floating-point constant truncated to integer|exponent too large"
+ const _ uint16 = 1e6464569 // ERROR "integer too large|floating-point constant truncated to integer|exponent too large"
+ const _ uint8 = 1e646456 // ERROR "integer too large|floating-point constant truncated to integer|exponent too large"
+ const _ uint = 1e64645 // ERROR "integer too large|floating-point constant truncated to integer|exponent too large"
- const _ rune = 1e64645 // ERROR "integer too large"
+ const _ rune = 1e64645 // ERROR "integer too large|floating-point constant truncated to integer|exponent too large"
}
diff --git a/test/fixedbugs/issue13821b.go b/test/fixedbugs/issue13821b.go
index be67cea6dd..df68e8d626 100644
--- a/test/fixedbugs/issue13821b.go
+++ b/test/fixedbugs/issue13821b.go
@@ -15,10 +15,10 @@ var b B
var b2 B2
var x1 = b && 1 < 2 // x1 has type B, not ideal bool
var x2 = 1 < 2 && b // x2 has type B, not ideal bool
-var x3 = b && b2 // ERROR "mismatched types B and B2"
-var x4 = x1 && b2 // ERROR "mismatched types B and B2"
-var x5 = x2 && b2 // ERROR "mismatched types B and B2"
-var x6 = b2 && x1 // ERROR "mismatched types B2 and B"
-var x7 = b2 && x2 // ERROR "mismatched types B2 and B"
+var x3 = b && b2 // ERROR "mismatched types B and B2|incompatible types"
+var x4 = x1 && b2 // ERROR "mismatched types B and B2|incompatible types"
+var x5 = x2 && b2 // ERROR "mismatched types B and B2|incompatible types"
+var x6 = b2 && x1 // ERROR "mismatched types B2 and B|incompatible types"
+var x7 = b2 && x2 // ERROR "mismatched types B2 and B|incompatible types"
-var x8 = b && !B2(true) // ERROR "mismatched types B and B2"
+var x8 = b && !B2(true) // ERROR "mismatched types B and B2|incompatible types"
diff --git a/test/fixedbugs/issue14006.go b/test/fixedbugs/issue14006.go
index 02041cc290..9cad2b4c9d 100644
--- a/test/fixedbugs/issue14006.go
+++ b/test/fixedbugs/issue14006.go
@@ -21,26 +21,26 @@ func f() {
var x int
switch x {
case 1:
- 2: // ERROR "unexpected :"
+ 2: // ERROR "unexpected :|expected .*;.* or .*}.* or newline|value computed is not used"
case 2:
}
switch x {
case 1:
- 2: ; // ERROR "unexpected :"
+ 2: ; // ERROR "unexpected :|expected .*;.* or .*}.* or newline|value computed is not used"
case 2:
}
var y string
switch y {
case "foo":
- "bar": // ERROR "unexpected :"
+ "bar": // ERROR "unexpected :|expected .*;.* or .*}.* or newline|value computed is not used"
case "bar":
}
switch y {
case "foo":
- "bar": ; // ERROR "unexpected :"
+ "bar": ; // ERROR "unexpected :|expected .*;.* or .*}.* or newline|value computed is not used"
case "bar":
}
@@ -56,12 +56,12 @@ func g() {
var z bool
switch {
case z:
- labelname: // ERROR "label labelname defined and not used"
+ labelname: // ERROR "label labelname defined and not used|previous definition|defined and not used"
}
switch {
case z:
- labelname: ; // ERROR "label labelname already defined at LINE-5"
+ labelname: ; // ERROR "label labelname already defined at LINE-5|label .*labelname.* already defined"
case false:
}
-}
\ No newline at end of file
+}
diff --git a/test/fixedbugs/issue14010.go b/test/fixedbugs/issue14010.go
index 2786e107e8..0b233342be 100644
--- a/test/fixedbugs/issue14010.go
+++ b/test/fixedbugs/issue14010.go
@@ -10,6 +10,6 @@
package main
func main() {
- true = false // ERROR "cannot assign to true"
- byte = 0 // ERROR "not an expression"
+ true = false // ERROR "cannot assign to true|invalid left hand side"
+ byte = 0 // ERROR "not an expression|invalid left hand side|invalid use of type"
}
diff --git a/test/fixedbugs/issue14136.go b/test/fixedbugs/issue14136.go
index f9efd05f96..38308cd75c 100644
--- a/test/fixedbugs/issue14136.go
+++ b/test/fixedbugs/issue14136.go
@@ -14,6 +14,6 @@ package main
type T struct{}
func main() {
- t := T{X: 1, X: 1, X: 1, X: 1, X: 1, X: 1, X: 1, X: 1, X: 1, X: 1} // ERROR "unknown field 'X' in struct literal of type T"
- var s string = 1 // ERROR "cannot use 1"
+ t := T{X: 1, X: 1, X: 1, X: 1, X: 1, X: 1, X: 1, X: 1, X: 1, X: 1} // ERROR "unknown field 'X' in struct literal of type T|unknown field .*X.* in .*T.*"
+ var s string = 1 // ERROR "cannot use 1|incompatible type"
}
diff --git a/test/fixedbugs/issue14321.go b/test/fixedbugs/issue14321.go
index 058008c386..e1149c3f9d 100644
--- a/test/fixedbugs/issue14321.go
+++ b/test/fixedbugs/issue14321.go
@@ -27,7 +27,7 @@ type C struct {
B
}
-var _ = C.F // ERROR "ambiguous selector"
-var _ = C.G // ERROR "ambiguous selector"
-var _ = C.H // ERROR "ambiguous selector"
-var _ = C.I // ERROR "no method I"
+var _ = C.F // ERROR "ambiguous"
+var _ = C.G // ERROR "ambiguous"
+var _ = C.H // ERROR "ambiguous"
+var _ = C.I // ERROR "no method .*I.*"
diff --git a/test/fixedbugs/issue14520.go b/test/fixedbugs/issue14520.go
index 84d240faf0..0b840ff4be 100644
--- a/test/fixedbugs/issue14520.go
+++ b/test/fixedbugs/issue14520.go
@@ -9,6 +9,6 @@ package f
import /* // ERROR "import path" */ `
bogus`
-func f(x int /* // ERROR "unexpected newline"
+func f(x int /* // GC_ERROR "unexpected newline"
-*/)
+*/) // GCCGO_ERROR "expected .*\).*|expected declaration"
diff --git a/test/fixedbugs/issue14636.go b/test/fixedbugs/issue14636.go
index 6797046e02..06fd193dae 100644
--- a/test/fixedbugs/issue14636.go
+++ b/test/fixedbugs/issue14636.go
@@ -1,4 +1,4 @@
-// +build !nacl,!js,!android
+// +build !nacl,!js,!android,gc
// run
// Copyright 2016 The Go Authors. All rights reserved.
diff --git a/test/fixedbugs/issue14652.go b/test/fixedbugs/issue14652.go
index b030aee16f..d53b412668 100644
--- a/test/fixedbugs/issue14652.go
+++ b/test/fixedbugs/issue14652.go
@@ -6,4 +6,4 @@
package p
-var x any // ERROR "undefined: any"
+var x any // ERROR "undefined: any|undefined type .*any.*"
diff --git a/test/fixedbugs/issue14729.go b/test/fixedbugs/issue14729.go
index 88e01f9e16..9b30fd2715 100644
--- a/test/fixedbugs/issue14729.go
+++ b/test/fixedbugs/issue14729.go
@@ -10,5 +10,5 @@ package main
import "unsafe"
-type s struct { unsafe.Pointer } // ERROR "embedded type cannot be a pointer"
+type s struct { unsafe.Pointer } // ERROR "embedded type cannot be a pointer|embedded type may not be a pointer"
type s1 struct { p unsafe.Pointer }
diff --git a/test/fixedbugs/issue15514.dir/c.go b/test/fixedbugs/issue15514.dir/c.go
index 11624f9256..dc2ef5bed5 100644
--- a/test/fixedbugs/issue15514.dir/c.go
+++ b/test/fixedbugs/issue15514.dir/c.go
@@ -7,4 +7,4 @@ package c
import "./a"
import "./b"
-var _ a.A = b.B() // ERROR "cannot use b\.B"
+var _ a.A = b.B() // ERROR "cannot use b\.B|incompatible type"
diff --git a/test/fixedbugs/issue15898.go b/test/fixedbugs/issue15898.go
index 7b66ea23dc..94369f9345 100644
--- a/test/fixedbugs/issue15898.go
+++ b/test/fixedbugs/issue15898.go
@@ -8,11 +8,11 @@ package p
func f(e interface{}) {
switch e.(type) {
- case nil, nil: // ERROR "multiple nil cases in type switch"
+ case nil, nil: // ERROR "multiple nil cases in type switch|duplicate type in switch"
}
switch e.(type) {
case nil:
- case nil: // ERROR "multiple nil cases in type switch"
+ case nil: // ERROR "multiple nil cases in type switch|duplicate type in switch"
}
}
diff --git a/test/fixedbugs/issue16037_run.go b/test/fixedbugs/issue16037_run.go
index d05e3f7f31..68104a9000 100644
--- a/test/fixedbugs/issue16037_run.go
+++ b/test/fixedbugs/issue16037_run.go
@@ -1,4 +1,4 @@
-// +build !nacl,!js,!android
+// +build !nacl,!js,!android,!gccgo
// run
// Copyright 2016 The Go Authors. All rights reserved.
diff --git a/test/fixedbugs/issue16439.go b/test/fixedbugs/issue16439.go
index f9382bafcd..704b6b15a6 100644
--- a/test/fixedbugs/issue16439.go
+++ b/test/fixedbugs/issue16439.go
@@ -7,12 +7,12 @@
package p
var a []int = []int{1: 1}
-var b []int = []int{-1: 1} // ERROR "must be non-negative integer constant"
+var b []int = []int{-1: 1} // ERROR "must be non-negative integer constant|index expression is negative"
var c []int = []int{2.0: 2}
-var d []int = []int{-2.0: 2} // ERROR "must be non-negative integer constant"
+var d []int = []int{-2.0: 2} // ERROR "must be non-negative integer constant|index expression is negative"
var e []int = []int{3 + 0i: 3}
-var f []int = []int{3i: 3} // ERROR "truncated to integer"
+var f []int = []int{3i: 3} // ERROR "truncated to integer|index expression is not integer constant"
-var g []int = []int{"a": 4} // ERROR "must be non-negative integer constant"
+var g []int = []int{"a": 4} // ERROR "must be non-negative integer constant|index expression is not integer constant"
diff --git a/test/fixedbugs/issue17328.go b/test/fixedbugs/issue17328.go
index abe4daa353..ef60edbd42 100644
--- a/test/fixedbugs/issue17328.go
+++ b/test/fixedbugs/issue17328.go
@@ -8,6 +8,6 @@ package main
func main() {
i := 0
- for ; ; i++) { // ERROR "unexpected \), expecting { after for clause"
+ for ; ; i++) { // ERROR "unexpected \), expecting { after for clause|expected .*{.*|expected .*;.*"
}
-}
+} // GCCGO_ERROR "expected declaration"
diff --git a/test/fixedbugs/issue17588.go b/test/fixedbugs/issue17588.go
index 1be57c6292..0e3a14ef7c 100644
--- a/test/fixedbugs/issue17588.go
+++ b/test/fixedbugs/issue17588.go
@@ -11,7 +11,7 @@
package p
-type F func(b T) // ERROR "T is not a type"
+type F func(b T) // ERROR "T is not a type|expected type"
func T(fn F) {
func() {
diff --git a/test/fixedbugs/issue17631.go b/test/fixedbugs/issue17631.go
index 79b7e8a751..b820b2d5a7 100644
--- a/test/fixedbugs/issue17631.go
+++ b/test/fixedbugs/issue17631.go
@@ -17,6 +17,6 @@ func main() {
expect map[string]int
}{
about: "this one",
- updates: map[string]int{"gopher": 10}, // ERROR "unknown field 'updates' in struct literal of type"
+ updates: map[string]int{"gopher": 10}, // ERROR "unknown field 'updates' in struct literal of type|unknown field .*updates.* in .*unnamed struct.*"
}
}
diff --git a/test/fixedbugs/issue17645.go b/test/fixedbugs/issue17645.go
index 95fcecd1e0..bb34e4ee97 100644
--- a/test/fixedbugs/issue17645.go
+++ b/test/fixedbugs/issue17645.go
@@ -12,5 +12,5 @@ type Foo struct {
func main() {
var s []int
- var _ string = append(s, Foo{""}) // ERROR "cannot use .. \(type untyped string\) as type int in field value" "cannot use Foo{...} \(type Foo\) as type int in append" "cannot use append\(s\, Foo{...}\) \(type \[\]int\) as type string in assignment"
+ var _ string = append(s, Foo{""}) // ERROR "cannot use .. \(type untyped string\) as type int in field value|incompatible type" "cannot use Foo{...} \(type Foo\) as type int in append" "cannot use append\(s\, Foo{...}\) \(type \[\]int\) as type string in assignment"
}
diff --git a/test/fixedbugs/issue17758.go b/test/fixedbugs/issue17758.go
index e7f2f3af91..8e40f9db73 100644
--- a/test/fixedbugs/issue17758.go
+++ b/test/fixedbugs/issue17758.go
@@ -10,7 +10,7 @@ func foo() {
_ = func() {}
}
-func foo() { // ERROR "foo redeclared in this block"
+func foo() { // ERROR "foo redeclared in this block|redefinition of .*foo.*"
_ = func() {}
}
diff --git a/test/fixedbugs/issue18092.go b/test/fixedbugs/issue18092.go
index 94fd2dd383..a0f7eddda5 100644
--- a/test/fixedbugs/issue18092.go
+++ b/test/fixedbugs/issue18092.go
@@ -10,6 +10,6 @@ func _() {
var ch chan bool
select {
default:
- case <-ch { // don't crash here
- } // ERROR "expecting :"
+ case <-ch { // GCCGO_ERROR "expected colon"
+ } // GC_ERROR "expecting :"
}
diff --git a/test/fixedbugs/issue18231.go b/test/fixedbugs/issue18231.go
index adfd2277ff..7747304052 100644
--- a/test/fixedbugs/issue18231.go
+++ b/test/fixedbugs/issue18231.go
@@ -14,7 +14,7 @@ type T struct {
}
var _ = T{
- f: { // ERROR "missing type in composite literal"
+ f: { // ERROR "missing type in composite literal|may only omit types within"
"a": "b",
},
}
diff --git a/test/fixedbugs/issue18393.go b/test/fixedbugs/issue18393.go
index c16ff4df97..454392721f 100644
--- a/test/fixedbugs/issue18393.go
+++ b/test/fixedbugs/issue18393.go
@@ -21,4 +21,4 @@ var x // error on line 24, not 30
-// ERROR "syntax error: unexpected newline, expecting type"
+// ERROR "syntax error: unexpected newline, expecting type|expected type"
diff --git a/test/fixedbugs/issue18419.dir/test.go b/test/fixedbugs/issue18419.dir/test.go
index 31c6025e3f..da9639dd72 100644
--- a/test/fixedbugs/issue18419.dir/test.go
+++ b/test/fixedbugs/issue18419.dir/test.go
@@ -9,7 +9,7 @@ package main
import "./other"
func InMyCode(e *other.Exported) {
- e.member() // ERROR "e\.member undefined .cannot refer to unexported field or method other\.\(\*Exported\)\.member."
+ e.member() // ERROR "e\.member undefined .cannot refer to unexported field or method other\.\(\*Exported\)\.member.|unexported field or method"
}
func main() {}
diff --git a/test/fixedbugs/issue18655.go b/test/fixedbugs/issue18655.go
index abc2600280..13762f1a94 100644
--- a/test/fixedbugs/issue18655.go
+++ b/test/fixedbugs/issue18655.go
@@ -11,12 +11,12 @@ type A = T
type B = T
func (T) m() {}
-func (T) m() {} // ERROR "redeclared"
-func (A) m() {} // ERROR "redeclared"
-func (A) m() {} // ERROR "redeclared"
-func (B) m() {} // ERROR "redeclared"
-func (B) m() {} // ERROR "redeclared"
+func (T) m() {} // ERROR "redeclared|redefinition"
+func (A) m() {} // ERROR "redeclared|redefinition"
+func (A) m() {} // ERROR "redeclared|redefinition"
+func (B) m() {} // ERROR "redeclared|redefinition"
+func (B) m() {} // ERROR "redeclared|redefinition"
-func (*T) m() {} // ERROR "redeclared"
-func (*A) m() {} // ERROR "redeclared"
-func (*B) m() {} // ERROR "redeclared"
+func (*T) m() {} // ERROR "redeclared|redefinition"
+func (*A) m() {} // ERROR "redeclared|redefinition"
+func (*B) m() {} // ERROR "redeclared|redefinition"
diff --git a/test/fixedbugs/issue18915.go b/test/fixedbugs/issue18915.go
index 66e31e2556..22f97c6b62 100644
--- a/test/fixedbugs/issue18915.go
+++ b/test/fixedbugs/issue18915.go
@@ -10,12 +10,12 @@
package p
func _() {
- if a := 10 { // ERROR "cannot use a := 10 as value"
+ if a := 10 { // ERROR "cannot use a := 10 as value|expected .*;|declared but not used"
}
- for b := 10 { // ERROR "cannot use b := 10 as value"
+ for b := 10 { // ERROR "cannot use b := 10 as value|parse error|declared but not used"
}
- switch c := 10 { // ERROR "cannot use c := 10 as value"
+ switch c := 10 { // ERROR "cannot use c := 10 as value|expected .*;|declared but not used"
}
}
diff --git a/test/fixedbugs/issue19012.go b/test/fixedbugs/issue19012.go
index 636bf06e75..158618aa27 100644
--- a/test/fixedbugs/issue19012.go
+++ b/test/fixedbugs/issue19012.go
@@ -13,13 +13,13 @@ package main
func f(x int, y uint) {
if true {
- return "a" > 10 // ERROR "^too many arguments to return$" "."
+ return "a" > 10 // ERROR "^too many arguments to return$|return with value in function with no return|mismatched types"
}
- return "gopher" == true, 10 // ERROR "^too many arguments to return$" "."
+ return "gopher" == true, 10 // ERROR "^too many arguments to return$|return with value in function with no return|mismatched types"
}
func main() {
- f(2, 3 < "x", 10) // ERROR "^too many arguments in call to f$" "."
+ f(2, 3 < "x", 10) // ERROR "too many arguments|invalid operation|incompatible type"
- f(10, 10, "a") // ERROR "too many arguments in call to f\n\thave \(number, number, string\)\n\twant \(int, uint\)"
+ f(10, 10, "a") // ERROR "too many arguments"
}
diff --git a/test/fixedbugs/issue19028.dir/main.go b/test/fixedbugs/issue19028.dir/main.go
index 627e926f93..e2ee7b8ca1 100644
--- a/test/fixedbugs/issue19028.dir/main.go
+++ b/test/fixedbugs/issue19028.dir/main.go
@@ -6,7 +6,7 @@ package main
import (
"reflect"
- fake "./reflect" // 2nd package with name "reflect"
+ fake "./a" // 2nd package with name "reflect"
)
type T struct {
diff --git a/test/fixedbugs/issue19056.go b/test/fixedbugs/issue19056.go
index e4e8d07905..d279eaa3cf 100644
--- a/test/fixedbugs/issue19056.go
+++ b/test/fixedbugs/issue19056.go
@@ -6,4 +6,4 @@
package p
-var _ = ... . // ERROR "unexpected ..."
+var _ = ... . // ERROR "unexpected ...|expected operand|expected .*;"
diff --git a/test/fixedbugs/issue19323.go b/test/fixedbugs/issue19323.go
index f90af660d5..71365e10dd 100644
--- a/test/fixedbugs/issue19323.go
+++ b/test/fixedbugs/issue19323.go
@@ -9,11 +9,11 @@ package p
func g() {}
func f() {
- g()[:] // ERROR "g.. used as value"
+ g()[:] // ERROR "g.. used as value|attempt to slice object that is not"
}
func g2() ([]byte, []byte) { return nil, nil }
func f2() {
- g2()[:] // ERROR "multiple-value g2.. in single-value context"
+ g2()[:] // ERROR "multiple-value g2.. in single-value context|attempt to slice object that is not"
}
diff --git a/test/fixedbugs/issue19482.go b/test/fixedbugs/issue19482.go
index 97497a434c..4c2c19ec9d 100644
--- a/test/fixedbugs/issue19482.go
+++ b/test/fixedbugs/issue19482.go
@@ -22,13 +22,13 @@ func ok() {
var (
y = T{"stare"}
- w = T{_: "look"} // ERROR "invalid field name _ in struct initializer"
+ w = T{_: "look"} // ERROR "invalid field name _ in struct initializer|expected struct field name"
_ = T{"page"}
- _ = T{_: "out"} // ERROR "invalid field name _ in struct initializer"
+ _ = T{_: "out"} // ERROR "invalid field name _ in struct initializer|expected struct field name"
)
func bad() {
- var z = T{_: "verse"} // ERROR "invalid field name _ in struct initializer"
+ var z = T{_: "verse"} // ERROR "invalid field name _ in struct initializer|expected struct field name"
_ = z
- _ = T{_: "itinerary"} // ERROR "invalid field name _ in struct initializer"
+ _ = T{_: "itinerary"} // ERROR "invalid field name _ in struct initializer|expected struct field name"
}
diff --git a/test/fixedbugs/issue19658.go b/test/fixedbugs/issue19658.go
index b2539629df..bab409c6c0 100644
--- a/test/fixedbugs/issue19658.go
+++ b/test/fixedbugs/issue19658.go
@@ -1,4 +1,4 @@
-// +build !nacl,!js
+// +build !nacl,!js,!gccgo
// run
// Copyright 2017 The Go Authors. All rights reserved.
diff --git a/test/fixedbugs/issue19667.go b/test/fixedbugs/issue19667.go
index c94a11d871..e33e350487 100644
--- a/test/fixedbugs/issue19667.go
+++ b/test/fixedbugs/issue19667.go
@@ -9,5 +9,5 @@
package p
func f() {
- if err := http.ListenAndServe(
-} // ERROR "unexpected }, expecting expression"
+ if err := http.ListenAndServe( // GCCGO_ERROR "undefined name"
+} // ERROR "unexpected }, expecting expression|expected operand|missing .*\)|expected .*;|expected .*{"
diff --git a/test/fixedbugs/issue19880.go b/test/fixedbugs/issue19880.go
index 629c95d960..3d83cf3a12 100644
--- a/test/fixedbugs/issue19880.go
+++ b/test/fixedbugs/issue19880.go
@@ -11,7 +11,7 @@ type T struct {
}
func a() {
- _ = T // ERROR "type T is not an expression"
+ _ = T // ERROR "type T is not an expression|invalid use of type"
}
func b() {
diff --git a/test/fixedbugs/issue19977.go b/test/fixedbugs/issue19977.go
index 3db1dfd636..6e4a9cc422 100644
--- a/test/fixedbugs/issue19977.go
+++ b/test/fixedbugs/issue19977.go
@@ -9,7 +9,7 @@
package foo
func Foo() {
- switch x := a.(type) { // ERROR "undefined: a"
+ switch x := a.(type) { // ERROR "undefined: a|reference to undefined name .*a"
default:
_ = x
}
diff --git a/test/fixedbugs/issue20185.go b/test/fixedbugs/issue20185.go
index 2cbb143ed0..9065868d7f 100644
--- a/test/fixedbugs/issue20185.go
+++ b/test/fixedbugs/issue20185.go
@@ -10,7 +10,7 @@
package p
func F() {
- switch t := nil.(type) { // ERROR "cannot type switch on non-interface value nil"
+ switch t := nil.(type) { // ERROR "cannot type switch on non-interface value"
default:
_ = t
}
@@ -19,7 +19,7 @@ func F() {
const x = 1
func G() {
- switch t := x.(type) { // ERROR "cannot type switch on non-interface value x \(type untyped int\)"
+ switch t := x.(type) { // ERROR "cannot type switch on non-interface value|declared but not used"
default:
}
}
diff --git a/test/fixedbugs/issue20227.go b/test/fixedbugs/issue20227.go
index 4448eb5438..f59923106d 100644
--- a/test/fixedbugs/issue20227.go
+++ b/test/fixedbugs/issue20227.go
@@ -8,9 +8,9 @@
package p
-var _ = 1 / 1e-600000000i // ERROR "complex division by zero"
-var _ = 1i / 1e-600000000 // ERROR "complex division by zero"
-var _ = 1i / 1e-600000000i // ERROR "complex division by zero"
+var _ = 1 / 1e-600000000i // ERROR "division by zero"
+var _ = 1i / 1e-600000000 // ERROR "division by zero"
+var _ = 1i / 1e-600000000i // ERROR "division by zero"
-var _ = 1 / (1e-600000000 + 1e-600000000i) // ERROR "complex division by zero"
-var _ = 1i / (1e-600000000 + 1e-600000000i) // ERROR "complex division by zero"
+var _ = 1 / (1e-600000000 + 1e-600000000i) // ERROR "division by zero"
+var _ = 1i / (1e-600000000 + 1e-600000000i) // ERROR "division by zero"
diff --git a/test/fixedbugs/issue20415.go b/test/fixedbugs/issue20415.go
index 5ad085564b..1d9a745ab4 100644
--- a/test/fixedbugs/issue20415.go
+++ b/test/fixedbugs/issue20415.go
@@ -11,7 +11,7 @@ package p
// 1
var f byte
-var f interface{} // ERROR "issue20415.go:12: previous declaration"
+var f interface{} // ERROR "issue20415.go:12: previous declaration|redefinition"
func _(f int) {
}
@@ -22,7 +22,7 @@ var g byte
func _(g int) {
}
-var g interface{} // ERROR "issue20415.go:20: previous declaration"
+var g interface{} // ERROR "issue20415.go:20: previous declaration|redefinition"
// 3
func _(h int) {
@@ -30,4 +30,4 @@ func _(h int) {
var h byte
-var h interface{} // ERROR "issue20415.go:31: previous declaration"
+var h interface{} // ERROR "issue20415.go:31: previous declaration|redefinition"
diff --git a/test/fixedbugs/issue20529.go b/test/fixedbugs/issue20529.go
index 669064c2ea..eeaaf37358 100644
--- a/test/fixedbugs/issue20529.go
+++ b/test/fixedbugs/issue20529.go
@@ -15,7 +15,7 @@ package p
import "runtime"
-func f() { // ERROR "stack frame too large"
+func f() { // GC_ERROR "stack frame too large"
x := [][]int{1e9: []int{}}
runtime.KeepAlive(x)
}
diff --git a/test/fixedbugs/issue20602.go b/test/fixedbugs/issue20602.go
index ca4ce095aa..d4d513b050 100644
--- a/test/fixedbugs/issue20602.go
+++ b/test/fixedbugs/issue20602.go
@@ -10,5 +10,5 @@
package p
var p = &[1]complex128{0}
-var _ = real(p) // ERROR "type \*\[1\]complex128"
-var _ = imag(p) // ERROR "type \*\[1\]complex128"
+var _ = real(p) // ERROR "type \*\[1\]complex128|argument must have complex type"
+var _ = imag(p) // ERROR "type \*\[1\]complex128|argument must have complex type"
diff --git a/test/fixedbugs/issue20749.go b/test/fixedbugs/issue20749.go
index af9ff3fbed..de2d3ad16a 100644
--- a/test/fixedbugs/issue20749.go
+++ b/test/fixedbugs/issue20749.go
@@ -9,7 +9,7 @@ package p
// Verify that the compiler complains even if the array
// has length 0.
var a [0]int
-var _ = a[2:] // ERROR "invalid slice index 2"
+var _ = a[2:] // ERROR "invalid slice index 2|array index out of bounds"
var b [1]int
-var _ = b[2:] // ERROR "invalid slice index 2"
+var _ = b[2:] // ERROR "invalid slice index 2|array index out of bounds"
diff --git a/test/fixedbugs/issue20780.go b/test/fixedbugs/issue20780.go
index 58952e53ee..53c4f615e1 100644
--- a/test/fixedbugs/issue20780.go
+++ b/test/fixedbugs/issue20780.go
@@ -9,7 +9,7 @@
package main
-func f() { // ERROR "stack frame too large"
+func f() { // GC_ERROR "stack frame too large"
var x [800e6]byte
g(x)
return
diff --git a/test/fixedbugs/issue20812.go b/test/fixedbugs/issue20812.go
index 0175eede17..d0df831dfd 100644
--- a/test/fixedbugs/issue20812.go
+++ b/test/fixedbugs/issue20812.go
@@ -7,9 +7,9 @@
package p
func f() {
- _ = int("1") // ERROR "cannot convert"
- _ = bool(0) // ERROR "cannot convert"
- _ = bool("false") // ERROR "cannot convert"
- _ = int(false) // ERROR "cannot convert"
- _ = string(true) // ERROR "cannot convert"
+ _ = int("1") // ERROR "cannot convert|invalid type conversion"
+ _ = bool(0) // ERROR "cannot convert|invalid type conversion"
+ _ = bool("false") // ERROR "cannot convert|invalid type conversion"
+ _ = int(false) // ERROR "cannot convert|invalid type conversion"
+ _ = string(true) // ERROR "cannot convert|invalid type conversion"
}
diff --git a/test/fixedbugs/issue20813.go b/test/fixedbugs/issue20813.go
index b931aea592..b147a8903c 100644
--- a/test/fixedbugs/issue20813.go
+++ b/test/fixedbugs/issue20813.go
@@ -7,5 +7,5 @@
package p
func f() {
- 1 = 2 // ERROR "cannot assign to 1"
+ 1 = 2 // ERROR "cannot assign to 1|invalid left hand side"
}
diff --git a/test/fixedbugs/issue21256.go b/test/fixedbugs/issue21256.go
index 3d3612478d..c845ec52b3 100644
--- a/test/fixedbugs/issue21256.go
+++ b/test/fixedbugs/issue21256.go
@@ -6,4 +6,4 @@
package main
-var main = func() {} // ERROR "must be func"
+var main = func() {} // ERROR "must be func|redefinition"
diff --git a/test/fixedbugs/issue21273.go b/test/fixedbugs/issue21273.go
index 7a790d14b5..77a1abad9b 100644
--- a/test/fixedbugs/issue21273.go
+++ b/test/fixedbugs/issue21273.go
@@ -24,5 +24,5 @@ func g() {
func h() {
type T4 struct{ m map[T4]int } // ERROR "invalid map key"
- type _ map[T4]int // ERROR "invalid map key"
+ type _ map[T4]int // GC_ERROR "invalid map key"
}
diff --git a/test/fixedbugs/issue21317.go b/test/fixedbugs/issue21317.go
index f4ec422371..32b660c163 100644
--- a/test/fixedbugs/issue21317.go
+++ b/test/fixedbugs/issue21317.go
@@ -1,3 +1,4 @@
+// +build !js,gc
// run
// Copyright 2017 The Go Authors. All rights reserved.
@@ -16,15 +17,10 @@ import (
"log"
"os"
"os/exec"
- "runtime"
"strings"
)
func main() {
- if runtime.Compiler != "gc" || runtime.GOOS == "js" {
- return
- }
-
f, err := ioutil.TempFile("", "issue21317.go")
if err != nil {
log.Fatal(err)
diff --git a/test/fixedbugs/issue21576.go b/test/fixedbugs/issue21576.go
index ae6161ccf5..3f9b1ba008 100644
--- a/test/fixedbugs/issue21576.go
+++ b/test/fixedbugs/issue21576.go
@@ -1,6 +1,6 @@
// run
-// +build !nacl,!js
+// +build !nacl,!js,!gccgo
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
diff --git a/test/fixedbugs/issue21979.go b/test/fixedbugs/issue21979.go
index 1c02f574c3..addf786c03 100644
--- a/test/fixedbugs/issue21979.go
+++ b/test/fixedbugs/issue21979.go
@@ -7,39 +7,39 @@
package p
func f() {
- _ = bool("") // ERROR "cannot convert .. \(type untyped string\) to type bool"
- _ = bool(1) // ERROR "cannot convert 1 \(type untyped int\) to type bool"
- _ = bool(1.0) // ERROR "cannot convert 1 \(type untyped float\) to type bool"
- _ = bool(-4 + 2i) // ERROR "cannot convert -4 \+ 2i \(type untyped complex\) to type bool"
+ _ = bool("") // ERROR "cannot convert .. \(type untyped string\) to type bool|invalid type conversion"
+ _ = bool(1) // ERROR "cannot convert 1 \(type untyped int\) to type bool|invalid type conversion"
+ _ = bool(1.0) // ERROR "cannot convert 1 \(type untyped float\) to type bool|invalid type conversion"
+ _ = bool(-4 + 2i) // ERROR "cannot convert -4 \+ 2i \(type untyped complex\) to type bool|invalid type conversion"
- _ = string(true) // ERROR "cannot convert true \(type untyped bool\) to type string"
+ _ = string(true) // ERROR "cannot convert true \(type untyped bool\) to type string|invalid type conversion"
_ = string(-1)
- _ = string(1.0) // ERROR "cannot convert 1 \(type untyped float\) to type string"
- _ = string(-4 + 2i) // ERROR "cannot convert -4 \+ 2i \(type untyped complex\) to type string"
+ _ = string(1.0) // ERROR "cannot convert 1 \(type untyped float\) to type string|invalid type conversion"
+ _ = string(-4 + 2i) // ERROR "cannot convert -4 \+ 2i \(type untyped complex\) to type string|invalid type conversion"
- _ = int("") // ERROR "cannot convert .. \(type untyped string\) to type int"
- _ = int(true) // ERROR "cannot convert true \(type untyped bool\) to type int"
+ _ = int("") // ERROR "cannot convert .. \(type untyped string\) to type int|invalid type conversion"
+ _ = int(true) // ERROR "cannot convert true \(type untyped bool\) to type int|invalid type conversion"
_ = int(-1)
_ = int(1)
_ = int(1.0)
_ = int(-4 + 2i) // ERROR "truncated to integer"
- _ = uint("") // ERROR "cannot convert .. \(type untyped string\) to type uint"
- _ = uint(true) // ERROR "cannot convert true \(type untyped bool\) to type uint"
- _ = uint(-1) // ERROR "constant -1 overflows uint"
+ _ = uint("") // ERROR "cannot convert .. \(type untyped string\) to type uint|invalid type conversion"
+ _ = uint(true) // ERROR "cannot convert true \(type untyped bool\) to type uint|invalid type conversion"
+ _ = uint(-1) // ERROR "constant -1 overflows uint|integer constant overflow"
_ = uint(1)
_ = uint(1.0)
_ = uint(-4 + 2i) // ERROR "constant -4 overflows uint" "truncated to integer"
- _ = float64("") // ERROR "cannot convert .. \(type untyped string\) to type float64"
- _ = float64(true) // ERROR "cannot convert true \(type untyped bool\) to type float64"
+ _ = float64("") // ERROR "cannot convert .. \(type untyped string\) to type float64|invalid type conversion"
+ _ = float64(true) // ERROR "cannot convert true \(type untyped bool\) to type float64|invalid type conversion"
_ = float64(-1)
_ = float64(1)
_ = float64(1.0)
- _ = float64(-4 + 2i) // ERROR "truncated to real"
+ _ = float64(-4 + 2i) // ERROR "truncated to"
- _ = complex128("") // ERROR "cannot convert .. \(type untyped string\) to type complex128"
- _ = complex128(true) // ERROR "cannot convert true \(type untyped bool\) to type complex128"
+ _ = complex128("") // ERROR "cannot convert .. \(type untyped string\) to type complex128|invalid type conversion"
+ _ = complex128(true) // ERROR "cannot convert true \(type untyped bool\) to type complex128|invalid type conversion"
_ = complex128(-1)
_ = complex128(1)
_ = complex128(1.0)
diff --git a/test/fixedbugs/issue21988.go b/test/fixedbugs/issue21988.go
index 850e0398d6..4dbf06ee31 100644
--- a/test/fixedbugs/issue21988.go
+++ b/test/fixedbugs/issue21988.go
@@ -8,7 +8,7 @@
package p
-const X = Wrong(0) // ERROR "undefined: Wrong"
+const X = Wrong(0) // ERROR "undefined: Wrong|undefined name .*Wrong"
func _() {
switch 0 {
diff --git a/test/fixedbugs/issue22063.go b/test/fixedbugs/issue22063.go
index bfdb2e0027..8d84047e07 100644
--- a/test/fixedbugs/issue22063.go
+++ b/test/fixedbugs/issue22063.go
@@ -8,7 +8,7 @@
package p
-const X = Wrong(0) // ERROR "undefined: Wrong"
+const X = Wrong(0) // ERROR "undefined: Wrong|reference to undefined name .*Wrong"
func _() {
switch interface{}(nil) {
diff --git a/test/fixedbugs/issue22200.go b/test/fixedbugs/issue22200.go
index 66b9538e03..37440d9bf0 100644
--- a/test/fixedbugs/issue22200.go
+++ b/test/fixedbugs/issue22200.go
@@ -12,7 +12,7 @@ func f1(x *[1<<30 - 1e6]byte) byte {
}
return 0
}
-func f2(x *[1<<30 + 1e6]byte) byte { // ERROR "stack frame too large"
+func f2(x *[1<<30 + 1e6]byte) byte { // GC_ERROR "stack frame too large"
for _, b := range *x {
return b
}
diff --git a/test/fixedbugs/issue22200b.go b/test/fixedbugs/issue22200b.go
index 8d4515eb05..ce20923334 100644
--- a/test/fixedbugs/issue22200b.go
+++ b/test/fixedbugs/issue22200b.go
@@ -8,19 +8,19 @@
package p
-func f3(x *[1 << 31]byte) byte { // ERROR "stack frame too large"
+func f3(x *[1 << 31]byte) byte { // GC_ERROR "stack frame too large"
for _, b := range *x {
return b
}
return 0
}
-func f4(x *[1 << 32]byte) byte { // ERROR "stack frame too large"
+func f4(x *[1 << 32]byte) byte { // GC_ERROR "stack frame too large"
for _, b := range *x {
return b
}
return 0
}
-func f5(x *[1 << 33]byte) byte { // ERROR "stack frame too large"
+func f5(x *[1 << 33]byte) byte { // GC_ERROR "stack frame too large"
for _, b := range *x {
return b
}
diff --git a/test/fixedbugs/issue22660.go b/test/fixedbugs/issue22660.go
index 44ba42ac96..9ce9c4d732 100644
--- a/test/fixedbugs/issue22660.go
+++ b/test/fixedbugs/issue22660.go
@@ -1,3 +1,4 @@
+// +build !js,gc
// run
// Copyright 2017 The Go Authors. All rights reserved.
@@ -14,15 +15,10 @@ import (
"os"
"os/exec"
"path/filepath"
- "runtime"
"strings"
)
func main() {
- if runtime.GOOS == "js" {
- return // no file system available on builders
- }
-
f, err := ioutil.TempFile("", "issue22660.go")
if err != nil {
log.Fatal(err)
diff --git a/test/fixedbugs/issue22662b.go b/test/fixedbugs/issue22662b.go
index 0fcfe8d0db..8da17679be 100644
--- a/test/fixedbugs/issue22662b.go
+++ b/test/fixedbugs/issue22662b.go
@@ -1,3 +1,4 @@
+// +build !js,gc
// run
// Copyright 2018 The Go Authors. All rights reserved.
@@ -13,7 +14,6 @@ import (
"log"
"os"
"os/exec"
- "runtime"
"strings"
)
@@ -36,10 +36,6 @@ var tests = []struct {
}
func main() {
- if runtime.GOOS == "js" {
- return // can not exec go tool
- }
-
f, err := ioutil.TempFile("", "issue22662b.go")
if err != nil {
log.Fatal(err)
diff --git a/test/fixedbugs/issue22794.go b/test/fixedbugs/issue22794.go
index c7e9eb1224..2ac31ef0c7 100644
--- a/test/fixedbugs/issue22794.go
+++ b/test/fixedbugs/issue22794.go
@@ -13,8 +13,8 @@ type it struct {
func main() {
i1 := it{Floats: true}
- if i1.floats { // ERROR "(type it .* field or method floats, but does have Floats)"
+ if i1.floats { // ERROR "(type it .* field or method floats, but does have Floats)|undefined field or method"
}
- i2 := &it{floats: false} // ERROR "(but does have Floats)"
- _ = &it{InneR: "foo"} // ERROR "(but does have inner)"
+ i2 := &it{floats: false} // ERROR "(but does have Floats)|unknown field|declared but not used"
+ _ = &it{InneR: "foo"} // ERROR "(but does have inner)|unknown field"
}
diff --git a/test/fixedbugs/issue22822.go b/test/fixedbugs/issue22822.go
index 0e838cb597..dc86c97fe5 100644
--- a/test/fixedbugs/issue22822.go
+++ b/test/fixedbugs/issue22822.go
@@ -12,7 +12,7 @@ package main
func F() {
slice := []int{1, 2, 3}
len := int(2)
- println(len(slice)) // ERROR "cannot call non-function len .type int., declared at LINE-1"
+ println(len(slice)) // ERROR "cannot call non-function len .type int., declared at LINE-1|expected function"
const iota = 1
- println(iota(slice)) // ERROR "cannot call non-function iota .type int., declared at LINE-1"
+ println(iota(slice)) // ERROR "cannot call non-function iota .type int., declared at LINE-1|expected function"
}
diff --git a/test/fixedbugs/issue22904.go b/test/fixedbugs/issue22904.go
index 09f4a2118e..02459c6a4e 100644
--- a/test/fixedbugs/issue22904.go
+++ b/test/fixedbugs/issue22904.go
@@ -10,7 +10,7 @@
package p
type a struct{ b } // ERROR "invalid recursive type"
-type b struct{ a }
+type b struct{ a } // GCCGO_ERROR "invalid recursive type"
var x interface{}
diff --git a/test/fixedbugs/issue22921.go b/test/fixedbugs/issue22921.go
index 04f78b2c08..5336ba3410 100644
--- a/test/fixedbugs/issue22921.go
+++ b/test/fixedbugs/issue22921.go
@@ -8,11 +8,11 @@ package main
import "bytes"
-type _ struct{ bytes.nonexist } // ERROR "unexported"
+type _ struct{ bytes.nonexist } // ERROR "unexported|undefined"
-type _ interface{ bytes.nonexist } // ERROR "unexported"
+type _ interface{ bytes.nonexist } // ERROR "unexported|undefined|expected signature or type name"
func main() {
var _ bytes.Buffer
- var _ bytes.buffer // ERROR "unexported"
+ var _ bytes.buffer // ERROR "unexported|undefined"
}
diff --git a/test/fixedbugs/issue23093.go b/test/fixedbugs/issue23093.go
index 2fd7d5fff1..7b2865ca41 100644
--- a/test/fixedbugs/issue23093.go
+++ b/test/fixedbugs/issue23093.go
@@ -6,4 +6,4 @@
package p
-var f = func() { f() } // ERROR "initialization loop"
+var f = func() { f() } // ERROR "initialization loop|initialization expression for .*f.* depends upon itself"
diff --git a/test/fixedbugs/issue23732.go b/test/fixedbugs/issue23732.go
index 5e63eb2074..db2d182234 100644
--- a/test/fixedbugs/issue23732.go
+++ b/test/fixedbugs/issue23732.go
@@ -21,22 +21,22 @@ type Bar struct {
}
func main() {
- _ = Foo{
+ _ = Foo{ // GCCGO_ERROR "too few expressions"
1,
2,
- 3, // ERROR "too few values in Foo{...}"
+ 3, // GC_ERROR "too few values in Foo{...}"
}
_ = Foo{
1,
2,
3,
- Bar{"A", "B"}, // ERROR "too many values in Bar{...}"
+ Bar{"A", "B"}, // ERROR "too many values in Bar{...}|too many expressions"
}
- _ = Foo{
+ _ = Foo{ // GCCGO_ERROR "too few expressions"
1,
2,
- Bar{"A", "B"}, // ERROR "too many values in Bar{...}" "too few values in Foo{...}"
+ Bar{"A", "B"}, // ERROR "too many values in Bar{...}|too many expressions" "too few values in Foo{...}"
}
}
diff --git a/test/fixedbugs/issue23823.go b/test/fixedbugs/issue23823.go
index fe6cef1fb4..067a8f1638 100644
--- a/test/fixedbugs/issue23823.go
+++ b/test/fixedbugs/issue23823.go
@@ -11,6 +11,6 @@ type I1 = interface {
}
// BAD: type loop should mention I1; see also #41669
-type I2 interface { // ERROR "invalid recursive type I2\n\tLINE: I2 refers to\n\tLINE: I2$"
- I1
+type I2 interface { // GC_ERROR "invalid recursive type I2\n\tLINE: I2 refers to\n\tLINE: I2$"
+ I1 // GCCGO_ERROR "invalid recursive interface"
}
diff --git a/test/fixedbugs/issue24339.go b/test/fixedbugs/issue24339.go
index 502c575ec8..2cca7f8bda 100644
--- a/test/fixedbugs/issue24339.go
+++ b/test/fixedbugs/issue24339.go
@@ -17,4 +17,4 @@ var _ = struct{}{ /*line :20:1*/foo /*line :21:1*/: /*line :22:1*/0 }
-// ERROR "unknown field 'foo'"
\ No newline at end of file
+// ERROR "unknown field 'foo'"
diff --git a/test/fixedbugs/issue25507.go b/test/fixedbugs/issue25507.go
index 8dcbae16ab..9143a73397 100644
--- a/test/fixedbugs/issue25507.go
+++ b/test/fixedbugs/issue25507.go
@@ -16,14 +16,14 @@ type large struct {
b [1500000000]byte
}
-func (x large) f1() int { // ERROR "stack frame too large"
+func (x large) f1() int { // GC_ERROR "stack frame too large"
return 5
}
-func f2(x large) int { // ERROR "stack frame too large"
+func f2(x large) int { // GC_ERROR "stack frame too large"
return 5
}
-func f3() (x large, i int) { // ERROR "stack frame too large"
+func f3() (x large, i int) { // GC_ERROR "stack frame too large"
return
}
diff --git a/test/fixedbugs/issue25727.go b/test/fixedbugs/issue25727.go
index da7c94cc12..936b9f8ff5 100644
--- a/test/fixedbugs/issue25727.go
+++ b/test/fixedbugs/issue25727.go
@@ -9,13 +9,13 @@ package main
import "net/http"
var s = http.Server{}
-var _ = s.doneChan // ERROR "s.doneChan undefined .cannot refer to unexported field or method doneChan.$"
-var _ = s.DoneChan // ERROR "s.DoneChan undefined .type http.Server has no field or method DoneChan.$"
-var _ = http.Server{tlsConfig: nil} // ERROR "unknown field 'tlsConfig' in struct literal.+ .but does have TLSConfig.$"
-var _ = http.Server{DoneChan: nil} // ERROR "unknown field 'DoneChan' in struct literal of type http.Server$"
+var _ = s.doneChan // ERROR "s.doneChan undefined .cannot refer to unexported field or method doneChan.$|unexported field or method"
+var _ = s.DoneChan // ERROR "s.DoneChan undefined .type http.Server has no field or method DoneChan.$|undefined field or method"
+var _ = http.Server{tlsConfig: nil} // ERROR "unknown field 'tlsConfig' in struct literal.+ .but does have TLSConfig.$|unknown field .?tlsConfig.? in .?http.Server"
+var _ = http.Server{DoneChan: nil} // ERROR "unknown field 'DoneChan' in struct literal of type http.Server$|unknown field .?DoneChan.? in .?http.Server"
type foo struct {
bar int
}
-var _ = &foo{bAr: 10} // ERROR "unknown field 'bAr' in struct literal.+ .but does have bar.$"
+var _ = &foo{bAr: 10} // ERROR "unknown field 'bAr' in struct literal.+ .but does have bar.$|unknown field .?bAr.? in .?foo"
diff --git a/test/fixedbugs/issue25958.go b/test/fixedbugs/issue25958.go
index ba7ee82230..90fcee15fd 100644
--- a/test/fixedbugs/issue25958.go
+++ b/test/fixedbugs/issue25958.go
@@ -11,7 +11,7 @@ package p
func f(done chan struct{}) {
select {
- case done: // ERROR "must be receive", "not used"
- case (chan struct{})(done): // ERROR "must be receive"
+ case done: // ERROR "must be receive|expected .*<-.* or .*=" "not used"
+ case (chan struct{})(done): // ERROR "must be receive|expected .*<-.* or .*="
}
}
diff --git a/test/fixedbugs/issue26416.go b/test/fixedbugs/issue26416.go
index bc37fd9d3a..44a4fc73b7 100644
--- a/test/fixedbugs/issue26416.go
+++ b/test/fixedbugs/issue26416.go
@@ -21,7 +21,7 @@ type t3 struct {
}
var (
- _ = t2{t1f1: 600} // ERROR "cannot use promoted field t1.t1f1 in struct literal of type t2"
- _ = t3{t1f2: 800} // ERROR "cannot use promoted field t2.t1.t1f2 in struct literal of type t3"
- _ = t3{t2f1: 900} // ERROR "cannot use promoted field t2.t2f1 in struct literal of type t3"
+ _ = t2{t1f1: 600} // ERROR "cannot use promoted field t1.t1f1 in struct literal of type t2|unknown field"
+ _ = t3{t1f2: 800} // ERROR "cannot use promoted field t2.t1.t1f2 in struct literal of type t3|unknown field"
+ _ = t3{t2f1: 900} // ERROR "cannot use promoted field t2.t2f1 in struct literal of type t3|unknown field"
)
diff --git a/test/fixedbugs/issue26616.go b/test/fixedbugs/issue26616.go
index e5565b68ca..87c0293661 100644
--- a/test/fixedbugs/issue26616.go
+++ b/test/fixedbugs/issue26616.go
@@ -6,13 +6,13 @@
package p
-var x int = three() // ERROR "assignment mismatch: 1 variable but three returns 3 values"
+var x int = three() // ERROR "assignment mismatch: 1 variable but three returns 3 values|multiple-value function call in single-value context"
func f() {
- var _ int = three() // ERROR "assignment mismatch: 1 variable but three returns 3 values"
- var a int = three() // ERROR "assignment mismatch: 1 variable but three returns 3 values"
- a = three() // ERROR "assignment mismatch: 1 variable but three returns 3 values"
- b := three() // ERROR "assignment mismatch: 1 variable but three returns 3 values"
+ var _ int = three() // ERROR "assignment mismatch: 1 variable but three returns 3 values|multiple-value function call in single-value context"
+ var a int = three() // ERROR "assignment mismatch: 1 variable but three returns 3 values|multiple-value function call in single-value context"
+ a = three() // ERROR "assignment mismatch: 1 variable but three returns 3 values|multiple-value function call in single-value context"
+ b := three() // ERROR "assignment mismatch: 1 variable but three returns 3 values|single variable set to multiple-value|multiple-value function call in single-value context"
_, _ = a, b
}
diff --git a/test/fixedbugs/issue26855.go b/test/fixedbugs/issue26855.go
index 144e4415f7..b965635a65 100644
--- a/test/fixedbugs/issue26855.go
+++ b/test/fixedbugs/issue26855.go
@@ -20,9 +20,9 @@ type P struct {
type T struct{}
var _ = S{
- f: &T{}, // ERROR "cannot use &T{}"
+ f: &T{}, // ERROR "cannot use &T{}|incompatible type"
}
var _ = P{
- f: T{}, // ERROR "cannot use T{}"
+ f: T{}, // ERROR "cannot use T{}|incompatible type"
}
diff --git a/test/fixedbugs/issue27356.go b/test/fixedbugs/issue27356.go
index 42784876a5..c3e686df33 100644
--- a/test/fixedbugs/issue27356.go
+++ b/test/fixedbugs/issue27356.go
@@ -11,9 +11,9 @@ package p
var a = []int{1,2,3}
func _(len int) {
- _ = len(a) // ERROR "cannot call non-function"
+ _ = len(a) // ERROR "cannot call non-function|expected function"
}
var cap = false
-var _ = cap(a) // ERROR "cannot call non-function"
+var _ = cap(a) // ERROR "cannot call non-function|expected function"
diff --git a/test/fixedbugs/issue27938.go b/test/fixedbugs/issue27938.go
index b0007be928..ed974e642d 100644
--- a/test/fixedbugs/issue27938.go
+++ b/test/fixedbugs/issue27938.go
@@ -11,13 +11,13 @@
package p
type _ struct {
- F sync.Mutex // ERROR "undefined: sync"
+ F sync.Mutex // ERROR "undefined: sync|expected package"
}
type _ struct {
- sync.Mutex // ERROR "undefined: sync"
+ sync.Mutex // ERROR "undefined: sync|expected package"
}
type _ interface {
- sync.Mutex // ERROR "undefined: sync"
+ sync.Mutex // ERROR "undefined: sync|expected package|expected signature or type name"
}
diff --git a/test/fixedbugs/issue28079b.go b/test/fixedbugs/issue28079b.go
index 9ff221baff..54c9db994b 100644
--- a/test/fixedbugs/issue28079b.go
+++ b/test/fixedbugs/issue28079b.go
@@ -10,8 +10,8 @@ package p
import "unsafe"
-type T [uintptr(unsafe.Pointer(nil))]int // ERROR "non-constant array bound"
+type T [uintptr(unsafe.Pointer(nil))]int // ERROR "non-constant array bound|array bound is not constant"
func f() {
- _ = complex(1<= 0 {
- return 1 // ERROR "not enough arguments to return\n\thave \(number\)\n\twant \(int, int, int, int\)"
+ return 1 // ERROR "not enough arguments to return\n\thave \(number\)\n\twant \(int, int, int, int\)|not enough arguments to return"
}
- return 2, 3 // ERROR "not enough arguments to return\n\thave \(number, number\)\n\twant \(int, int, int, int\)"
+ return 2, 3 // ERROR "not enough arguments to return\n\thave \(number, number\)\n\twant \(int, int, int, int\)|not enough arguments to return"
}
func foo4(name string) (string, int) {
switch name {
case "cow":
- return "moo" // ERROR "not enough arguments to return\n\thave \(string\)\n\twant \(string, int\)"
+ return "moo" // ERROR "not enough arguments to return\n\thave \(string\)\n\twant \(string, int\)|not enough arguments to return"
case "dog":
- return "dog", 10, true // ERROR "too many arguments to return\n\thave \(string, number, bool\)\n\twant \(string, int\)"
+ return "dog", 10, true // ERROR "too many arguments to return\n\thave \(string, number, bool\)\n\twant \(string, int\)|too many values in return statement"
case "fish":
- return "" // ERROR "not enough arguments to return\n\thave \(string\)\n\twant \(string, int\)"
+ return "" // ERROR "not enough arguments to return\n\thave \(string\)\n\twant \(string, int\)|not enough arguments to return"
default:
return "lizard", 10
}
@@ -40,14 +40,14 @@ type U float64
func foo5() (S, T, U) {
if false {
- return "" // ERROR "not enough arguments to return\n\thave \(string\)\n\twant \(S, T, U\)"
+ return "" // ERROR "not enough arguments to return\n\thave \(string\)\n\twant \(S, T, U\)|not enough arguments to return"
} else {
ptr := new(T)
- return ptr // ERROR "not enough arguments to return\n\thave \(\*T\)\n\twant \(S, T, U\)"
+ return ptr // ERROR "not enough arguments to return\n\thave \(\*T\)\n\twant \(S, T, U\)|not enough arguments to return"
}
- return new(S), 12.34, 1 + 0i, 'r', true // ERROR "too many arguments to return\n\thave \(\*S, number, number, number, bool\)\n\twant \(S, T, U\)"
+ return new(S), 12.34, 1 + 0i, 'r', true // ERROR "too many arguments to return\n\thave \(\*S, number, number, number, bool\)\n\twant \(S, T, U\)|too many values in return statement"
}
func foo6() (T, string) {
- return "T", true, true // ERROR "too many arguments to return\n\thave \(string, bool, bool\)\n\twant \(T, string\)"
+ return "T", true, true // ERROR "too many arguments to return\n\thave \(string, bool, bool\)\n\twant \(T, string\)|too many values in return statement"
}
diff --git a/test/fixedbugs/issue43111.go b/test/fixedbugs/issue43111.go
new file mode 100644
index 0000000000..76d7beb084
--- /dev/null
+++ b/test/fixedbugs/issue43111.go
@@ -0,0 +1,70 @@
+// run
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+var ch chan int
+var x int
+
+func f() int {
+ close(ch)
+ ch = nil
+ return 0
+}
+
+func g() int {
+ ch = nil
+ x = 0
+ return 0
+}
+
+func main() {
+ var nilch chan int
+ var v int
+ var ok bool
+ _, _ = v, ok
+
+ ch = make(chan int)
+ select {
+ case <-ch:
+ case nilch <- f():
+ }
+
+ ch = make(chan int)
+ select {
+ case v = <-ch:
+ case nilch <- f():
+ }
+
+ ch = make(chan int)
+ select {
+ case v := <-ch: _ = v
+ case nilch <- f():
+ }
+
+ ch = make(chan int)
+ select {
+ case v, ok = <-ch:
+ case nilch <- f():
+ }
+
+ ch = make(chan int)
+ select {
+ case v, ok := <-ch: _, _ = v, ok
+ case nilch <- f():
+ }
+
+ ch1 := make(chan int, 1)
+ ch = ch1
+ x = 42
+ select {
+ case ch <- x:
+ case nilch <- g():
+ }
+ if got := <-ch1; got != 42 {
+ panic(got)
+ }
+}
diff --git a/test/fixedbugs/issue43112.go b/test/fixedbugs/issue43112.go
new file mode 100644
index 0000000000..e36627a015
--- /dev/null
+++ b/test/fixedbugs/issue43112.go
@@ -0,0 +1,41 @@
+// compile
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type Symbol interface{}
+
+type Value interface {
+ String() string
+}
+
+type Object interface {
+ String() string
+}
+
+type Scope struct {
+ outer *Scope
+ elems map[string]Object
+}
+
+func (s *Scope) findouter(name string) (*Scope, Object) {
+ return s.outer.findouter(name)
+}
+
+func (s *Scope) Resolve(name string) (sym Symbol) {
+ if _, obj := s.findouter(name); obj != nil {
+ sym = obj.(Symbol)
+ }
+ return
+}
+
+type ScopeName struct {
+ scope *Scope
+}
+
+func (n *ScopeName) Get(name string) (Value, error) {
+ return n.scope.Resolve(name).(Value), nil
+}
diff --git a/test/fixedbugs/issue43292.go b/test/fixedbugs/issue43292.go
new file mode 100644
index 0000000000..02f1c69bd1
--- /dev/null
+++ b/test/fixedbugs/issue43292.go
@@ -0,0 +1,59 @@
+// run
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func main() {
+ {
+ i := I(A{})
+
+ b := make(chan I, 1)
+ b <- B{}
+
+ var ok bool
+ i, ok = <-b
+ _ = ok
+
+ i.M()
+ }
+
+ {
+ i := I(A{})
+
+ b := make(chan I, 1)
+ b <- B{}
+
+ select {
+ case i = <-b:
+ }
+
+ i.M()
+ }
+
+ {
+ i := I(A{})
+
+ b := make(chan I, 1)
+ b <- B{}
+
+ var ok bool
+ select {
+ case i, ok = <-b:
+ }
+ _ = ok
+
+ i.M()
+ }
+}
+
+type I interface{ M() int }
+
+type T int
+
+func (T) M() int { return 0 }
+
+type A struct{ T }
+type B struct{ T }
diff --git a/test/fixedbugs/issue6402.go b/test/fixedbugs/issue6402.go
index da5980c9ab..ecde9ae510 100644
--- a/test/fixedbugs/issue6402.go
+++ b/test/fixedbugs/issue6402.go
@@ -9,5 +9,5 @@
package p
func f() uintptr {
- return nil // ERROR "cannot use nil as type uintptr in return argument"
+ return nil // ERROR "cannot use nil as type uintptr in return argument|incompatible type"
}
diff --git a/test/fixedbugs/issue6403.go b/test/fixedbugs/issue6403.go
index b61e2e225d..809efefa0f 100644
--- a/test/fixedbugs/issue6403.go
+++ b/test/fixedbugs/issue6403.go
@@ -10,5 +10,5 @@ package p
import "syscall"
-const A int = syscall.X // ERROR "undefined: syscall.X"
-const B int = voidpkg.X // ERROR "undefined: voidpkg"
+const A int = syscall.X // ERROR "undefined: syscall.X|undefined identifier .*syscall.X"
+const B int = voidpkg.X // ERROR "undefined: voidpkg|undefined name .*voidpkg"
diff --git a/test/fixedbugs/issue6772.go b/test/fixedbugs/issue6772.go
index 4d0001c870..5bd15ba72e 100644
--- a/test/fixedbugs/issue6772.go
+++ b/test/fixedbugs/issue6772.go
@@ -7,14 +7,14 @@
package p
func f1() {
- for a, a := range []int{1, 2, 3} { // ERROR "a repeated on left side of :="
+ for a, a := range []int{1, 2, 3} { // ERROR "a.* repeated on left side of :="
println(a)
}
}
func f2() {
var a int
- for a, a := range []int{1, 2, 3} { // ERROR "a repeated on left side of :="
+ for a, a := range []int{1, 2, 3} { // ERROR "a.* repeated on left side of :="
println(a)
}
println(a)
diff --git a/test/fixedbugs/issue6889.go b/test/fixedbugs/issue6889.go
index 805a877d58..efd8b76148 100644
--- a/test/fixedbugs/issue6889.go
+++ b/test/fixedbugs/issue6889.go
@@ -107,5 +107,5 @@ const (
f96 = f95 * 96
f97 = f96 * 97
f98 = f97 * 98
- f99 = f98 * 99 // ERROR "overflow"
+ f99 = f98 * 99 // GC_ERROR "overflow"
)
diff --git a/test/fixedbugs/issue6964.go b/test/fixedbugs/issue6964.go
index 7ad83364ab..36a3c5bb40 100644
--- a/test/fixedbugs/issue6964.go
+++ b/test/fixedbugs/issue6964.go
@@ -7,5 +7,5 @@
package main
func main() {
- _ = string(-4 + 2i + 2) // ERROR "-4 \+ 2i"
+ _ = string(-4 + 2i + 2) // ERROR "-4 \+ 2i|invalid type conversion"
}
diff --git a/test/fixedbugs/issue7129.go b/test/fixedbugs/issue7129.go
index 2425cbd343..2765200ac8 100644
--- a/test/fixedbugs/issue7129.go
+++ b/test/fixedbugs/issue7129.go
@@ -15,7 +15,7 @@ func g() bool { return true }
func h(int, int) {}
func main() {
- f(g()) // ERROR "in argument to f"
- f(true) // ERROR "in argument to f"
- h(true, true) // ERROR "in argument to h"
+ f(g()) // ERROR "in argument to f|incompatible type"
+ f(true) // ERROR "in argument to f|incompatible type"
+ h(true, true) // ERROR "in argument to h|incompatible type"
}
diff --git a/test/fixedbugs/issue7150.go b/test/fixedbugs/issue7150.go
index 8a8a7d088f..7cddf4875e 100644
--- a/test/fixedbugs/issue7150.go
+++ b/test/fixedbugs/issue7150.go
@@ -9,9 +9,9 @@
package main
func main() {
- _ = [0]int{-1: 50} // ERROR "index must be non-negative integer constant"
- _ = [0]int{0: 0} // ERROR "index 0 out of bounds \[0:0\]"
- _ = [0]int{5: 25} // ERROR "index 5 out of bounds \[0:0\]"
- _ = [10]int{2: 10, 15: 30} // ERROR "index 15 out of bounds \[0:10\]"
- _ = [10]int{5: 5, 1: 1, 12: 12} // ERROR "index 12 out of bounds \[0:10\]"
+ _ = [0]int{-1: 50} // ERROR "index must be non-negative integer constant|index expression is negative"
+ _ = [0]int{0: 0} // ERROR "index 0 out of bounds \[0:0\]|out of range"
+ _ = [0]int{5: 25} // ERROR "index 5 out of bounds \[0:0\]|out of range"
+ _ = [10]int{2: 10, 15: 30} // ERROR "index 15 out of bounds \[0:10\]|out of range"
+ _ = [10]int{5: 5, 1: 1, 12: 12} // ERROR "index 12 out of bounds \[0:10\]|out of range"
}
diff --git a/test/fixedbugs/issue7153.go b/test/fixedbugs/issue7153.go
index 66b1338496..e8b95d5db8 100644
--- a/test/fixedbugs/issue7153.go
+++ b/test/fixedbugs/issue7153.go
@@ -8,4 +8,4 @@
package p
-var _ = []int{a: true, true} // ERROR "undefined: a" "cannot use true \(type untyped bool\) as type int in slice literal"
+var _ = []int{a: true, true} // ERROR "undefined: a" "cannot use true \(type untyped bool\) as type int in slice literal|undefined name .*a|incompatible type"
diff --git a/test/fixedbugs/issue7310.go b/test/fixedbugs/issue7310.go
index 6829d5e126..ba50e4237b 100644
--- a/test/fixedbugs/issue7310.go
+++ b/test/fixedbugs/issue7310.go
@@ -9,7 +9,7 @@
package main
func main() {
- _ = copy(nil, []int{}) // ERROR "use of untyped nil"
- _ = copy([]int{}, nil) // ERROR "use of untyped nil"
- _ = 1 + true // ERROR "mismatched types untyped int and untyped bool"
+ _ = copy(nil, []int{}) // ERROR "use of untyped nil|left argument must be a slice"
+ _ = copy([]int{}, nil) // ERROR "use of untyped nil|second argument must be slice or string"
+ _ = 1 + true // ERROR "mismatched types untyped int and untyped bool|incompatible types"
}
diff --git a/test/fixedbugs/issue7538a.go b/test/fixedbugs/issue7538a.go
index 283d9eb1ba..b1701508d8 100644
--- a/test/fixedbugs/issue7538a.go
+++ b/test/fixedbugs/issue7538a.go
@@ -11,5 +11,5 @@ package p
func f() {
_:
_:
- goto _ // ERROR "not defined"
+ goto _ // ERROR "not defined|undefined label"
}
diff --git a/test/fixedbugs/issue7675.go b/test/fixedbugs/issue7675.go
index d97ee357a2..6cda05f332 100644
--- a/test/fixedbugs/issue7675.go
+++ b/test/fixedbugs/issue7675.go
@@ -13,12 +13,12 @@ func f(string, int, float64, string)
func g(string, int, float64, ...string)
func main() {
- f(1, 0.5, "hello") // ERROR "not enough arguments"
+ f(1, 0.5, "hello") // ERROR "not enough arguments|incompatible type"
f("1", 2, 3.1, "4")
- f(1, 0.5, "hello", 4, 5) // ERROR "too many arguments"
- g(1, 0.5) // ERROR "not enough arguments"
+ f(1, 0.5, "hello", 4, 5) // ERROR "too many arguments|incompatible type"
+ g(1, 0.5) // ERROR "not enough arguments|incompatible type"
g("1", 2, 3.1)
- g(1, 0.5, []int{3, 4}...) // ERROR "not enough arguments"
+ g(1, 0.5, []int{3, 4}...) // ERROR "not enough arguments|incompatible type"
g("1", 2, 3.1, "4", "5")
- g(1, 0.5, "hello", 4, []int{5, 6}...) // ERROR "too many arguments"
+ g(1, 0.5, "hello", 4, []int{5, 6}...) // ERROR "too many arguments|truncated to integer"
}
diff --git a/test/fixedbugs/issue7746.go b/test/fixedbugs/issue7746.go
index 0dc119d2e6..745496293d 100644
--- a/test/fixedbugs/issue7746.go
+++ b/test/fixedbugs/issue7746.go
@@ -10,7 +10,7 @@ const (
c0 = 1 << 100
c1 = c0 * c0
c2 = c1 * c1
- c3 = c2 * c2 // ERROR "overflow"
+ c3 = c2 * c2 // GC_ERROR "overflow"
c4 = c3 * c3
c5 = c4 * c4
c6 = c5 * c5
@@ -21,7 +21,7 @@ const (
c11 = c10 * c10
c12 = c11 * c11
c13 = c12 * c12
- c14 = c13 * c13
+ c14 = c13 * c13 // GCCGO_ERROR "overflow"
c15 = c14 * c14
c16 = c15 * c15
c17 = c16 * c16
diff --git a/test/fixedbugs/issue7760.go b/test/fixedbugs/issue7760.go
index cccae48910..7e1d03596e 100644
--- a/test/fixedbugs/issue7760.go
+++ b/test/fixedbugs/issue7760.go
@@ -12,14 +12,14 @@ import "unsafe"
type myPointer unsafe.Pointer
-const _ = unsafe.Pointer(uintptr(1)) // ERROR "is not (a )?constant"
-const _ = myPointer(uintptr(1)) // ERROR "is not (a )?constant"
+const _ = unsafe.Pointer(uintptr(1)) // ERROR "is not (a )?constant|invalid constant type"
+const _ = myPointer(uintptr(1)) // ERROR "is not (a )?constant|invalid constant type"
-const _ = (*int)(unsafe.Pointer(uintptr(1))) // ERROR "is not (a )?constant"
-const _ = (*int)(myPointer(uintptr(1))) // ERROR "is not (a )?constant"
+const _ = (*int)(unsafe.Pointer(uintptr(1))) // ERROR "is not (a )?constant|invalid constant type"
+const _ = (*int)(myPointer(uintptr(1))) // ERROR "is not (a )?constant|invalid constant type"
-const _ = uintptr(unsafe.Pointer(uintptr(1))) // ERROR "is not (a )?constant"
-const _ = uintptr(myPointer(uintptr(1))) // ERROR "is not (a )?constant"
+const _ = uintptr(unsafe.Pointer(uintptr(1))) // ERROR "is not (a )?constant|expression is not constant"
+const _ = uintptr(myPointer(uintptr(1))) // ERROR "is not (a )?constant|expression is no constant"
-const _ = []byte("") // ERROR "is not (a )?constant"
-const _ = []rune("") // ERROR "is not (a )?constant"
+const _ = []byte("") // ERROR "is not (a )?constant|invalid constant type"
+const _ = []rune("") // ERROR "is not (a )?constant|invalid constant type"
diff --git a/test/fixedbugs/issue8183.go b/test/fixedbugs/issue8183.go
index 531dd4dbf8..caac667346 100644
--- a/test/fixedbugs/issue8183.go
+++ b/test/fixedbugs/issue8183.go
@@ -12,12 +12,12 @@ const (
ok = byte(iota + 253)
bad
barn
- bard // ERROR "constant 256 overflows byte"
+ bard // ERROR "constant 256 overflows byte|integer constant overflow"
)
const (
c = len([1 - iota]int{})
d
- e // ERROR "array bound must be non-negative"
- f // ERROR "array bound must be non-negative"
+ e // ERROR "array bound must be non-negative|negative array bound"
+ f // ERROR "array bound must be non-negative|negative array bound"
)
diff --git a/test/fixedbugs/issue8311.go b/test/fixedbugs/issue8311.go
index 375b480a17..b5fd5daea1 100644
--- a/test/fixedbugs/issue8311.go
+++ b/test/fixedbugs/issue8311.go
@@ -11,6 +11,6 @@ package p
func f() {
var x []byte
- x++ // ERROR "invalid operation: x[+][+]"
+ x++ // ERROR "invalid operation: x[+][+]|non-numeric type"
}
diff --git a/test/fixedbugs/issue8385.go b/test/fixedbugs/issue8385.go
index 6447e9f0e8..f3d395e521 100644
--- a/test/fixedbugs/issue8385.go
+++ b/test/fixedbugs/issue8385.go
@@ -27,16 +27,16 @@ func (t T) M(x int) {
func g() func(int)
func main() {
- Fooer.Foo(5, 6) // ERROR "not enough arguments in call to method expression Fooer.Foo"
+ Fooer.Foo(5, 6) // ERROR "not enough arguments in call to method expression Fooer.Foo|incompatible type|not enough arguments"
var i I
var t *T
- g()() // ERROR "not enough arguments in call to g\(\)"
- f() // ERROR "not enough arguments in call to f"
- i.M() // ERROR "not enough arguments in call to i\.M"
- I.M() // ERROR "not enough arguments in call to method expression I\.M"
- t.M() // ERROR "not enough arguments in call to t\.M"
- T.M() // ERROR "not enough arguments in call to method expression T\.M"
- (*T).M() // ERROR "not enough arguments in call to method expression \(\*T\)\.M"
+ g()() // ERROR "not enough arguments in call to g\(\)|not enough arguments"
+ f() // ERROR "not enough arguments in call to f|not enough arguments"
+ i.M() // ERROR "not enough arguments in call to i\.M|not enough arguments"
+ I.M() // ERROR "not enough arguments in call to method expression I\.M|not enough arguments"
+ t.M() // ERROR "not enough arguments in call to t\.M|not enough arguments"
+ T.M() // ERROR "not enough arguments in call to method expression T\.M|not enough arguments"
+ (*T).M() // ERROR "not enough arguments in call to method expression \(\*T\)\.M|not enough arguments"
}
diff --git a/test/fixedbugs/issue8438.go b/test/fixedbugs/issue8438.go
index 3a4f193b57..f433e36924 100644
--- a/test/fixedbugs/issue8438.go
+++ b/test/fixedbugs/issue8438.go
@@ -10,8 +10,8 @@
package main
func main() {
- _ = []byte{"foo"} // ERROR "cannot use"
- _ = []int{"foo"} // ERROR "cannot use"
- _ = []rune{"foo"} // ERROR "cannot use"
+ _ = []byte{"foo"} // ERROR "cannot use|incompatible type"
+ _ = []int{"foo"} // ERROR "cannot use|incompatible type"
+ _ = []rune{"foo"} // ERROR "cannot use|incompatible type"
_ = []string{"foo"} // OK
}
diff --git a/test/fixedbugs/issue8440.go b/test/fixedbugs/issue8440.go
index f9b1dea3eb..e9c5b54d51 100644
--- a/test/fixedbugs/issue8440.go
+++ b/test/fixedbugs/issue8440.go
@@ -7,5 +7,5 @@
package main
func main() {
- n.foo = 6 // ERROR "undefined: n in n.foo"
+ n.foo = 6 // ERROR "undefined: n in n.foo|undefined name .*n"
}
diff --git a/test/fixedbugs/issue8507.go b/test/fixedbugs/issue8507.go
index ad6ba8ac68..392ecf4063 100644
--- a/test/fixedbugs/issue8507.go
+++ b/test/fixedbugs/issue8507.go
@@ -9,7 +9,7 @@
package p
-type T struct{ T } // ERROR "invalid recursive type T"
+type T struct{ T } // ERROR "invalid recursive type .*T"
func f() {
println(T{} == T{})
diff --git a/test/fixedbugs/issue9036.go b/test/fixedbugs/issue9036.go
index 38f06c30c8..e3d394f7f2 100644
--- a/test/fixedbugs/issue9036.go
+++ b/test/fixedbugs/issue9036.go
@@ -18,8 +18,8 @@ const (
)
const x4 = 0x1p10 // valid hexadecimal float
-const x5 = 1p10 // ERROR "'p' exponent requires hexadecimal mantissa"
-const x6 = 0P0 // ERROR "'P' exponent requires hexadecimal mantissa"
+const x5 = 1p10 // ERROR "'p' exponent requires hexadecimal mantissa|invalid prefix"
+const x6 = 0P0 // ERROR "'P' exponent requires hexadecimal mantissa|invalid prefix"
func main() {
fmt.Printf("%g %T\n", x1, x1)
diff --git a/test/fixedbugs/issue9076.go b/test/fixedbugs/issue9076.go
index 8daf12fee8..1613d5ede3 100644
--- a/test/fixedbugs/issue9076.go
+++ b/test/fixedbugs/issue9076.go
@@ -11,5 +11,5 @@ package main
import "unsafe"
const Hundred = 100
-var _ int32 = 100/unsafe.Sizeof(int(0)) + 1 // GC_ERROR "100 \/ unsafe.Sizeof\(int\(0\)\) \+ 1"
-var _ int32 = Hundred/unsafe.Sizeof(int(0)) + 1 // GC_ERROR "Hundred \/ unsafe.Sizeof\(int\(0\)\) \+ 1"
+var _ int32 = 100/unsafe.Sizeof(int(0)) + 1 // ERROR "100 \/ unsafe.Sizeof\(int\(0\)\) \+ 1|incompatible type"
+var _ int32 = Hundred/unsafe.Sizeof(int(0)) + 1 // ERROR "Hundred \/ unsafe.Sizeof\(int\(0\)\) \+ 1|incompatible type"
diff --git a/test/fixedbugs/issue9083.go b/test/fixedbugs/issue9083.go
index 8fbd78be7a..d4762f802e 100644
--- a/test/fixedbugs/issue9083.go
+++ b/test/fixedbugs/issue9083.go
@@ -19,4 +19,5 @@ func main() {
x = make(chan int) // ERROR "cannot use make\(chan int\)|incompatible"
x = make(chan int, 0) // ERROR "cannot use make\(chan int, 0\)|incompatible"
x = make(chan int, zero) // ERROR "cannot use make\(chan int, zero\)|incompatible"
+ _ = x
}
diff --git a/test/fixedbugs/issue9355.go b/test/fixedbugs/issue9355.go
index ab3369d415..319a2a90df 100644
--- a/test/fixedbugs/issue9355.go
+++ b/test/fixedbugs/issue9355.go
@@ -1,3 +1,4 @@
+// +build !js,gc
// run
// Copyright 2014 The Go Authors. All rights reserved.
@@ -13,14 +14,9 @@ import (
"os/exec"
"path/filepath"
"regexp"
- "runtime"
)
func main() {
- if runtime.Compiler != "gc" || runtime.GOOS == "js" {
- return
- }
-
err := os.Chdir(filepath.Join("fixedbugs", "issue9355.dir"))
check(err)
diff --git a/test/fixedbugs/issue9370.go b/test/fixedbugs/issue9370.go
index 120af35397..6cc8d5b9e5 100644
--- a/test/fixedbugs/issue9370.go
+++ b/test/fixedbugs/issue9370.go
@@ -33,95 +33,95 @@ var (
var (
_ = e == c
_ = e != c
- _ = e >= c // ERROR "invalid operation.*not defined"
+ _ = e >= c // ERROR "invalid operation.*not defined|invalid comparison"
_ = c == e
_ = c != e
- _ = c >= e // ERROR "invalid operation.*not defined"
+ _ = c >= e // ERROR "invalid operation.*not defined|invalid comparison"
_ = i == c
_ = i != c
- _ = i >= c // ERROR "invalid operation.*not defined"
+ _ = i >= c // ERROR "invalid operation.*not defined|invalid comparison"
_ = c == i
_ = c != i
- _ = c >= i // ERROR "invalid operation.*not defined"
+ _ = c >= i // ERROR "invalid operation.*not defined|invalid comparison"
_ = e == n
_ = e != n
- _ = e >= n // ERROR "invalid operation.*not defined"
+ _ = e >= n // ERROR "invalid operation.*not defined|invalid comparison"
_ = n == e
_ = n != e
- _ = n >= e // ERROR "invalid operation.*not defined"
+ _ = n >= e // ERROR "invalid operation.*not defined|invalid comparison"
// i and n are not assignable to each other
- _ = i == n // ERROR "invalid operation.*mismatched types"
- _ = i != n // ERROR "invalid operation.*mismatched types"
- _ = i >= n // ERROR "invalid operation.*mismatched types"
- _ = n == i // ERROR "invalid operation.*mismatched types"
- _ = n != i // ERROR "invalid operation.*mismatched types"
- _ = n >= i // ERROR "invalid operation.*mismatched types"
+ _ = i == n // ERROR "invalid operation.*mismatched types|incompatible types"
+ _ = i != n // ERROR "invalid operation.*mismatched types|incompatible types"
+ _ = i >= n // ERROR "invalid operation.*mismatched types|incompatible types"
+ _ = n == i // ERROR "invalid operation.*mismatched types|incompatible types"
+ _ = n != i // ERROR "invalid operation.*mismatched types|incompatible types"
+ _ = n >= i // ERROR "invalid operation.*mismatched types|incompatible types"
_ = e == 1
_ = e != 1
- _ = e >= 1 // ERROR "invalid operation.*not defined"
+ _ = e >= 1 // ERROR "invalid operation.*not defined|invalid comparison"
_ = 1 == e
_ = 1 != e
- _ = 1 >= e // ERROR "invalid operation.*not defined"
+ _ = 1 >= e // ERROR "invalid operation.*not defined|invalid comparison"
- _ = i == 1 // ERROR "invalid operation.*mismatched types"
- _ = i != 1 // ERROR "invalid operation.*mismatched types"
- _ = i >= 1 // ERROR "invalid operation.*mismatched types"
- _ = 1 == i // ERROR "invalid operation.*mismatched types"
- _ = 1 != i // ERROR "invalid operation.*mismatched types"
- _ = 1 >= i // ERROR "invalid operation.*mismatched types"
+ _ = i == 1 // ERROR "invalid operation.*mismatched types|incompatible types"
+ _ = i != 1 // ERROR "invalid operation.*mismatched types|incompatible types"
+ _ = i >= 1 // ERROR "invalid operation.*mismatched types|incompatible types"
+ _ = 1 == i // ERROR "invalid operation.*mismatched types|incompatible types"
+ _ = 1 != i // ERROR "invalid operation.*mismatched types|incompatible types"
+ _ = 1 >= i // ERROR "invalid operation.*mismatched types|incompatible types"
- _ = e == f // ERROR "invalid operation.*not defined"
- _ = e != f // ERROR "invalid operation.*not defined"
- _ = e >= f // ERROR "invalid operation.*not defined"
- _ = f == e // ERROR "invalid operation.*not defined"
- _ = f != e // ERROR "invalid operation.*not defined"
- _ = f >= e // ERROR "invalid operation.*not defined"
+ _ = e == f // ERROR "invalid operation.*not defined|invalid operation"
+ _ = e != f // ERROR "invalid operation.*not defined|invalid operation"
+ _ = e >= f // ERROR "invalid operation.*not defined|invalid comparison"
+ _ = f == e // ERROR "invalid operation.*not defined|invalid operation"
+ _ = f != e // ERROR "invalid operation.*not defined|invalid operation"
+ _ = f >= e // ERROR "invalid operation.*not defined|invalid comparison"
- _ = i == f // ERROR "invalid operation.*mismatched types"
- _ = i != f // ERROR "invalid operation.*mismatched types"
- _ = i >= f // ERROR "invalid operation.*mismatched types"
- _ = f == i // ERROR "invalid operation.*mismatched types"
- _ = f != i // ERROR "invalid operation.*mismatched types"
- _ = f >= i // ERROR "invalid operation.*mismatched types"
+ _ = i == f // ERROR "invalid operation.*mismatched types|incompatible types"
+ _ = i != f // ERROR "invalid operation.*mismatched types|incompatible types"
+ _ = i >= f // ERROR "invalid operation.*mismatched types|incompatible types"
+ _ = f == i // ERROR "invalid operation.*mismatched types|incompatible types"
+ _ = f != i // ERROR "invalid operation.*mismatched types|incompatible types"
+ _ = f >= i // ERROR "invalid operation.*mismatched types|incompatible types"
- _ = e == g // ERROR "invalid operation.*not defined"
- _ = e != g // ERROR "invalid operation.*not defined"
- _ = e >= g // ERROR "invalid operation.*not defined"
- _ = g == e // ERROR "invalid operation.*not defined"
- _ = g != e // ERROR "invalid operation.*not defined"
- _ = g >= e // ERROR "invalid operation.*not defined"
+ _ = e == g // ERROR "invalid operation.*not defined|invalid operation"
+ _ = e != g // ERROR "invalid operation.*not defined|invalid operation"
+ _ = e >= g // ERROR "invalid operation.*not defined|invalid comparison"
+ _ = g == e // ERROR "invalid operation.*not defined|invalid operation"
+ _ = g != e // ERROR "invalid operation.*not defined|invalid operation"
+ _ = g >= e // ERROR "invalid operation.*not defined|invalid comparison"
- _ = i == g // ERROR "invalid operation.*not defined"
- _ = i != g // ERROR "invalid operation.*not defined"
- _ = i >= g // ERROR "invalid operation.*not defined"
- _ = g == i // ERROR "invalid operation.*not defined"
- _ = g != i // ERROR "invalid operation.*not defined"
- _ = g >= i // ERROR "invalid operation.*not defined"
+ _ = i == g // ERROR "invalid operation.*not defined|invalid operation"
+ _ = i != g // ERROR "invalid operation.*not defined|invalid operation"
+ _ = i >= g // ERROR "invalid operation.*not defined|invalid comparison"
+ _ = g == i // ERROR "invalid operation.*not defined|invalid operation"
+ _ = g != i // ERROR "invalid operation.*not defined|invalid operation"
+ _ = g >= i // ERROR "invalid operation.*not defined|invalid comparison"
- _ = _ == e // ERROR "cannot use _ as value"
- _ = _ == i // ERROR "cannot use _ as value"
- _ = _ == c // ERROR "cannot use _ as value"
- _ = _ == n // ERROR "cannot use _ as value"
- _ = _ == f // ERROR "cannot use _ as value"
- _ = _ == g // ERROR "cannot use _ as value"
+ _ = _ == e // ERROR "cannot use .*_.* as value"
+ _ = _ == i // ERROR "cannot use .*_.* as value"
+ _ = _ == c // ERROR "cannot use .*_.* as value"
+ _ = _ == n // ERROR "cannot use .*_.* as value"
+ _ = _ == f // ERROR "cannot use .*_.* as value"
+ _ = _ == g // ERROR "cannot use .*_.* as value"
- _ = e == _ // ERROR "cannot use _ as value"
- _ = i == _ // ERROR "cannot use _ as value"
- _ = c == _ // ERROR "cannot use _ as value"
- _ = n == _ // ERROR "cannot use _ as value"
- _ = f == _ // ERROR "cannot use _ as value"
- _ = g == _ // ERROR "cannot use _ as value"
+ _ = e == _ // ERROR "cannot use .*_.* as value"
+ _ = i == _ // ERROR "cannot use .*_.* as value"
+ _ = c == _ // ERROR "cannot use .*_.* as value"
+ _ = n == _ // ERROR "cannot use .*_.* as value"
+ _ = f == _ // ERROR "cannot use .*_.* as value"
+ _ = g == _ // ERROR "cannot use .*_.* as value"
- _ = _ == _ // ERROR "cannot use _ as value"
+ _ = _ == _ // ERROR "cannot use .*_.* as value"
- _ = e ^ c // ERROR "invalid operation.*mismatched types"
- _ = c ^ e // ERROR "invalid operation.*mismatched types"
- _ = 1 ^ e // ERROR "invalid operation.*mismatched types"
- _ = e ^ 1 // ERROR "invalid operation.*mismatched types"
+ _ = e ^ c // ERROR "invalid operation.*mismatched types|incompatible types"
+ _ = c ^ e // ERROR "invalid operation.*mismatched types|incompatible types"
+ _ = 1 ^ e // ERROR "invalid operation.*mismatched types|incompatible types"
+ _ = e ^ 1 // ERROR "invalid operation.*mismatched types|incompatible types"
_ = 1 ^ c
_ = c ^ 1
)
diff --git a/test/fixedbugs/issue9521.go b/test/fixedbugs/issue9521.go
index a33f0483f3..1ad40bdfda 100644
--- a/test/fixedbugs/issue9521.go
+++ b/test/fixedbugs/issue9521.go
@@ -13,6 +13,6 @@ func f() (_, _ []int) { return }
func g() (x []int, y float64) { return }
func main() {
- _ = append(f()) // ERROR "cannot use \[\]int value as type int in append"
- _ = append(g()) // ERROR "cannot use float64 value as type int in append"
+ _ = append(f()) // ERROR "cannot use \[\]int value as type int in append|incompatible type"
+ _ = append(g()) // ERROR "cannot use float64 value as type int in append|incompatible type"
}
diff --git a/test/fixedbugs/issue9862_run.go b/test/fixedbugs/issue9862_run.go
index 299e809545..c956c7f7bd 100644
--- a/test/fixedbugs/issue9862_run.go
+++ b/test/fixedbugs/issue9862_run.go
@@ -1,4 +1,4 @@
-// +build !nacl,!js
+// +build !nacl,!js,gc
// run
// Copyright 2015 The Go Authors. All rights reserved.
diff --git a/test/linkobj.go b/test/linkobj.go
index 2902d23f4b..4c9bd24568 100644
--- a/test/linkobj.go
+++ b/test/linkobj.go
@@ -1,4 +1,4 @@
-// +build !nacl,!js
+// +build !nacl,!js,gc
// run
// Copyright 2016 The Go Authors. All rights reserved.
diff --git a/test/linkx_run.go b/test/linkx_run.go
index f25053bf28..ccfc3a93df 100644
--- a/test/linkx_run.go
+++ b/test/linkx_run.go
@@ -1,4 +1,4 @@
-// +build !nacl,!js
+// +build !nacl,!js,gc
// run
// Copyright 2014 The Go Authors. All rights reserved.
diff --git a/test/nosplit.go b/test/nosplit.go
index a3f2a9fb7e..faa7b8c2d8 100644
--- a/test/nosplit.go
+++ b/test/nosplit.go
@@ -1,4 +1,4 @@
-// +build !nacl,!js,!aix,!gcflags_noopt
+// +build !nacl,!js,!aix,!gcflags_noopt,gc
// run
// Copyright 2014 The Go Authors. All rights reserved.
diff --git a/test/run.go b/test/run.go
index 4abf32d25c..db3e9f6c2f 100644
--- a/test/run.go
+++ b/test/run.go
@@ -438,7 +438,7 @@ func (ctxt *context) match(name string) bool {
}
}
- if name == ctxt.GOOS || name == ctxt.GOARCH {
+ if name == ctxt.GOOS || name == ctxt.GOARCH || name == "gc" {
return true
}
diff --git a/test/sinit_run.go b/test/sinit_run.go
index c37fc9b88c..dcaf338331 100644
--- a/test/sinit_run.go
+++ b/test/sinit_run.go
@@ -1,4 +1,4 @@
-// +build !nacl,!js
+// +build !nacl,!js,gc
// run
// Copyright 2014 The Go Authors. All rights reserved.