From 9c81fd53b3ae52e286d3020ee8b381328b6b9bd2 Mon Sep 17 00:00:00 2001
From: 180909 <734461790@qq.com>
Date: Sun, 25 Jul 2021 11:21:14 +0000
Subject: [PATCH 01/29] cmd/vet: add missing copyright header
Change-Id: I78942dde77547f91daebe763328f52b4c476ddaf
GitHub-Last-Rev: 423f1683fc7db8c1764383cf0a61c54ee21c06f2
GitHub-Pull-Request: golang/go#47334
Reviewed-on: https://go-review.googlesource.com/c/go/+/336434
Reviewed-by: Ian Lance Taylor
Trust: Than McIntosh
---
src/cmd/vet/main.go | 4 ++++
src/cmd/vet/testdata/copylock/copylock.go | 4 ++++
src/cmd/vet/testdata/httpresponse/httpresponse.go | 4 ++++
src/cmd/vet/testdata/testingpkg/tests.go | 4 ++++
src/cmd/vet/testdata/testingpkg/tests_test.go | 4 ++++
5 files changed, 20 insertions(+)
diff --git a/src/cmd/vet/main.go b/src/cmd/vet/main.go
index a33bba2466..7da8606ece 100644
--- a/src/cmd/vet/main.go
+++ b/src/cmd/vet/main.go
@@ -1,3 +1,7 @@
+// 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.
+
package main
import (
diff --git a/src/cmd/vet/testdata/copylock/copylock.go b/src/cmd/vet/testdata/copylock/copylock.go
index 8079cf3248..7cfafe6408 100644
--- a/src/cmd/vet/testdata/copylock/copylock.go
+++ b/src/cmd/vet/testdata/copylock/copylock.go
@@ -1,3 +1,7 @@
+// Copyright 2018 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 copylock
import "sync"
diff --git a/src/cmd/vet/testdata/httpresponse/httpresponse.go b/src/cmd/vet/testdata/httpresponse/httpresponse.go
index 6141f6e06d..98e394a271 100644
--- a/src/cmd/vet/testdata/httpresponse/httpresponse.go
+++ b/src/cmd/vet/testdata/httpresponse/httpresponse.go
@@ -1,3 +1,7 @@
+// Copyright 2018 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 httpresponse
import (
diff --git a/src/cmd/vet/testdata/testingpkg/tests.go b/src/cmd/vet/testdata/testingpkg/tests.go
index 69d29d3c6c..8f4674d33c 100644
--- a/src/cmd/vet/testdata/testingpkg/tests.go
+++ b/src/cmd/vet/testdata/testingpkg/tests.go
@@ -1 +1,5 @@
+// Copyright 2018 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 testdata
diff --git a/src/cmd/vet/testdata/testingpkg/tests_test.go b/src/cmd/vet/testdata/testingpkg/tests_test.go
index 09bb98d980..815dcc8a95 100644
--- a/src/cmd/vet/testdata/testingpkg/tests_test.go
+++ b/src/cmd/vet/testdata/testingpkg/tests_test.go
@@ -1,3 +1,7 @@
+// Copyright 2018 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 testdata
func Example_BadSuffix() {} // ERROR "Example_BadSuffix has malformed example suffix: BadSuffix"
From bfbb288574841f2db2499a580d7bf985a5df4556 Mon Sep 17 00:00:00 2001
From: Ian Lance Taylor
Date: Sun, 25 Jul 2021 16:26:13 -0700
Subject: [PATCH 02/29] runtime: remove adjustTimers counter
In CL 336432 we changed adjusttimers so that it no longer cleared
timerModifiedEarliest if there were no timersModifiedEarlier timers.
This caused some Google internal tests to time out, presumably due
to the increased contention on timersLock. We can avoid that by
simply not skipping the loop in adjusttimers, which lets us safely
clear timerModifiedEarliest. And if we don't skip the loop, then there
isn't much reason to keep the count of timerModifiedEarlier timers at all.
So remove it.
The effect will be that for programs that create some timerModifiedEarlier
timers and then remove them all, the program will do an occasional
additional loop over all the timers. And, programs that have some
timerModifiedEarlier timers will always loop over all the timers,
without the quicker exit when they have all been seen. But the loops
should not occur all that often, due to timerModifiedEarliest.
For #47329
Change-Id: I7b244c1244d97b169a3c7fbc8f8a8b115731ddee
Reviewed-on: https://go-review.googlesource.com/c/go/+/337309
Trust: Ian Lance Taylor
Run-TryBot: Ian Lance Taylor
TryBot-Result: Go Bot
Reviewed-by: Michael Pratt
---
src/runtime/proc.go | 1 -
src/runtime/runtime2.go | 6 -----
src/runtime/time.go | 55 +++++++----------------------------------
3 files changed, 9 insertions(+), 53 deletions(-)
diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index 4c92588a66..7bc2a92590 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -4919,7 +4919,6 @@ func (pp *p) destroy() {
moveTimers(plocal, pp.timers)
pp.timers = nil
pp.numTimers = 0
- pp.adjustTimers = 0
pp.deletedTimers = 0
atomic.Store64(&pp.timer0When, 0)
unlock(&pp.timersLock)
diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go
index 8a15787382..5051ec4d3e 100644
--- a/src/runtime/runtime2.go
+++ b/src/runtime/runtime2.go
@@ -727,12 +727,6 @@ type p struct {
// Modified using atomic instructions.
numTimers uint32
- // Number of timerModifiedEarlier timers on P's heap.
- // This should only be modified while holding timersLock,
- // or while the timer status is in a transient state
- // such as timerModifying.
- adjustTimers uint32
-
// Number of timerDeleted timers in P's heap.
// Modified using atomic instructions.
deletedTimers uint32
diff --git a/src/runtime/time.go b/src/runtime/time.go
index 7b84d2af57..666b242316 100644
--- a/src/runtime/time.go
+++ b/src/runtime/time.go
@@ -333,7 +333,6 @@ func deltimer(t *timer) bool {
// Must fetch t.pp before setting status
// to timerDeleted.
tpp := t.pp.ptr()
- atomic.Xadd(&tpp.adjustTimers, -1)
if !atomic.Cas(&t.status, timerModifying, timerDeleted) {
badTimer()
}
@@ -510,20 +509,9 @@ loop:
tpp := t.pp.ptr()
- // Update the adjustTimers field. Subtract one if we
- // are removing a timerModifiedEarlier, add one if we
- // are adding a timerModifiedEarlier.
- adjust := int32(0)
- if status == timerModifiedEarlier {
- adjust--
- }
if newStatus == timerModifiedEarlier {
- adjust++
updateTimerModifiedEarliest(tpp, when)
}
- if adjust != 0 {
- atomic.Xadd(&tpp.adjustTimers, adjust)
- }
// Set the new status of the timer.
if !atomic.Cas(&t.status, timerModifying, newStatus) {
@@ -591,9 +579,6 @@ func cleantimers(pp *p) {
// Move t to the right position.
dodeltimer0(pp)
doaddtimer(pp, t)
- if s == timerModifiedEarlier {
- atomic.Xadd(&pp.adjustTimers, -1)
- }
if !atomic.Cas(&t.status, timerMoving, timerWaiting) {
badTimer()
}
@@ -664,32 +649,23 @@ func moveTimers(pp *p, timers []*timer) {
// it also moves timers that have been modified to run later,
// and removes deleted timers. The caller must have locked the timers for pp.
func adjusttimers(pp *p, now int64) {
- if atomic.Load(&pp.adjustTimers) == 0 {
+ // If we haven't yet reached the time of the first timerModifiedEarlier
+ // timer, don't do anything. This speeds up programs that adjust
+ // a lot of timers back and forth if the timers rarely expire.
+ // We'll postpone looking through all the adjusted timers until
+ // one would actually expire.
+ first := atomic.Load64(&pp.timerModifiedEarliest)
+ if first == 0 || int64(first) > now {
if verifyTimers {
verifyTimerHeap(pp)
}
return
}
- // If we haven't yet reached the time of the first timerModifiedEarlier
- // timer, don't do anything. This speeds up programs that adjust
- // a lot of timers back and forth if the timers rarely expire.
- // We'll postpone looking through all the adjusted timers until
- // one would actually expire.
- if first := atomic.Load64(&pp.timerModifiedEarliest); first != 0 {
- if int64(first) > now {
- if verifyTimers {
- verifyTimerHeap(pp)
- }
- return
- }
-
- // We are going to clear all timerModifiedEarlier timers.
- atomic.Store64(&pp.timerModifiedEarliest, 0)
- }
+ // We are going to clear all timerModifiedEarlier timers.
+ atomic.Store64(&pp.timerModifiedEarliest, 0)
var moved []*timer
-loop:
for i := 0; i < len(pp.timers); i++ {
t := pp.timers[i]
if t.pp.ptr() != pp {
@@ -716,11 +692,6 @@ loop:
// loop to skip some other timer.
dodeltimer(pp, i)
moved = append(moved, t)
- if s == timerModifiedEarlier {
- if n := atomic.Xadd(&pp.adjustTimers, -1); int32(n) <= 0 {
- break loop
- }
- }
// Look at this heap position again.
i--
}
@@ -819,9 +790,6 @@ func runtimer(pp *p, now int64) int64 {
t.when = t.nextwhen
dodeltimer0(pp)
doaddtimer(pp, t)
- if s == timerModifiedEarlier {
- atomic.Xadd(&pp.adjustTimers, -1)
- }
if !atomic.Cas(&t.status, timerMoving, timerWaiting) {
badTimer()
}
@@ -916,7 +884,6 @@ func clearDeletedTimers(pp *p) {
atomic.Store64(&pp.timerModifiedEarliest, 0)
cdel := int32(0)
- cearlier := int32(0)
to := 0
changedHeap := false
timers := pp.timers
@@ -941,9 +908,6 @@ nextTimer:
if !atomic.Cas(&t.status, timerMoving, timerWaiting) {
badTimer()
}
- if s == timerModifiedEarlier {
- cearlier++
- }
continue nextTimer
}
case timerDeleted:
@@ -980,7 +944,6 @@ nextTimer:
atomic.Xadd(&pp.deletedTimers, -cdel)
atomic.Xadd(&pp.numTimers, -cdel)
- atomic.Xadd(&pp.adjustTimers, -cearlier)
timers = timers[:to]
pp.timers = timers
From 840e583ff340d22a6263a348922283e6d5cd2e31 Mon Sep 17 00:00:00 2001
From: Koichi Shiraishi
Date: Sun, 25 Jul 2021 03:00:04 +0900
Subject: [PATCH 03/29] runtime: correct variable name in comment
Change-Id: Ic35ec2ed320c3c266afbeec8bdea1dedac4725e4
Reviewed-on: https://go-review.googlesource.com/c/go/+/336892
Reviewed-by: Ian Lance Taylor
Trust: Austin Clements
---
src/runtime/race.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/runtime/race.go b/src/runtime/race.go
index cc8c5db1bd..ce6b5b5468 100644
--- a/src/runtime/race.go
+++ b/src/runtime/race.go
@@ -343,7 +343,7 @@ func racereadrangepc1(addr, size, pc uintptr)
func racewriterangepc1(addr, size, pc uintptr)
func racecallbackthunk(uintptr)
-// racecall allows calling an arbitrary function f from C race runtime
+// racecall allows calling an arbitrary function fn from C race runtime
// with up to 4 uintptr arguments.
func racecall(fn *byte, arg0, arg1, arg2, arg3 uintptr)
From 33ff1559702388c57c45f9e6cd032f06e8c3c163 Mon Sep 17 00:00:00 2001
From: Rob Findley
Date: Mon, 26 Jul 2021 16:33:44 -0400
Subject: [PATCH 04/29] go/types: preserve untyped constants on the RHS of a
shift expression
CL 291316 fixed go/types to verify that untyped shift counts are
representable by uint, but as a side effect also converted their types
to uint.
Rearrange the logic to keep the check for representability, but not
actually convert untyped integer constants. Untyped non-integer
constants are still converted, to preserve the behavior of 1.16. This
behavior for non-integer types is a bug, filed as #47410.
Updates #47410
Fixes #47243
Change-Id: I5eab4aab35b97f932fccdee2d4a18623ee2ccad5
Reviewed-on: https://go-review.googlesource.com/c/go/+/337529
Trust: Robert Findley
Trust: Robert Griesemer
Run-TryBot: Robert Findley
TryBot-Result: Go Bot
Reviewed-by: Robert Griesemer
---
src/go/types/api_test.go | 12 ++++++++++++
src/go/types/check_test.go | 7 +++++++
src/go/types/expr.go | 34 +++++++++++++++++++++++++---------
3 files changed, 44 insertions(+), 9 deletions(-)
diff --git a/src/go/types/api_test.go b/src/go/types/api_test.go
index f37b91d5a4..f964c656f9 100644
--- a/src/go/types/api_test.go
+++ b/src/go/types/api_test.go
@@ -322,6 +322,18 @@ func TestTypesInfo(t *testing.T) {
`[][]struct{}`,
},
+ // issue 47243
+ {`package issue47243_a; var x int32; var _ = x << 3`, `3`, `untyped int`},
+ {`package issue47243_b; var x int32; var _ = x << 3.`, `3.`, `uint`}, // issue 47410: should be untyped float
+ {`package issue47243_c; var x int32; var _ = 1 << x`, `1 << x`, `int`},
+ {`package issue47243_d; var x int32; var _ = 1 << x`, `1`, `int`},
+ {`package issue47243_e; var x int32; var _ = 1 << 2`, `1`, `untyped int`},
+ {`package issue47243_f; var x int32; var _ = 1 << 2`, `2`, `untyped int`},
+ {`package issue47243_g; var x int32; var _ = int(1) << 2`, `2`, `untyped int`},
+ {`package issue47243_h; var x int32; var _ = 1 << (2 << x)`, `1`, `int`},
+ {`package issue47243_i; var x int32; var _ = 1 << (2 << x)`, `(2 << x)`, `untyped int`},
+ {`package issue47243_j; var x int32; var _ = 1 << (2 << x)`, `2`, `untyped int`},
+
// tests for broken code that doesn't parse or type-check
{broken + `x0; func _() { var x struct {f string}; x.f := 0 }`, `x.f`, `string`},
{broken + `x1; func _() { var z string; type x struct {f string}; y := &x{q: z}}`, `z`, `string`},
diff --git a/src/go/types/check_test.go b/src/go/types/check_test.go
index c85a8e46fb..f83abf11ce 100644
--- a/src/go/types/check_test.go
+++ b/src/go/types/check_test.go
@@ -344,6 +344,13 @@ func TestIssue46453(t *testing.T) {
checkFiles(t, nil, "", []string{"issue46453.go"}, [][]byte{[]byte(src)}, false, nil)
}
+func TestIssue47243_TypedRHS(t *testing.T) {
+ // The RHS of the shift expression below overflows uint on 32bit platforms,
+ // but this is OK as it is explicitly typed.
+ const src = "package issue47243\n\nvar a uint64; var _ = a << uint64(4294967296)" // uint64(1<<32)
+ checkFiles(t, &StdSizes{4, 4}, "", []string{"p.go"}, [][]byte{[]byte(src)}, false, nil)
+}
+
func TestCheck(t *testing.T) { DefPredeclaredTestFuncs(); testDir(t, "check") }
func TestExamples(t *testing.T) { testDir(t, "examples") }
func TestFixedbugs(t *testing.T) { testDir(t, "fixedbugs") }
diff --git a/src/go/types/expr.go b/src/go/types/expr.go
index 5c65fad447..58962e777b 100644
--- a/src/go/types/expr.go
+++ b/src/go/types/expr.go
@@ -778,32 +778,48 @@ func (check *Checker) shift(x, y *operand, e ast.Expr, op token.Token) {
// spec: "The right operand in a shift expression must have integer type
// or be an untyped constant representable by a value of type uint."
- // Provide a good error message for negative shift counts.
+ // Check that constants are representable by uint, but do not convert them
+ // (see also issue #47243).
if y.mode == constant_ {
+ // Provide a good error message for negative shift counts.
yval := constant.ToInt(y.val) // consider -1, 1.0, but not -1.1
if yval.Kind() == constant.Int && constant.Sign(yval) < 0 {
check.invalidOp(y, _InvalidShiftCount, "negative shift count %s", y)
x.mode = invalid
return
}
+
+ if isUntyped(y.typ) {
+ // Caution: Check for representability here, rather than in the switch
+ // below, because isInteger includes untyped integers (was bug #43697).
+ check.representable(y, Typ[Uint])
+ if y.mode == invalid {
+ x.mode = invalid
+ return
+ }
+ }
}
- // Caution: Check for isUntyped first because isInteger includes untyped
- // integers (was bug #43697).
- if isUntyped(y.typ) {
+ // Check that RHS is otherwise at least of integer type.
+ switch {
+ case isInteger(y.typ):
+ if !isUnsigned(y.typ) && !check.allowVersion(check.pkg, 1, 13) {
+ check.invalidOp(y, _InvalidShiftCount, "signed shift count %s requires go1.13 or later", y)
+ x.mode = invalid
+ return
+ }
+ case isUntyped(y.typ):
+ // This is incorrect, but preserves pre-existing behavior.
+ // See also bug #47410.
check.convertUntyped(y, Typ[Uint])
if y.mode == invalid {
x.mode = invalid
return
}
- } else if !isInteger(y.typ) {
+ default:
check.invalidOp(y, _InvalidShiftCount, "shift count %s must be integer", y)
x.mode = invalid
return
- } else if !isUnsigned(y.typ) && !check.allowVersion(check.pkg, 1, 13) {
- check.invalidOp(y, _InvalidShiftCount, "signed shift count %s requires go1.13 or later", y)
- x.mode = invalid
- return
}
if x.mode == constant_ {
From 7ba8e796c91eaf4befcacc4d24127ae54475d6a5 Mon Sep 17 00:00:00 2001
From: Changkun Ou
Date: Mon, 26 Jul 2021 15:04:48 +0200
Subject: [PATCH 05/29] testing: clarify T.Name returns a distinct name of the
running test
According to the discussion, it is clear that T.Name returns a
distinct name among all tests. However, there is no specification
of how sub-tests with the same specified test name are constructed.
This change only clarifies the uniqueness and the components of the
name without suggesting any explicit format of the returned name.
Fixes #46488
Change-Id: I6cebd419b69fb08d8646cb744a129548452042ef
Reviewed-on: https://go-review.googlesource.com/c/go/+/337392
Reviewed-by: Ian Lance Taylor
Reviewed-by: Emmanuel Odeke
Run-TryBot: Ian Lance Taylor
TryBot-Result: Go Bot
---
src/testing/testing.go | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/testing/testing.go b/src/testing/testing.go
index 681f99ef93..a19238d31e 100644
--- a/src/testing/testing.go
+++ b/src/testing/testing.go
@@ -680,7 +680,11 @@ type T struct {
func (c *common) private() {}
-// Name returns the name of the running test or benchmark.
+// Name returns the name of the running (sub-) test or benchmark.
+//
+// The name will include the name of the test along with the names of
+// any nested sub-tests. If two sibling sub-tests have the same name,
+// Name will append a suffix to guarantee the returned name is unique.
func (c *common) Name() string {
return c.name
}
From c8cf0f74e4a8f078ab5570e76c37621a0daf0309 Mon Sep 17 00:00:00 2001
From: 180909 <734461790@qq.com>
Date: Tue, 27 Jul 2021 09:49:55 +0000
Subject: [PATCH 06/29] cmd/go: add missing flag in UsageLine
Change-Id: I31689dc8de1f6b95bb35578b20533c63903f7258
GitHub-Last-Rev: 5bfee0535ded703f84d45390d5a87295b6e5fe5a
GitHub-Pull-Request: golang/go#47418
Reviewed-on: https://go-review.googlesource.com/c/go/+/337691
Run-TryBot: Jay Conrod
TryBot-Result: Go Bot
Reviewed-by: Jay Conrod
Trust: Jay Conrod
Trust: Russ Cox
---
src/cmd/go/alldocs.go | 4 ++--
src/cmd/go/internal/modcmd/edit.go | 2 +-
src/cmd/go/internal/modcmd/init.go | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go
index 954caae9fb..7f88d3216c 100644
--- a/src/cmd/go/alldocs.go
+++ b/src/cmd/go/alldocs.go
@@ -1078,7 +1078,7 @@
//
// Usage:
//
-// go mod edit [editing flags] [go.mod]
+// go mod edit [editing flags] [-fmt|-print|-json] [go.mod]
//
// Edit provides a command-line interface for editing go.mod,
// for use primarily by tools or scripts. It reads only go.mod;
@@ -1204,7 +1204,7 @@
//
// Usage:
//
-// go mod init [module]
+// go mod init [module-path]
//
// Init initializes and writes a new go.mod file in the current directory, in
// effect creating a new module rooted at the current directory. The go.mod file
diff --git a/src/cmd/go/internal/modcmd/edit.go b/src/cmd/go/internal/modcmd/edit.go
index e856e7c630..bb3d521092 100644
--- a/src/cmd/go/internal/modcmd/edit.go
+++ b/src/cmd/go/internal/modcmd/edit.go
@@ -25,7 +25,7 @@ import (
)
var cmdEdit = &base.Command{
- UsageLine: "go mod edit [editing flags] [go.mod]",
+ UsageLine: "go mod edit [editing flags] [-fmt|-print|-json] [go.mod]",
Short: "edit go.mod from tools or scripts",
Long: `
Edit provides a command-line interface for editing go.mod,
diff --git a/src/cmd/go/internal/modcmd/init.go b/src/cmd/go/internal/modcmd/init.go
index 73cc282d81..958c3066ac 100644
--- a/src/cmd/go/internal/modcmd/init.go
+++ b/src/cmd/go/internal/modcmd/init.go
@@ -13,7 +13,7 @@ import (
)
var cmdInit = &base.Command{
- UsageLine: "go mod init [module]",
+ UsageLine: "go mod init [module-path]",
Short: "initialize new module in current directory",
Long: `
Init initializes and writes a new go.mod file in the current directory, in
From 7cd10c1149e51a9d2f0868babaf66b8091b9c0b9 Mon Sep 17 00:00:00 2001
From: Jay Conrod
Date: Tue, 27 Jul 2021 10:22:35 -0700
Subject: [PATCH 07/29] cmd/go: use .mod instead of .zip to determine if
version has go.mod file
When checking for updates, the go command checks whether the highest
compatible version has a go.mod file in order to determine whether
+incompatible versions may be considered "latest". Previously, to
perform this check, the go command would download the content of the
module (the .zip file) to see whether a go.mod file was present at the
root. This is slower than necessary, and it caused 'go list -m -u' to
try to save the sum for the .zip file in go.sum in some cases.
With this change, the go command only downloads the .mod file and
checks whether it appears to be a fake file generated for a version
that didn't have a go.mod file. This is faster and requires less
verification. Fake files only have a "module" directive. It's possible
to commit a file that passes this test, but it would be difficult to
do accidentally: Go 1.12 and later at least add a "go" directive. A
false positive here would cause version queries to have slightly
different results but would not affect builds.
Fixes #47377
Change-Id: Ie5ffd0b45e39bd0921328a60af99a9f6e5ab6346
Reviewed-on: https://go-review.googlesource.com/c/go/+/337850
Trust: Jay Conrod
Run-TryBot: Jay Conrod
TryBot-Result: Go Bot
Reviewed-by: Michael Matloob
---
src/cmd/go/internal/modfetch/coderepo.go | 23 ++---
src/cmd/go/internal/modload/modfile.go | 83 ++++++++++---------
src/cmd/go/internal/modload/query.go | 30 +++++--
.../script/mod_update_sum_readonly.txt | 34 ++++++++
4 files changed, 114 insertions(+), 56 deletions(-)
create mode 100644 src/cmd/go/testdata/script/mod_update_sum_readonly.txt
diff --git a/src/cmd/go/internal/modfetch/coderepo.go b/src/cmd/go/internal/modfetch/coderepo.go
index f817a04583..dfef9f73c2 100644
--- a/src/cmd/go/internal/modfetch/coderepo.go
+++ b/src/cmd/go/internal/modfetch/coderepo.go
@@ -864,22 +864,25 @@ func (r *codeRepo) GoMod(version string) (data []byte, err error) {
data, err = r.code.ReadFile(rev, path.Join(dir, "go.mod"), codehost.MaxGoMod)
if err != nil {
if os.IsNotExist(err) {
- return r.legacyGoMod(rev, dir), nil
+ return LegacyGoMod(r.modPath), nil
}
return nil, err
}
return data, nil
}
-func (r *codeRepo) legacyGoMod(rev, dir string) []byte {
- // We used to try to build a go.mod reflecting pre-existing
- // package management metadata files, but the conversion
- // was inherently imperfect (because those files don't have
- // exactly the same semantics as go.mod) and, when done
- // for dependencies in the middle of a build, impossible to
- // correct. So we stopped.
- // Return a fake go.mod that simply declares the module path.
- return []byte(fmt.Sprintf("module %s\n", modfile.AutoQuote(r.modPath)))
+// LegacyGoMod generates a fake go.mod file for a module that doesn't have one.
+// The go.mod file contains a module directive and nothing else: no go version,
+// no requirements.
+//
+// We used to try to build a go.mod reflecting pre-existing
+// package management metadata files, but the conversion
+// was inherently imperfect (because those files don't have
+// exactly the same semantics as go.mod) and, when done
+// for dependencies in the middle of a build, impossible to
+// correct. So we stopped.
+func LegacyGoMod(modPath string) []byte {
+ return []byte(fmt.Sprintf("module %s\n", modfile.AutoQuote(modPath)))
}
func (r *codeRepo) modPrefix(rev string) string {
diff --git a/src/cmd/go/internal/modload/modfile.go b/src/cmd/go/internal/modload/modfile.go
index d280945ea6..6145e8b2f0 100644
--- a/src/cmd/go/internal/modload/modfile.go
+++ b/src/cmd/go/internal/modload/modfile.go
@@ -595,47 +595,14 @@ func rawGoModSummary(m module.Version) (*modFileSummary, error) {
}
c := rawGoModSummaryCache.Do(m, func() interface{} {
summary := new(modFileSummary)
- var f *modfile.File
- if m.Version == "" {
- // m is a replacement module with only a file path.
- dir := m.Path
- if !filepath.IsAbs(dir) {
- dir = filepath.Join(ModRoot(), dir)
- }
- gomod := filepath.Join(dir, "go.mod")
- var data []byte
- var err error
- if gomodActual, ok := fsys.OverlayPath(gomod); ok {
- // Don't lock go.mod if it's part of the overlay.
- // On Plan 9, locking requires chmod, and we don't want to modify any file
- // in the overlay. See #44700.
- data, err = os.ReadFile(gomodActual)
- } else {
- data, err = lockedfile.Read(gomodActual)
- }
- if err != nil {
- return cached{nil, module.VersionError(m, fmt.Errorf("reading %s: %v", base.ShortPath(gomod), err))}
- }
- f, err = modfile.ParseLax(gomod, data, nil)
- if err != nil {
- return cached{nil, module.VersionError(m, fmt.Errorf("parsing %s: %v", base.ShortPath(gomod), err))}
- }
- } else {
- if !semver.IsValid(m.Version) {
- // Disallow the broader queries supported by fetch.Lookup.
- base.Fatalf("go: internal error: %s@%s: unexpected invalid semantic version", m.Path, m.Version)
- }
-
- data, err := modfetch.GoMod(m.Path, m.Version)
- if err != nil {
- return cached{nil, err}
- }
- f, err = modfile.ParseLax("go.mod", data, nil)
- if err != nil {
- return cached{nil, module.VersionError(m, fmt.Errorf("parsing go.mod: %v", err))}
- }
+ name, data, err := rawGoModData(m)
+ if err != nil {
+ return cached{nil, err}
+ }
+ f, err := modfile.ParseLax(name, data, nil)
+ if err != nil {
+ return cached{nil, module.VersionError(m, fmt.Errorf("parsing %s: %v", base.ShortPath(name), err))}
}
-
if f.Module != nil {
summary.module = f.Module.Mod
summary.deprecated = f.Module.Deprecated
@@ -671,6 +638,42 @@ func rawGoModSummary(m module.Version) (*modFileSummary, error) {
var rawGoModSummaryCache par.Cache // module.Version → rawGoModSummary result
+// rawGoModData returns the content of the go.mod file for module m, ignoring
+// all replacements that may apply to m.
+//
+// rawGoModData cannot be used on the Target module.
+//
+// Unlike rawGoModSummary, rawGoModData does not cache its results in memory.
+// Use rawGoModSummary instead unless you specifically need these bytes.
+func rawGoModData(m module.Version) (name string, data []byte, err error) {
+ if m.Version == "" {
+ // m is a replacement module with only a file path.
+ dir := m.Path
+ if !filepath.IsAbs(dir) {
+ dir = filepath.Join(ModRoot(), dir)
+ }
+ gomod := filepath.Join(dir, "go.mod")
+ if gomodActual, ok := fsys.OverlayPath(gomod); ok {
+ // Don't lock go.mod if it's part of the overlay.
+ // On Plan 9, locking requires chmod, and we don't want to modify any file
+ // in the overlay. See #44700.
+ data, err = os.ReadFile(gomodActual)
+ } else {
+ data, err = lockedfile.Read(gomodActual)
+ }
+ if err != nil {
+ return gomod, nil, module.VersionError(m, fmt.Errorf("reading %s: %v", base.ShortPath(gomod), err))
+ }
+ } else {
+ if !semver.IsValid(m.Version) {
+ // Disallow the broader queries supported by fetch.Lookup.
+ base.Fatalf("go: internal error: %s@%s: unexpected invalid semantic version", m.Path, m.Version)
+ }
+ data, err = modfetch.GoMod(m.Path, m.Version)
+ }
+ return "go.mod", data, err
+}
+
// queryLatestVersionIgnoringRetractions looks up the latest version of the
// module with the given path without considering retracted or excluded
// versions.
diff --git a/src/cmd/go/internal/modload/query.go b/src/cmd/go/internal/modload/query.go
index dda9004a9f..e737ca90fc 100644
--- a/src/cmd/go/internal/modload/query.go
+++ b/src/cmd/go/internal/modload/query.go
@@ -5,13 +5,13 @@
package modload
import (
+ "bytes"
"context"
"errors"
"fmt"
"io/fs"
"os"
pathpkg "path"
- "path/filepath"
"sort"
"strings"
"sync"
@@ -931,14 +931,32 @@ func moduleHasRootPackage(ctx context.Context, m module.Version) (bool, error) {
return ok, err
}
-func versionHasGoMod(ctx context.Context, m module.Version) (bool, error) {
- needSum := false
- root, _, err := fetch(ctx, m, needSum)
+// versionHasGoMod returns whether a version has a go.mod file.
+//
+// versionHasGoMod fetches the go.mod file (possibly a fake) and true if it
+// contains anything other than a module directive with the same path. When a
+// module does not have a real go.mod file, the go command acts as if it had one
+// that only contained a module directive. Normal go.mod files created after
+// 1.12 at least have a go directive.
+//
+// This function is a heuristic, since it's possible to commit a file that would
+// pass this test. However, we only need a heurstic for determining whether
+// +incompatible versions may be "latest", which is what this function is used
+// for.
+//
+// This heuristic is useful for two reasons: first, when using a proxy,
+// this lets us fetch from the .mod endpoint which is much faster than the .zip
+// endpoint. The .mod file is used anyway, even if the .zip file contains a
+// go.mod with different content. Second, if we don't fetch the .zip, then
+// we don't need to verify it in go.sum. This makes 'go list -m -u' faster
+// and simpler.
+func versionHasGoMod(_ context.Context, m module.Version) (bool, error) {
+ _, data, err := rawGoModData(m)
if err != nil {
return false, err
}
- fi, err := os.Stat(filepath.Join(root, "go.mod"))
- return err == nil && !fi.IsDir(), nil
+ isFake := bytes.Equal(data, modfetch.LegacyGoMod(m.Path))
+ return !isFake, nil
}
// A versionRepo is a subset of modfetch.Repo that can report information about
diff --git a/src/cmd/go/testdata/script/mod_update_sum_readonly.txt b/src/cmd/go/testdata/script/mod_update_sum_readonly.txt
new file mode 100644
index 0000000000..41f12e4084
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_update_sum_readonly.txt
@@ -0,0 +1,34 @@
+# When finding the latest version of a module, we should not download version
+# contents. Previously, we downloaded .zip files to determine whether a real
+# .mod file was present in order to decide whether +incompatible versions
+# could be "latest".
+#
+# Verifies #47377.
+
+# rsc.io/breaker has two versions, neither of which has a .mod file.
+go list -m -versions rsc.io/breaker
+stdout '^rsc.io/breaker v1.0.0 v2.0.0\+incompatible$'
+go mod download rsc.io/breaker@v1.0.0
+! grep '^go' $GOPATH/pkg/mod/cache/download/rsc.io/breaker/@v/v1.0.0.mod
+go mod download rsc.io/breaker@v2.0.0+incompatible
+! grep '^go' $GOPATH/pkg/mod/cache/download/rsc.io/breaker/@v/v2.0.0+incompatible.mod
+
+# Delete downloaded .zip files.
+go clean -modcache
+
+# Check for updates.
+go list -m -u rsc.io/breaker
+stdout '^rsc.io/breaker v1.0.0 \[v2.0.0\+incompatible\]$'
+
+# We should not have downloaded zips.
+! exists $GOPATH/pkg/mod/cache/download/rsc.io/breaker/@v/v1.0.0.zip
+! exists $GOPATH/pkg/mod/cache/download/rsc.io/breaker/@v/v2.0.0+incompatible.zip
+
+-- go.mod --
+module m
+
+go 1.16
+
+require rsc.io/breaker v1.0.0
+-- go.sum --
+rsc.io/breaker v1.0.0/go.mod h1:s5yxDXvD88U1/ESC23I2FK3Lkv4YIKaB1ij/Hbm805g=
From b39e0f461c099abf98f5a8c81d58d32d9a765a03 Mon Sep 17 00:00:00 2001
From: Matthew Dempsky
Date: Tue, 27 Jul 2021 18:30:38 -0700
Subject: [PATCH 08/29] runtime: don't crash on nil pointers in
checkptrAlignment
Ironically, checkptrAlignment had a latent case of bad pointer
arithmetic: if ptr is nil, then `add(ptr, size-1)` might produce an
illegal pointer value.
The fix is to simply check for nil at the top of checkptrAlignment,
and short-circuit if so.
This CL also adds a more explicit bounds check in checkptrStraddles,
rather than relying on `add(ptr, size-1)` to wrap around. I don't
think this is necessary today, but it seems prudent to be careful.
Fixes #47430.
Change-Id: I5c50b2f7f41415dbebbd803e1b8e7766ca95e1fd
Reviewed-on: https://go-review.googlesource.com/c/go/+/338029
Trust: Matthew Dempsky
Run-TryBot: Matthew Dempsky
TryBot-Result: Go Bot
Reviewed-by: Keith Randall
---
src/runtime/checkptr.go | 11 +++++--
src/runtime/checkptr_test.go | 1 +
src/runtime/testdata/testprog/checkptr.go | 36 ++++++++++++++++++++++-
3 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/src/runtime/checkptr.go b/src/runtime/checkptr.go
index d42950844b..2d4afd5cf6 100644
--- a/src/runtime/checkptr.go
+++ b/src/runtime/checkptr.go
@@ -7,6 +7,11 @@ package runtime
import "unsafe"
func checkptrAlignment(p unsafe.Pointer, elem *_type, n uintptr) {
+ // nil pointer is always suitably aligned (#47430).
+ if p == nil {
+ return
+ }
+
// Check that (*[n]elem)(p) is appropriately aligned.
// Note that we allow unaligned pointers if the types they point to contain
// no pointers themselves. See issue 37298.
@@ -29,10 +34,12 @@ func checkptrStraddles(ptr unsafe.Pointer, size uintptr) bool {
return false
}
- end := add(ptr, size-1)
- if uintptr(end) < uintptr(ptr) {
+ // Check that add(ptr, size-1) won't overflow. This avoids the risk
+ // of producing an illegal pointer value (assuming ptr is legal).
+ if uintptr(ptr) >= -(size - 1) {
return true
}
+ end := add(ptr, size-1)
// TODO(mdempsky): Detect when [ptr, end] contains Go allocations,
// but neither ptr nor end point into one themselves.
diff --git a/src/runtime/checkptr_test.go b/src/runtime/checkptr_test.go
index 2a5c364e97..d5dd101adb 100644
--- a/src/runtime/checkptr_test.go
+++ b/src/runtime/checkptr_test.go
@@ -26,6 +26,7 @@ func TestCheckPtr(t *testing.T) {
}{
{"CheckPtrAlignmentPtr", "fatal error: checkptr: misaligned pointer conversion\n"},
{"CheckPtrAlignmentNoPtr", ""},
+ {"CheckPtrAlignmentNilPtr", ""},
{"CheckPtrArithmetic", "fatal error: checkptr: pointer arithmetic result points to invalid allocation\n"},
{"CheckPtrArithmetic2", "fatal error: checkptr: pointer arithmetic result points to invalid allocation\n"},
{"CheckPtrSize", "fatal error: checkptr: converted pointer straddles multiple allocations\n"},
diff --git a/src/runtime/testdata/testprog/checkptr.go b/src/runtime/testdata/testprog/checkptr.go
index f76b64ad96..9c5561396e 100644
--- a/src/runtime/testdata/testprog/checkptr.go
+++ b/src/runtime/testdata/testprog/checkptr.go
@@ -4,11 +4,16 @@
package main
-import "unsafe"
+import (
+ "runtime"
+ "time"
+ "unsafe"
+)
func init() {
register("CheckPtrAlignmentNoPtr", CheckPtrAlignmentNoPtr)
register("CheckPtrAlignmentPtr", CheckPtrAlignmentPtr)
+ register("CheckPtrAlignmentNilPtr", CheckPtrAlignmentNilPtr)
register("CheckPtrArithmetic", CheckPtrArithmetic)
register("CheckPtrArithmetic2", CheckPtrArithmetic2)
register("CheckPtrSize", CheckPtrSize)
@@ -29,6 +34,35 @@ func CheckPtrAlignmentPtr() {
sink2 = (**int64)(unsafe.Pointer(uintptr(p) + 1))
}
+// CheckPtrAlignmentNilPtr tests that checkptrAlignment doesn't crash
+// on nil pointers (#47430).
+func CheckPtrAlignmentNilPtr() {
+ var do func(int)
+ do = func(n int) {
+ // Inflate the stack so runtime.shrinkstack gets called during GC
+ if n > 0 {
+ do(n - 1)
+ }
+
+ var p unsafe.Pointer
+ _ = (*int)(p)
+ }
+
+ go func() {
+ for {
+ runtime.GC()
+ }
+ }()
+
+ go func() {
+ for i := 0; ; i++ {
+ do(i % 1024)
+ }
+ }()
+
+ time.Sleep(time.Second)
+}
+
func CheckPtrArithmetic() {
var x int
i := uintptr(unsafe.Pointer(&x))
From 9eee0ed4391942c73157c868a9ddcfdef48982f9 Mon Sep 17 00:00:00 2001
From: Jay Conrod
Date: Wed, 28 Jul 2021 11:52:14 -0700
Subject: [PATCH 09/29] cmd/go: fix go.mod file name printed in error messages
for replacements
This fixes a logic error introduced in CL 337850.
Fixes #47444
Change-Id: I6a49c8fc71fdde4ecb7f2e3329ad1f2cd286b7eb
Reviewed-on: https://go-review.googlesource.com/c/go/+/338189
Run-TryBot: Jay Conrod
TryBot-Result: Go Bot
Reviewed-by: Michael Matloob
Trust: Jay Conrod
---
src/cmd/go/internal/modload/modfile.go | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/cmd/go/internal/modload/modfile.go b/src/cmd/go/internal/modload/modfile.go
index 6145e8b2f0..03e02e73b6 100644
--- a/src/cmd/go/internal/modload/modfile.go
+++ b/src/cmd/go/internal/modload/modfile.go
@@ -652,8 +652,8 @@ func rawGoModData(m module.Version) (name string, data []byte, err error) {
if !filepath.IsAbs(dir) {
dir = filepath.Join(ModRoot(), dir)
}
- gomod := filepath.Join(dir, "go.mod")
- if gomodActual, ok := fsys.OverlayPath(gomod); ok {
+ name = filepath.Join(dir, "go.mod")
+ if gomodActual, ok := fsys.OverlayPath(name); ok {
// Don't lock go.mod if it's part of the overlay.
// On Plan 9, locking requires chmod, and we don't want to modify any file
// in the overlay. See #44700.
@@ -662,16 +662,17 @@ func rawGoModData(m module.Version) (name string, data []byte, err error) {
data, err = lockedfile.Read(gomodActual)
}
if err != nil {
- return gomod, nil, module.VersionError(m, fmt.Errorf("reading %s: %v", base.ShortPath(gomod), err))
+ return "", nil, module.VersionError(m, fmt.Errorf("reading %s: %v", base.ShortPath(name), err))
}
} else {
if !semver.IsValid(m.Version) {
// Disallow the broader queries supported by fetch.Lookup.
base.Fatalf("go: internal error: %s@%s: unexpected invalid semantic version", m.Path, m.Version)
}
+ name = "go.mod"
data, err = modfetch.GoMod(m.Path, m.Version)
}
- return "go.mod", data, err
+ return name, data, err
}
// queryLatestVersionIgnoringRetractions looks up the latest version of the
From 70fd4e47d73b92fe90e44ac785e2f98f9df0ab67 Mon Sep 17 00:00:00 2001
From: Ian Lance Taylor
Date: Wed, 28 Jul 2021 21:09:31 -0700
Subject: [PATCH 10/29] runtime: avoid possible preemption when returning from
Go to C
When returning from Go to C, it was possible for the goroutine to be
preempted after calling unlockOSThread. This could happen when there
a context function installed by SetCgoTraceback set a non-zero context,
leading to a defer call in cgocallbackg1. The defer function wrapper,
introduced in 1.17 as part of the regabi support, was not nosplit,
and hence was a potential preemption point. If it did get preempted,
the G would move to a new M. It would then attempt to return to C
code on a different stack, typically leading to a SIGSEGV.
Fix this in a simple way by postponing the unlockOSThread until after
the other defer. Also check for the failure condition and fail early,
rather than waiting for a SIGSEGV.
Without the fix to cgocall.go, the test case fails about 50% of the
time on my laptop.
Fixes #47441
Change-Id: Ib8ca13215bd36cddc2a49e86698824a29c6a68ba
Reviewed-on: https://go-review.googlesource.com/c/go/+/338197
Trust: Ian Lance Taylor
Reviewed-by: Keith Randall
Reviewed-by: Cherry Mui
---
src/runtime/cgocall.go | 20 +++++++----
src/runtime/crash_cgo_test.go | 9 +++++
.../testdata/testprogcgo/tracebackctxt.go | 33 +++++++++++++++++--
.../testdata/testprogcgo/tracebackctxt_c.c | 14 +++++++-
4 files changed, 67 insertions(+), 9 deletions(-)
diff --git a/src/runtime/cgocall.go b/src/runtime/cgocall.go
index 8ffb48a888..2626216f95 100644
--- a/src/runtime/cgocall.go
+++ b/src/runtime/cgocall.go
@@ -212,6 +212,8 @@ func cgocallbackg(fn, frame unsafe.Pointer, ctxt uintptr) {
// a different M. The call to unlockOSThread is in unwindm.
lockOSThread()
+ checkm := gp.m
+
// Save current syscall parameters, so m.syscall can be
// used again if callback decide to make syscall.
syscall := gp.m.syscall
@@ -227,15 +229,20 @@ func cgocallbackg(fn, frame unsafe.Pointer, ctxt uintptr) {
osPreemptExtExit(gp.m)
- cgocallbackg1(fn, frame, ctxt)
+ cgocallbackg1(fn, frame, ctxt) // will call unlockOSThread
// At this point unlockOSThread has been called.
// The following code must not change to a different m.
// This is enforced by checking incgo in the schedule function.
+ gp.m.incgo = true
+
+ if gp.m != checkm {
+ throw("m changed unexpectedly in cgocallbackg")
+ }
+
osPreemptExtEnter(gp.m)
- gp.m.incgo = true
// going back to cgo call
reentersyscall(savedpc, uintptr(savedsp))
@@ -244,6 +251,11 @@ func cgocallbackg(fn, frame unsafe.Pointer, ctxt uintptr) {
func cgocallbackg1(fn, frame unsafe.Pointer, ctxt uintptr) {
gp := getg()
+
+ // When we return, undo the call to lockOSThread in cgocallbackg.
+ // We must still stay on the same m.
+ defer unlockOSThread()
+
if gp.m.needextram || atomic.Load(&extraMWaiters) > 0 {
gp.m.needextram = false
systemstack(newextram)
@@ -323,10 +335,6 @@ func unwindm(restore *bool) {
releasem(mp)
}
-
- // Undo the call to lockOSThread in cgocallbackg.
- // We must still stay on the same m.
- unlockOSThread()
}
// called from assembly
diff --git a/src/runtime/crash_cgo_test.go b/src/runtime/crash_cgo_test.go
index 7d25c51aa2..5729942cee 100644
--- a/src/runtime/crash_cgo_test.go
+++ b/src/runtime/crash_cgo_test.go
@@ -282,6 +282,15 @@ func TestCgoTracebackContext(t *testing.T) {
}
}
+func TestCgoTracebackContextPreemption(t *testing.T) {
+ t.Parallel()
+ got := runTestProg(t, "testprogcgo", "TracebackContextPreemption")
+ want := "OK\n"
+ if got != want {
+ t.Errorf("expected %q got %v", want, got)
+ }
+}
+
func testCgoPprof(t *testing.T, buildArg, runArg, top, bottom string) {
t.Parallel()
if runtime.GOOS != "linux" || (runtime.GOARCH != "amd64" && runtime.GOARCH != "ppc64le") {
diff --git a/src/runtime/testdata/testprogcgo/tracebackctxt.go b/src/runtime/testdata/testprogcgo/tracebackctxt.go
index 51fa4ad25c..62ff8eccd6 100644
--- a/src/runtime/testdata/testprogcgo/tracebackctxt.go
+++ b/src/runtime/testdata/testprogcgo/tracebackctxt.go
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// The __attribute__((weak)) used below doesn't seem to work on Windows.
-
package main
// Test the context argument to SetCgoTraceback.
@@ -14,20 +12,24 @@ package main
extern void C1(void);
extern void C2(void);
extern void tcContext(void*);
+extern void tcContextSimple(void*);
extern void tcTraceback(void*);
extern void tcSymbolizer(void*);
extern int getContextCount(void);
+extern void TracebackContextPreemptionCallGo(int);
*/
import "C"
import (
"fmt"
"runtime"
+ "sync"
"unsafe"
)
func init() {
register("TracebackContext", TracebackContext)
+ register("TracebackContextPreemption", TracebackContextPreemption)
}
var tracebackOK bool
@@ -105,3 +107,30 @@ wantLoop:
tracebackOK = false
}
}
+
+// Issue 47441.
+func TracebackContextPreemption() {
+ runtime.SetCgoTraceback(0, unsafe.Pointer(C.tcTraceback), unsafe.Pointer(C.tcContextSimple), unsafe.Pointer(C.tcSymbolizer))
+
+ const funcs = 10
+ const calls = 1e5
+ var wg sync.WaitGroup
+ for i := 0; i < funcs; i++ {
+ wg.Add(1)
+ go func(i int) {
+ defer wg.Done()
+ for j := 0; j < calls; j++ {
+ C.TracebackContextPreemptionCallGo(C.int(i*calls + j))
+ }
+ }(i)
+ }
+ wg.Wait()
+
+ fmt.Println("OK")
+}
+
+//export TracebackContextPreemptionGoFunction
+func TracebackContextPreemptionGoFunction(i C.int) {
+ // Do some busy work.
+ fmt.Sprintf("%d\n", i)
+}
diff --git a/src/runtime/testdata/testprogcgo/tracebackctxt_c.c b/src/runtime/testdata/testprogcgo/tracebackctxt_c.c
index 900cada0d3..910cb7b899 100644
--- a/src/runtime/testdata/testprogcgo/tracebackctxt_c.c
+++ b/src/runtime/testdata/testprogcgo/tracebackctxt_c.c
@@ -11,6 +11,7 @@
// Functions exported from Go.
extern void G1(void);
extern void G2(void);
+extern void TracebackContextPreemptionGoFunction(int);
void C1() {
G1();
@@ -62,10 +63,17 @@ void tcContext(void* parg) {
}
}
+void tcContextSimple(void* parg) {
+ struct cgoContextArg* arg = (struct cgoContextArg*)(parg);
+ if (arg->context == 0) {
+ arg->context = 1;
+ }
+}
+
void tcTraceback(void* parg) {
int base, i;
struct cgoTracebackArg* arg = (struct cgoTracebackArg*)(parg);
- if (arg->context == 0) {
+ if (arg->context == 0 && arg->sigContext == 0) {
// This shouldn't happen in this program.
abort();
}
@@ -89,3 +97,7 @@ void tcSymbolizer(void *parg) {
arg->func = "cFunction";
arg->lineno = arg->pc + (arg->more << 16);
}
+
+void TracebackContextPreemptionCallGo(int i) {
+ TracebackContextPreemptionGoFunction(i);
+}
From b7a85e0003cedb1b48a1fd3ae5b746ec6330102e Mon Sep 17 00:00:00 2001
From: Damien Neil
Date: Wed, 7 Jul 2021 16:34:34 -0700
Subject: [PATCH 11/29] net/http/httputil: close incoming ReverseProxy request
body
Reading from an incoming request body after the request handler aborts
with a panic can cause a panic, becuse http.Server does not (contrary
to its documentation) close the request body in this case.
Always close the incoming request body in ReverseProxy.ServeHTTP to
ensure that any in-flight outgoing requests using the body do not
read from it.
Updates #46866
Fixes CVE-2021-36221
Change-Id: I310df269200ad8732c5d9f1a2b00de68725831df
Reviewed-on: https://go-review.googlesource.com/c/go/+/333191
Trust: Damien Neil
Reviewed-by: Brad Fitzpatrick
Reviewed-by: Filippo Valsorda
---
src/net/http/httputil/reverseproxy.go | 9 +++++
src/net/http/httputil/reverseproxy_test.go | 39 ++++++++++++++++++++++
2 files changed, 48 insertions(+)
diff --git a/src/net/http/httputil/reverseproxy.go b/src/net/http/httputil/reverseproxy.go
index 5d39955d62..8b63368386 100644
--- a/src/net/http/httputil/reverseproxy.go
+++ b/src/net/http/httputil/reverseproxy.go
@@ -235,6 +235,15 @@ func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
if req.ContentLength == 0 {
outreq.Body = nil // Issue 16036: nil Body for http.Transport retries
}
+ if outreq.Body != nil {
+ // Reading from the request body after returning from a handler is not
+ // allowed, and the RoundTrip goroutine that reads the Body can outlive
+ // this handler. This can lead to a crash if the handler panics (see
+ // Issue 46866). Although calling Close doesn't guarantee there isn't
+ // any Read in flight after the handle returns, in practice it's safe to
+ // read after closing it.
+ defer outreq.Body.Close()
+ }
if outreq.Header == nil {
outreq.Header = make(http.Header) // Issue 33142: historical behavior was to always allocate
}
diff --git a/src/net/http/httputil/reverseproxy_test.go b/src/net/http/httputil/reverseproxy_test.go
index 1898ed8b8a..4b6ad77a29 100644
--- a/src/net/http/httputil/reverseproxy_test.go
+++ b/src/net/http/httputil/reverseproxy_test.go
@@ -1122,6 +1122,45 @@ func TestReverseProxy_PanicBodyError(t *testing.T) {
rproxy.ServeHTTP(httptest.NewRecorder(), req)
}
+// Issue #46866: panic without closing incoming request body causes a panic
+func TestReverseProxy_PanicClosesIncomingBody(t *testing.T) {
+ backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ out := "this call was relayed by the reverse proxy"
+ // Coerce a wrong content length to induce io.ErrUnexpectedEOF
+ w.Header().Set("Content-Length", fmt.Sprintf("%d", len(out)*2))
+ fmt.Fprintln(w, out)
+ }))
+ defer backend.Close()
+ backendURL, err := url.Parse(backend.URL)
+ if err != nil {
+ t.Fatal(err)
+ }
+ proxyHandler := NewSingleHostReverseProxy(backendURL)
+ proxyHandler.ErrorLog = log.New(io.Discard, "", 0) // quiet for tests
+ frontend := httptest.NewServer(proxyHandler)
+ defer frontend.Close()
+ frontendClient := frontend.Client()
+
+ var wg sync.WaitGroup
+ for i := 0; i < 2; i++ {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ for j := 0; j < 10; j++ {
+ const reqLen = 6 * 1024 * 1024
+ req, _ := http.NewRequest("POST", frontend.URL, &io.LimitedReader{R: neverEnding('x'), N: reqLen})
+ req.ContentLength = reqLen
+ resp, _ := frontendClient.Transport.RoundTrip(req)
+ if resp != nil {
+ io.Copy(io.Discard, resp.Body)
+ resp.Body.Close()
+ }
+ }
+ }()
+ }
+ wg.Wait()
+}
+
func TestSelectFlushInterval(t *testing.T) {
tests := []struct {
name string
From b8ca6e59eda969c1d3aed9b0c5bd9e99cf0e7dfe Mon Sep 17 00:00:00 2001
From: Josh Bleecher Snyder
Date: Fri, 30 Jul 2021 11:04:36 -0700
Subject: [PATCH 12/29] all: gofmt
Change-Id: Icfafcfb62a389d9fd2e7a4d17809486ed91f15c3
Reviewed-on: https://go-review.googlesource.com/c/go/+/338629
Trust: Josh Bleecher Snyder
Run-TryBot: Josh Bleecher Snyder
TryBot-Result: Go Bot
Reviewed-by: Ian Lance Taylor
---
src/crypto/ed25519/internal/edwards25519/field/fe_amd64.go | 1 +
src/runtime/export_debug_regabiargs_off_test.go | 3 +--
src/runtime/export_debug_regabiargs_on_test.go | 3 +--
3 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/src/crypto/ed25519/internal/edwards25519/field/fe_amd64.go b/src/crypto/ed25519/internal/edwards25519/field/fe_amd64.go
index 44dc8e8caf..8fe583939f 100644
--- a/src/crypto/ed25519/internal/edwards25519/field/fe_amd64.go
+++ b/src/crypto/ed25519/internal/edwards25519/field/fe_amd64.go
@@ -1,5 +1,6 @@
// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
+//go:build amd64 && gc && !purego
// +build amd64,gc,!purego
package field
diff --git a/src/runtime/export_debug_regabiargs_off_test.go b/src/runtime/export_debug_regabiargs_off_test.go
index fce37ab4d1..5009003d27 100644
--- a/src/runtime/export_debug_regabiargs_off_test.go
+++ b/src/runtime/export_debug_regabiargs_off_test.go
@@ -3,8 +3,7 @@
// license that can be found in the LICENSE file.
//go:build amd64 && linux && !goexperiment.regabiargs
-// +build amd64,linux
-// +build !goexperiment.regabiargs
+// +build amd64,linux,!goexperiment.regabiargs
package runtime
diff --git a/src/runtime/export_debug_regabiargs_on_test.go b/src/runtime/export_debug_regabiargs_on_test.go
index 3c65127e56..e1b72efd0f 100644
--- a/src/runtime/export_debug_regabiargs_on_test.go
+++ b/src/runtime/export_debug_regabiargs_on_test.go
@@ -3,8 +3,7 @@
// license that can be found in the LICENSE file.
//go:build amd64 && linux && goexperiment.regabiargs
-// +build amd64,linux
-// +build goexperiment.regabiargs
+// +build amd64,linux,goexperiment.regabiargs
package runtime
From 8a7ee4c51e992174d432ce0f40d9387a32d6ee4a Mon Sep 17 00:00:00 2001
From: Ian Lance Taylor
Date: Sat, 31 Jul 2021 15:39:08 -0700
Subject: [PATCH 13/29] io/fs: don't use absolute path in DirEntry.Name doc
Fixes #47485
Change-Id: I64ac00905a403b7594c706141679051a93058a31
Reviewed-on: https://go-review.googlesource.com/c/go/+/338889
Trust: Ian Lance Taylor
Run-TryBot: Ian Lance Taylor
TryBot-Result: Go Bot
Reviewed-by: Dmitri Shuralyov
---
src/io/fs/fs.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/io/fs/fs.go b/src/io/fs/fs.go
index e1be32478e..e603afadb0 100644
--- a/src/io/fs/fs.go
+++ b/src/io/fs/fs.go
@@ -86,7 +86,7 @@ type File interface {
type DirEntry interface {
// Name returns the name of the file (or subdirectory) described by the entry.
// This name is only the final element of the path (the base name), not the entire path.
- // For example, Name would return "hello.go" not "/home/gopher/hello.go".
+ // For example, Name would return "hello.go" not "home/gopher/hello.go".
Name() string
// IsDir reports whether the entry describes a directory.
From 6e738868a7a943d7d4fd6bb1963e7f6d78111726 Mon Sep 17 00:00:00 2001
From: Damien Neil
Date: Tue, 3 Aug 2021 19:38:37 -0700
Subject: [PATCH 14/29] net/http: speed up and deflake
TestCancelRequestWhenSharingConnection
This test made many requests over the same connection for 10
seconds, trusting that this will exercise the request cancelation
race from #41600.
Change the test to exhibit the specific race in a targeted fashion
with only two requests.
Updates #41600.
Updates #47016.
Change-Id: If99c9b9331ff645f6bb67fe9fb79b8aab8784710
Reviewed-on: https://go-review.googlesource.com/c/go/+/339594
Trust: Damien Neil
Run-TryBot: Damien Neil
TryBot-Result: Go Bot
Reviewed-by: Heschi Kreinick
---
src/net/http/transport_test.go | 81 ++++++++++++++++++++++------------
1 file changed, 53 insertions(+), 28 deletions(-)
diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go
index 690e0c299d..eeaa492644 100644
--- a/src/net/http/transport_test.go
+++ b/src/net/http/transport_test.go
@@ -6441,10 +6441,11 @@ func TestErrorWriteLoopRace(t *testing.T) {
// Test that a new request which uses the connection of an active request
// cannot cause it to be canceled as well.
func TestCancelRequestWhenSharingConnection(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping in short mode")
- }
+ reqc := make(chan chan struct{}, 2)
ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, req *Request) {
+ ch := make(chan struct{}, 1)
+ reqc <- ch
+ <-ch
w.Header().Add("Content-Length", "0")
}))
defer ts.Close()
@@ -6456,34 +6457,58 @@ func TestCancelRequestWhenSharingConnection(t *testing.T) {
var wg sync.WaitGroup
- ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-
- for i := 0; i < 10; i++ {
- wg.Add(1)
- go func() {
- defer wg.Done()
- for ctx.Err() == nil {
- reqctx, reqcancel := context.WithCancel(ctx)
- go reqcancel()
- req, _ := NewRequestWithContext(reqctx, "GET", ts.URL, nil)
- res, err := client.Do(req)
- if err == nil {
- res.Body.Close()
- }
- }
- }()
- }
-
- for ctx.Err() == nil {
- req, _ := NewRequest("GET", ts.URL, nil)
- if res, err := client.Do(req); err != nil {
- t.Errorf("unexpected: %p %v", req, err)
- break
- } else {
+ wg.Add(1)
+ putidlec := make(chan chan struct{})
+ go func() {
+ defer wg.Done()
+ ctx := httptrace.WithClientTrace(context.Background(), &httptrace.ClientTrace{
+ PutIdleConn: func(error) {
+ // Signal that the idle conn has been returned to the pool,
+ // and wait for the order to proceed.
+ ch := make(chan struct{})
+ putidlec <- ch
+ <-ch
+ },
+ })
+ req, _ := NewRequestWithContext(ctx, "GET", ts.URL, nil)
+ res, err := client.Do(req)
+ if err == nil {
res.Body.Close()
}
- }
+ if err != nil {
+ t.Errorf("request 1: got err %v, want nil", err)
+ }
+ }()
+ // Wait for the first request to receive a response and return the
+ // connection to the idle pool.
+ r1c := <-reqc
+ close(r1c)
+ idlec := <-putidlec
+
+ wg.Add(1)
+ cancelctx, cancel := context.WithCancel(context.Background())
+ go func() {
+ defer wg.Done()
+ req, _ := NewRequestWithContext(cancelctx, "GET", ts.URL, nil)
+ res, err := client.Do(req)
+ if err == nil {
+ res.Body.Close()
+ }
+ if !errors.Is(err, context.Canceled) {
+ t.Errorf("request 2: got err %v, want Canceled", err)
+ }
+ }()
+
+ // Wait for the second request to arrive at the server, and then cancel
+ // the request context.
+ r2c := <-reqc
cancel()
+
+ // Give the cancelation a moment to take effect, and then unblock the first request.
+ time.Sleep(1 * time.Millisecond)
+ close(idlec)
+
+ close(r2c)
wg.Wait()
}
From fd45e267c2f6ce7c6a88842e3ad94d3469223e42 Mon Sep 17 00:00:00 2001
From: Matthew Dempsky
Date: Thu, 5 Aug 2021 13:05:23 -0700
Subject: [PATCH 15/29] runtime: warn that KeepAlive is not an unsafe.Pointer
workaround
Even experienced users occasionally mistake that runtime.KeepAlive can
be used as a workaround for following the unsafe.Pointer safety rules,
but it cannot. Add an explicit warning to this effect to dissuade
users from trying to use it as such.
Fixes #47562.
Change-Id: I842e33a3e1c080933c6b1bd1b6318448adbf495c
Reviewed-on: https://go-review.googlesource.com/c/go/+/340269
Trust: Matthew Dempsky
Reviewed-by: Ian Lance Taylor
---
src/runtime/mfinal.go | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/runtime/mfinal.go b/src/runtime/mfinal.go
index fd318d49a8..c134a0f22d 100644
--- a/src/runtime/mfinal.go
+++ b/src/runtime/mfinal.go
@@ -466,6 +466,10 @@ okarg:
// Without the KeepAlive call, the finalizer could run at the start of
// syscall.Read, closing the file descriptor before syscall.Read makes
// the actual system call.
+//
+// Note: KeepAlive should only be used to prevent finalizers from
+// running prematurely. In particular, when used with unsafe.Pointer,
+// the rules for valid uses of unsafe.Pointer still apply.
func KeepAlive(x interface{}) {
// Introduce a use of x that the compiler can't eliminate.
// This makes sure x is alive on entry. We need x to be alive
From 70546f6404c5927a9868a80ccbf4c6c2beaea671 Mon Sep 17 00:00:00 2001
From: "Jason A. Donenfeld"
Date: Thu, 5 Aug 2021 13:37:29 +0200
Subject: [PATCH 16/29] runtime: allow arm64 SEH to be called if illegal
instruction
DLLs built with recent Microsoft toolchains for ARM64 test for ARMv8.1
atomics by potentially calling an illegal instruction, and then trapping
the exception to disable use of them by way of a structured exception
handler. However, vectored exception handlers are always called before
structured exception handlers. When LoadLibrary-ing DLLs that do this
probing during initialization, our lastcontinuehandler winds up being
called, and then crashing, but actually it should give execution back to
the library to handle the exception and fix up the state. So special
case this for arm64 with illegal instructions, and hope that we're not
masking other things in external DLLs that might more fatally trigger an
illegal instruction exception.
Updates #47576.
Change-Id: I341ab99cd8d513ae999b75596749d49779072022
Reviewed-on: https://go-review.googlesource.com/c/go/+/340070
Trust: Jason A. Donenfeld
Run-TryBot: Jason A. Donenfeld
TryBot-Result: Go Bot
Reviewed-by: Brad Fitzpatrick
Reviewed-by: Russ Cox
---
src/runtime/signal_windows.go | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/src/runtime/signal_windows.go b/src/runtime/signal_windows.go
index f2ce24d735..b720ddcf16 100644
--- a/src/runtime/signal_windows.go
+++ b/src/runtime/signal_windows.go
@@ -183,6 +183,17 @@ func lastcontinuehandler(info *exceptionrecord, r *context, gp *g) int32 {
return _EXCEPTION_CONTINUE_SEARCH
}
+ // VEH is called before SEH, but arm64 MSVC DLLs use SEH to trap
+ // illegal instructions during runtime initialization to determine
+ // CPU features, so if we make it to the last handler and we're
+ // arm64 and it's an illegal instruction and this is coming from
+ // non-Go code, then assume it's this runtime probing happen, and
+ // pass that onward to SEH.
+ if GOARCH == "arm64" && info.exceptioncode == _EXCEPTION_ILLEGAL_INSTRUCTION &&
+ (r.ip() < firstmoduledata.text || firstmoduledata.etext < r.ip()) {
+ return _EXCEPTION_CONTINUE_SEARCH
+ }
+
winthrow(info, r, gp)
return 0 // not reached
}
From 63b968f4f86f4c23ce92b7ac2feda4fc7ca17c8e Mon Sep 17 00:00:00 2001
From: "Bryan C. Mills"
Date: Fri, 16 Jul 2021 16:51:11 -0400
Subject: [PATCH 17/29] doc/go1.17: clarify Modules changes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Writing CL 333629 clarified my thinking about the behavioral changes
associated with lazy loading. There are really two interrelated
changes — graph pruning, and lazy loading proper — that are both made
possible by the added redundancy in the go.mod file.
(I had initially approached the whole cluster of features as “lazy
loading” because that was the starting point for the design. Graph
pruning came into the picture when we looked at how to bound the
worst-case behavior of lazy loading, but it is really the more
important of the two aspects of the design.)
Note that this change adds links to doc anchors added in CL 333629.
Fixes #36460
Fixes #47397
Change-Id: I0ef4af57f647bf5ee210ea7099191fb4befa2cc1
Reviewed-on: https://go-review.googlesource.com/c/go/+/335135
Trust: Bryan C. Mills
Run-TryBot: Bryan C. Mills
TryBot-Result: Go Bot
Reviewed-by: Jay Conrod
---
doc/go1.17.html | 70 +++++++++++++++++++++++++++++++------------------
1 file changed, 45 insertions(+), 25 deletions(-)
diff --git a/doc/go1.17.html b/doc/go1.17.html
index 48811e6b67..a8307bacac 100644
--- a/doc/go1.17.html
+++ b/doc/go1.17.html
@@ -134,35 +134,54 @@ Do not send CLs removing the interior tags from such phrases.
Go command
-Lazy module loading
+
+Pruned module graphs in go 1.17 modules
+ If a module specifies go 1.17 or higher, the module
+ graph includes only the immediate dependencies of
+ other go 1.17 modules, not their full transitive
+ dependencies. (See Module graph pruning
+ for more detail.)
+
+
+
+ For the go command to correctly resolve transitive imports using
+ the pruned module graph, the go.mod file for each module needs to
+ include more detail about the transitive dependencies relevant to that module.
If a module specifies go 1.17 or higher in its
- go.mod file, its transitive requirements are now loaded lazily,
- avoiding the need to download or read go.mod files for
- otherwise-irrelevant dependencies. To support lazy loading, in Go 1.17 modules
- the go command maintains explicit requirements in
- the go.mod file for every dependency that provides any package
- transitively imported by any package or test within the module.
- See the design
- document for more detail.
-
+ go.mod file, its go.mod file now contains an
+ explicit require
+ directive for every module that provides a transitively-imported package.
+ (In previous versions, the go.mod file typically only included
+ explicit requirements for directly-imported packages.)
+
+
+
+ Since the expanded go.mod file needed for module graph pruning
+ includes all of the dependencies needed to load the imports of any package in
+ the main module, if the main module specifies
+ go 1.17 or higher the go tool no longer
+ reads (or even downloads) go.mod files for dependencies if they
+ are not needed in order to complete the requested command.
+ (See Lazy loading.)
- Because the number of additional explicit requirements in the go.mod file may
- be substantial, in a Go 1.17 module the newly-added requirements
- on indirect dependencies are maintained in a
- separate require block from the block containing direct
- dependencies.
+ Because the number of explicit requirements may be substantially larger in an
+ expanded Go 1.17 go.mod file, the newly-added requirements
+ on indirect dependencies in a go 1.17
+ module are maintained in a separate require block from the block
+ containing direct dependencies.
- To facilitate the upgrade to lazy loading, the
- go mod tidy subcommand now supports
- a -go flag to set or change the go version in
- the go.mod file. To enable lazy loading for an existing module
- without changing the selected versions of its dependencies, run:
+ To facilitate the upgrade to Go 1.17 pruned module graphs, the
+ go mod tidy
+ subcommand now supports a -go flag to set or change
+ the go version in the go.mod file. To convert
+ the go.mod file for an existing module to Go 1.17 without
+ changing the selected versions of its dependencies, run:
@@ -199,10 +218,10 @@ Do not send CLs removing the interior tags from such phrases.
- The go mod graph subcommand also
- supports the -go flag, which causes it to report the graph as
- seen by the indicated Go version, showing dependencies that may otherwise be
- pruned out by lazy loading.
+ The go mod graph
+ subcommand also supports the -go flag, which causes it to report
+ the graph as seen by the indicated Go version, showing dependencies that may
+ otherwise be pruned out.
@@ -270,7 +289,8 @@ Do not send CLs removing the interior tags from such phrases.
If the main module specifies go 1.17 or higher,
- go mod vendor now annotates
+ go mod vendor
+ now annotates
vendor/modules.txt with the go version indicated by
each vendored module in its own go.mod file. The annotated
version is used when building the module's packages from vendored source code.
From 8eaf4d16bc69724cd450345cbaf55f2e2aef9b9c Mon Sep 17 00:00:00 2001
From: Cherry Mui
Date: Fri, 6 Aug 2021 15:37:10 -0400
Subject: [PATCH 18/29] make.bash: do not overwrite GO_LDSO if already set
Change-Id: I704bdb411bda3d8a40906c12f182e268dca4718f
Reviewed-on: https://go-review.googlesource.com/c/go/+/340450
Trust: Cherry Mui
Reviewed-by: Ian Lance Taylor
Run-TryBot: Ian Lance Taylor
TryBot-Result: Go Bot
---
src/make.bash | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/make.bash b/src/make.bash
index 4fb13f6275..f5e1b60bd5 100755
--- a/src/make.bash
+++ b/src/make.bash
@@ -130,8 +130,8 @@ if [ "$(uname -s)" = "GNU/kFreeBSD" ]; then
export CGO_ENABLED=0
fi
-# Test which linker/loader our system is using
-if type readelf >/dev/null 2>&1; then
+# Test which linker/loader our system is using, if GO_LDSO is not set.
+if [ -z "$GO_LDSO" ] && type readelf >/dev/null 2>&1; then
if echo "int main() { return 0; }" | ${CC:-cc} -o ./test-musl-ldso -x c - >/dev/null 2>&1; then
LDSO=$(readelf -l ./test-musl-ldso | grep 'interpreter:' | sed -e 's/^.*interpreter: \(.*\)[]]/\1/') >/dev/null 2>&1
[ -z "$LDSO" ] || export GO_LDSO="$LDSO"
From 891547e2d4bc2a23973e2c9f972ce69b2b48478e Mon Sep 17 00:00:00 2001
From: "Bryan C. Mills"
Date: Fri, 6 Aug 2021 21:10:31 -0400
Subject: [PATCH 19/29] doc/go1.17: fix a typo introduced in CL 335135
Change-Id: I62388bcb6d6f910ffa95d3db856ea29838573256
Reviewed-on: https://go-review.googlesource.com/c/go/+/340590
Trust: Bryan C. Mills
Run-TryBot: Bryan C. Mills
Reviewed-by: Rob Pike
---
doc/go1.17.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/go1.17.html b/doc/go1.17.html
index a8307bacac..d469f400ad 100644
--- a/doc/go1.17.html
+++ b/doc/go1.17.html
@@ -150,7 +150,7 @@ Do not send CLs removing the interior tags from such phrases.
the pruned module graph, the go.mod file for each module needs to
include more detail about the transitive dependencies relevant to that module.
If a module specifies go 1.17 or higher in its
- go.mod file, its go.mod file now contains an
+ go.mod file, its go.mod file now contains an
explicit require
directive for every module that provides a transitively-imported package.
(In previous versions, the go.mod file typically only included
From 507cc341ec2cb96b0199800245f222146f799266 Mon Sep 17 00:00:00 2001
From: Cuong Manh Le
Date: Mon, 9 Aug 2021 00:52:21 +0700
Subject: [PATCH 20/29] doc: add example for conversion from slice expressions
to array ptr
Fixes #47599
Change-Id: I8f4ccd3b0c2bcdb057ee853163b4421229141333
Reviewed-on: https://go-review.googlesource.com/c/go/+/340351
Trust: Cuong Manh Le
Run-TryBot: Cuong Manh Le
TryBot-Result: Go Bot
Reviewed-by: Keith Randall
---
doc/go_spec.html | 1 +
1 file changed, 1 insertion(+)
diff --git a/doc/go_spec.html b/doc/go_spec.html
index 0e14a1f3b6..fd5fee46eb 100644
--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -4329,6 +4329,7 @@ a run-time panic occurs.
s := make([]byte, 2, 4)
s0 := (*[0]byte)(s) // s0 != nil
+s1 := (*[1]byte)(s[1:]) // &s1[0] == &s[1]
s2 := (*[2]byte)(s) // &s2[0] == &s[0]
s4 := (*[4]byte)(s) // panics: len([4]byte) > len(s)
From 7aeaad5c86174f61b084d72d89fb02d7fc64391c Mon Sep 17 00:00:00 2001
From: Ian Lance Taylor
Date: Wed, 4 Aug 2021 20:55:28 -0700
Subject: [PATCH 21/29] runtime/cgo: when using msan explicitly unpoison
cgoCallers
This avoids an incorrect msan uninitialized memory report when using
runtime.SetCgoTraceback when a signal occurs while the fifth argument
register is undefined. See the issue for more details.
Fixes #47543
Change-Id: I3d1b673e2c93471ccdae0171a99b88b5a6062840
Reviewed-on: https://go-review.googlesource.com/c/go/+/339902
Trust: Ian Lance Taylor
Run-TryBot: Ian Lance Taylor
TryBot-Result: Go Bot
Reviewed-by: Austin Clements
---
misc/cgo/testsanitizers/msan_test.go | 1 +
misc/cgo/testsanitizers/testdata/msan8.go | 109 ++++++++++++++++++++++
src/runtime/cgo/gcc_traceback.c | 20 ++++
3 files changed, 130 insertions(+)
create mode 100644 misc/cgo/testsanitizers/testdata/msan8.go
diff --git a/misc/cgo/testsanitizers/msan_test.go b/misc/cgo/testsanitizers/msan_test.go
index 2a3494fbfc..5ee9947a58 100644
--- a/misc/cgo/testsanitizers/msan_test.go
+++ b/misc/cgo/testsanitizers/msan_test.go
@@ -42,6 +42,7 @@ func TestMSAN(t *testing.T) {
{src: "msan5.go"},
{src: "msan6.go"},
{src: "msan7.go"},
+ {src: "msan8.go"},
{src: "msan_fail.go", wantErr: true},
}
for _, tc := range cases {
diff --git a/misc/cgo/testsanitizers/testdata/msan8.go b/misc/cgo/testsanitizers/testdata/msan8.go
new file mode 100644
index 0000000000..1cb5c5677f
--- /dev/null
+++ b/misc/cgo/testsanitizers/testdata/msan8.go
@@ -0,0 +1,109 @@
+// Copyright 2021 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
+
+/*
+#include
+#include
+#include
+
+#include
+
+// cgoTracebackArg is the type of the argument passed to msanGoTraceback.
+struct cgoTracebackArg {
+ uintptr_t context;
+ uintptr_t sigContext;
+ uintptr_t* buf;
+ uintptr_t max;
+};
+
+// msanGoTraceback is registered as the cgo traceback function.
+// This will be called when a signal occurs.
+void msanGoTraceback(void* parg) {
+ struct cgoTracebackArg* arg = (struct cgoTracebackArg*)(parg);
+ arg->buf[0] = 0;
+}
+
+// msanGoWait will be called with all registers undefined as far as
+// msan is concerned. It just waits for a signal.
+// Because the registers are msan-undefined, the signal handler will
+// be invoked with all registers msan-undefined.
+__attribute__((noinline))
+void msanGoWait(unsigned long a1, unsigned long a2, unsigned long a3, unsigned long a4, unsigned long a5, unsigned long a6) {
+ sigset_t mask;
+
+ sigemptyset(&mask);
+ sigsuspend(&mask);
+}
+
+// msanGoSignalThread is the thread ID of the msanGoLoop thread.
+static pthread_t msanGoSignalThread;
+
+// msanGoSignalThreadSet is used to record that msanGoSignalThread
+// has been initialized. This is accessed atomically.
+static int32_t msanGoSignalThreadSet;
+
+// uninit is explicitly poisoned, so that we can make all registers
+// undefined by calling msanGoWait.
+static unsigned long uninit;
+
+// msanGoLoop loops calling msanGoWait, with the arguments passed
+// such that msan thinks that they are undefined. msan permits
+// undefined values to be used as long as they are not used to
+// for conditionals or for memory access.
+void msanGoLoop() {
+ int i;
+
+ msanGoSignalThread = pthread_self();
+ __atomic_store_n(&msanGoSignalThreadSet, 1, __ATOMIC_SEQ_CST);
+
+ // Force uninit to be undefined for msan.
+ __msan_poison(&uninit, sizeof uninit);
+ for (i = 0; i < 100; i++) {
+ msanGoWait(uninit, uninit, uninit, uninit, uninit, uninit);
+ }
+}
+
+// msanGoReady returns whether msanGoSignalThread is set.
+int msanGoReady() {
+ return __atomic_load_n(&msanGoSignalThreadSet, __ATOMIC_SEQ_CST) != 0;
+}
+
+// msanGoSendSignal sends a signal to the msanGoLoop thread.
+void msanGoSendSignal() {
+ pthread_kill(msanGoSignalThread, SIGWINCH);
+}
+*/
+import "C"
+
+import (
+ "runtime"
+ "time"
+)
+
+func main() {
+ runtime.SetCgoTraceback(0, C.msanGoTraceback, nil, nil)
+
+ c := make(chan bool)
+ go func() {
+ defer func() { c <- true }()
+ C.msanGoLoop()
+ }()
+
+ for C.msanGoReady() == 0 {
+ time.Sleep(time.Microsecond)
+ }
+
+loop:
+ for {
+ select {
+ case <-c:
+ break loop
+ default:
+ C.msanGoSendSignal()
+ time.Sleep(time.Microsecond)
+ }
+ }
+}
diff --git a/src/runtime/cgo/gcc_traceback.c b/src/runtime/cgo/gcc_traceback.c
index d86331c583..6e9470c43c 100644
--- a/src/runtime/cgo/gcc_traceback.c
+++ b/src/runtime/cgo/gcc_traceback.c
@@ -7,6 +7,14 @@
#include
#include "libcgo.h"
+#ifndef __has_feature
+#define __has_feature(x) 0
+#endif
+
+#if __has_feature(memory_sanitizer)
+#include
+#endif
+
// Call the user's traceback function and then call sigtramp.
// The runtime signal handler will jump to this code.
// We do it this way so that the user's traceback function will be called
@@ -19,6 +27,18 @@ x_cgo_callers(uintptr_t sig, void *info, void *context, void (*cgoTraceback)(str
arg.SigContext = (uintptr_t)(context);
arg.Buf = cgoCallers;
arg.Max = 32; // must match len(runtime.cgoCallers)
+
+#if __has_feature(memory_sanitizer)
+ // This function is called directly from the signal handler.
+ // The arguments are passed in registers, so whether msan
+ // considers cgoCallers to be initialized depends on whether
+ // it considers the appropriate register to be initialized.
+ // That can cause false reports in rare cases.
+ // Explicitly unpoison the memory to avoid that.
+ // See issue #47543 for more details.
+ __msan_unpoison(&arg, sizeof arg);
+#endif
+
(*cgoTraceback)(&arg);
sigtramp(sig, info, context);
}
From f1dce319ffd9d3663f522141abfb9c1ec9d92e04 Mon Sep 17 00:00:00 2001
From: Jay Conrod
Date: Thu, 5 Aug 2021 15:18:42 -0700
Subject: [PATCH 22/29] cmd/go: with -mod=vendor, don't panic if there are
duplicate requirements
In loadModFile with -mod=vendor, load the vendor list and use it to
initialize the module graph before calling updateRoots.
In updateLazyRoots with any mode other than "mod", return the original
*Requirements if no roots needed to be upgraded, even if there are
inconsistencies. This means 'go list -m -mod=readonly' and -mod=vendor
may succeed if there are duplicate requirements or requirements on
versions of the main module.
Fixes #47565
Change-Id: I4640dffc4a7359367cc910da0d29e3538bfd1ca4
Reviewed-on: https://go-review.googlesource.com/c/go/+/340252
Trust: Jay Conrod
Trust: Bryan C. Mills
Reviewed-by: Bryan C. Mills
---
src/cmd/go/internal/modload/buildlist.go | 19 +++++++++
src/cmd/go/internal/modload/init.go | 39 +++++++++----------
.../go/testdata/script/mod_tidy_lazy_self.txt | 17 +++-----
.../mod_vendor_redundant_requirement.txt | 29 ++++++++++++++
4 files changed, 72 insertions(+), 32 deletions(-)
create mode 100644 src/cmd/go/testdata/script/mod_vendor_redundant_requirement.txt
diff --git a/src/cmd/go/internal/modload/buildlist.go b/src/cmd/go/internal/modload/buildlist.go
index 604a57b437..bf69567316 100644
--- a/src/cmd/go/internal/modload/buildlist.go
+++ b/src/cmd/go/internal/modload/buildlist.go
@@ -191,6 +191,19 @@ func (rs *Requirements) rootSelected(path string) (version string, ok bool) {
return "", false
}
+// hasRedundantRoot returns true if the root list contains multiple requirements
+// of the same module or a requirement on any version of the main module.
+// Redundant requirements should be pruned, but they may influence version
+// selection.
+func (rs *Requirements) hasRedundantRoot() bool {
+ for i, m := range rs.rootModules {
+ if m.Path == Target.Path || (i > 0 && m.Path == rs.rootModules[i-1].Path) {
+ return true
+ }
+ }
+ return false
+}
+
// Graph returns the graph of module requirements loaded from the current
// root modules (as reported by RootModules).
//
@@ -882,6 +895,12 @@ func updateLazyRoots(ctx context.Context, direct map[string]bool, rs *Requiremen
// and (trivially) version.
if !rootsUpgraded {
+ if cfg.BuildMod != "mod" {
+ // The only changes to the root set (if any) were to remove duplicates.
+ // The requirements are consistent (if perhaps redundant), so keep the
+ // original rs to preserve its ModuleGraph.
+ return rs, nil
+ }
// The root set has converged: every root going into this iteration was
// already at its selected version, although we have have removed other
// (redundant) roots for the same path.
diff --git a/src/cmd/go/internal/modload/init.go b/src/cmd/go/internal/modload/init.go
index a8cbd9fe16..45f724d5e3 100644
--- a/src/cmd/go/internal/modload/init.go
+++ b/src/cmd/go/internal/modload/init.go
@@ -449,13 +449,22 @@ func loadModFile(ctx context.Context) (rs *Requirements, needCommit bool) {
}
setDefaultBuildMod() // possibly enable automatic vendoring
- rs = requirementsFromModFile(ctx)
-
+ rs = requirementsFromModFile()
if cfg.BuildMod == "vendor" {
readVendorList()
checkVendorConsistency()
rs.initVendor(vendorList)
}
+ if rs.hasRedundantRoot() {
+ // If any module path appears more than once in the roots, we know that the
+ // go.mod file needs to be updated even though we have not yet loaded any
+ // transitive dependencies.
+ rs, err = updateRoots(ctx, rs.direct, rs, nil, nil, false)
+ if err != nil {
+ base.Fatalf("go: %v", err)
+ }
+ }
+
if index.goVersionV == "" {
// TODO(#45551): Do something more principled instead of checking
// cfg.CmdName directly here.
@@ -530,7 +539,12 @@ func CreateModFile(ctx context.Context, modPath string) {
base.Fatalf("go: %v", err)
}
- commitRequirements(ctx, modFileGoVersion(), requirementsFromModFile(ctx))
+ rs := requirementsFromModFile()
+ rs, err = updateRoots(ctx, rs.direct, rs, nil, nil, false)
+ if err != nil {
+ base.Fatalf("go: %v", err)
+ }
+ commitRequirements(ctx, modFileGoVersion(), rs)
// Suggest running 'go mod tidy' unless the project is empty. Even if we
// imported all the correct requirements above, we're probably missing
@@ -641,9 +655,8 @@ func initTarget(m module.Version) {
// requirementsFromModFile returns the set of non-excluded requirements from
// the global modFile.
-func requirementsFromModFile(ctx context.Context) *Requirements {
+func requirementsFromModFile() *Requirements {
roots := make([]module.Version, 0, len(modFile.Require))
- mPathCount := map[string]int{Target.Path: 1}
direct := map[string]bool{}
for _, r := range modFile.Require {
if index != nil && index.exclude[r.Mod] {
@@ -656,28 +669,12 @@ func requirementsFromModFile(ctx context.Context) *Requirements {
}
roots = append(roots, r.Mod)
- mPathCount[r.Mod.Path]++
if !r.Indirect {
direct[r.Mod.Path] = true
}
}
module.Sort(roots)
rs := newRequirements(modDepthFromGoVersion(modFileGoVersion()), roots, direct)
-
- // If any module path appears more than once in the roots, we know that the
- // go.mod file needs to be updated even though we have not yet loaded any
- // transitive dependencies.
- for _, n := range mPathCount {
- if n > 1 {
- var err error
- rs, err = updateRoots(ctx, rs.direct, rs, nil, nil, false)
- if err != nil {
- base.Fatalf("go: %v", err)
- }
- break
- }
- }
-
return rs
}
diff --git a/src/cmd/go/testdata/script/mod_tidy_lazy_self.txt b/src/cmd/go/testdata/script/mod_tidy_lazy_self.txt
index ffcea18603..9abbabd2eb 100644
--- a/src/cmd/go/testdata/script/mod_tidy_lazy_self.txt
+++ b/src/cmd/go/testdata/script/mod_tidy_lazy_self.txt
@@ -2,18 +2,13 @@
# 'go mod tidy' should not panic if the main module initially
# requires an older version of itself.
+# A module may require an older version of itself without error. This is
+# inconsistent (the required version is never selected), but we still get
+# a reproducible build list.
+go list -m all
+stdout '^golang.org/issue/46078$'
-# A module that explicitly requires an older version of itself should be
-# rejected as inconsistent: we enforce that every explicit requirement is the
-# selected version of its module path, but the selected version of the main
-# module is always itself — not some explicit version.
-
-! go list -m all
-stderr '^go: updates to go\.mod needed; to update it:\n\tgo mod tidy$'
-
-
-# The suggested 'go mod tidy' command should succeed (not crash).
-
+# 'go mod tidy' should fix this (and not crash).
go mod tidy
diff --git a/src/cmd/go/testdata/script/mod_vendor_redundant_requirement.txt b/src/cmd/go/testdata/script/mod_vendor_redundant_requirement.txt
new file mode 100644
index 0000000000..3f6f5c5276
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_vendor_redundant_requirement.txt
@@ -0,0 +1,29 @@
+# 'go list -mod=vendor' should succeed even when go.mod contains redundant
+# requirements. Verifies #47565.
+go list -mod=vendor
+
+-- go.mod --
+module m
+
+go 1.17
+
+require example.com/m v0.0.0
+require example.com/m v0.0.0
+
+replace example.com/m v0.0.0 => ./m
+-- m/go.mod --
+module example.com/m
+
+go 1.17
+-- m/m.go --
+package m
+-- use.go --
+package use
+
+import _ "example.com/m"
+-- vendor/example.com/m/m.go --
+package m
+-- vendor/modules.txt --
+# example.com/m v0.0.0 => ./m
+## explicit; go 1.17
+example.com/m
From 1f9c9d853067635305f72e247c5b49e3fa5da8af Mon Sep 17 00:00:00 2001
From: fanzha02
Date: Tue, 3 Aug 2021 12:11:29 +0800
Subject: [PATCH 23/29] doc: use "high address/low address" instead of
"top/bottom"
The current document uses the "top" and "bottom" when talking
about the address within a frame, which may easily lead to
misunderstandings. This patch directly uses "high address"
and "low address" to make the expression clearer.
Change-Id: I7469330bbdc158672d7f0314fe6680ebdd9ab79a
Reviewed-on: https://go-review.googlesource.com/c/go/+/339369
Trust: fannie zhang
Reviewed-by: Austin Clements
Reviewed-by: Cherry Mui
---
doc/asm.html | 8 ++++----
src/cmd/internal/obj/textflag.go | 4 ++--
src/runtime/textflag.h | 4 ++--
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/doc/asm.html b/doc/asm.html
index d578800086..51f85eb948 100644
--- a/doc/asm.html
+++ b/doc/asm.html
@@ -166,7 +166,7 @@ jumps and branches.
-SP: Stack pointer: top of stack.
+SP: Stack pointer: the highest address within the local stack frame.
@@ -216,7 +216,7 @@ If a Go prototype does not name its result, the expected assembly name is
The SP pseudo-register is a virtual stack pointer
used to refer to frame-local variables and the arguments being
prepared for function calls.
-It points to the top of the local stack frame, so references should use negative offsets
+It points to the highest address within the local stack frame, so references should use negative offsets
in the range [−framesize, 0):
x-8(SP), y-4(SP), and so on.
@@ -409,7 +409,7 @@ The linker will choose one of the duplicates to use.
(For TEXT items.)
Don't insert the preamble to check if the stack must be split.
The frame for the routine, plus anything it calls, must fit in the
-spare space at the top of the stack segment.
+spare space remaining in the current stack segment.
Used to protect routines such as the stack splitting code itself.
@@ -460,7 +460,7 @@ Only valid on functions that declare a frame size of 0.
TOPFRAME = 2048
(For TEXT items.)
-Function is the top of the call stack. Traceback should stop at this function.
+Function is the outermost frame of the call stack. Traceback should stop at this function.
diff --git a/src/cmd/internal/obj/textflag.go b/src/cmd/internal/obj/textflag.go
index 881e192203..5ae75027c2 100644
--- a/src/cmd/internal/obj/textflag.go
+++ b/src/cmd/internal/obj/textflag.go
@@ -49,8 +49,8 @@ const (
// Function can call reflect.Type.Method or reflect.Type.MethodByName.
REFLECTMETHOD = 1024
- // Function is the top of the call stack. Call stack unwinders should stop
- // at this function.
+ // Function is the outermost frame of the call stack. Call stack unwinders
+ // should stop at this function.
TOPFRAME = 2048
// Function is an ABI wrapper.
diff --git a/src/runtime/textflag.h b/src/runtime/textflag.h
index e727208cd0..214075e360 100644
--- a/src/runtime/textflag.h
+++ b/src/runtime/textflag.h
@@ -32,8 +32,8 @@
#define NOFRAME 512
// Function can call reflect.Type.Method or reflect.Type.MethodByName.
#define REFLECTMETHOD 1024
-// Function is the top of the call stack. Call stack unwinders should stop
-// at this function.
+// Function is the outermost frame of the call stack. Call stack unwinders
+// should stop at this function.
#define TOPFRAME 2048
// Function is an ABI wrapper.
#define ABIWRAPPER 4096
From d4c0ed26ace91cb21fc0a67f088648674052aa3d Mon Sep 17 00:00:00 2001
From: Ian Lance Taylor
Date: Wed, 11 Aug 2021 09:10:55 -0700
Subject: [PATCH 24/29] doc/go1.17: linker passes -I to extld as
-Wl,--dynamic-linker
For #22446
Change-Id: I71a30761a28e81c50b7089d5a28be99c736c2dc8
Reviewed-on: https://go-review.googlesource.com/c/go/+/341332
Trust: Ian Lance Taylor
Run-TryBot: Ian Lance Taylor
Reviewed-by: Heschi Kreinick
TryBot-Result: Go Bot
---
doc/go1.17.html | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/doc/go1.17.html b/doc/go1.17.html
index d469f400ad..972f9c3559 100644
--- a/doc/go1.17.html
+++ b/doc/go1.17.html
@@ -488,6 +488,15 @@ func Foo() bool {
and compare functions by code pointer.
+Linker
+
+
+ When the linker uses external linking mode, which is the default
+ when linking a program that uses cgo, and the linker is invoked
+ with a -I option, the option will now be passed to the
+ external linker as a -Wl,--dynamic-linker option.
+
+
Core library
From dea23e9ca80dd629041cba03ae2544dad19948ee Mon Sep 17 00:00:00 2001
From: Matthew Dempsky
Date: Wed, 11 Aug 2021 12:40:12 -0700
Subject: [PATCH 25/29] src/make.*: make --no-clean flag a no-op that prints a
warning
This flag is undocumented and is no longer useful. Users who want to
install additional toolchains without cleaning the installed packages
should just use `go install`.
This CL changes cmd/dist to print a warning that --no-clean is
deprecated and to advise users to use `go install std cmd` instead,
and then otherwise ignores it:
```
$ ./make.bash --no-clean
Building Go cmd/dist using $GOROOT_BOOTSTRAP. (devel +b7a85e0003 linux/amd64)
warning: --no-clean is deprecated and has no effect; use 'go install std cmd' instead
Building Go toolchain1 using $GOROOT_BOOTSTRAP.
```
Fixes #47204.
Change-Id: I275031832098401a49e491e324e8de3427973630
Reviewed-on: https://go-review.googlesource.com/c/go/+/341392
Trust: Matthew Dempsky
Run-TryBot: Matthew Dempsky
TryBot-Result: Go Bot
Reviewed-by: Ian Lance Taylor
---
src/cmd/dist/build.go | 7 ++++++-
src/make.bash | 8 +-------
src/make.bat | 20 ++++++++++----------
src/make.rc | 7 +------
4 files changed, 18 insertions(+), 24 deletions(-)
diff --git a/src/cmd/dist/build.go b/src/cmd/dist/build.go
index 1abb03bcc5..bec17696f3 100644
--- a/src/cmd/dist/build.go
+++ b/src/cmd/dist/build.go
@@ -1263,14 +1263,19 @@ func cmdbootstrap() {
timelog("start", "dist bootstrap")
defer timelog("end", "dist bootstrap")
- var noBanner bool
+ var noBanner, noClean bool
var debug bool
flag.BoolVar(&rebuildall, "a", rebuildall, "rebuild all")
flag.BoolVar(&debug, "d", debug, "enable debugging of bootstrap process")
flag.BoolVar(&noBanner, "no-banner", noBanner, "do not print banner")
+ flag.BoolVar(&noClean, "no-clean", noClean, "print deprecation warning")
xflagparse(0)
+ if noClean {
+ xprintf("warning: --no-clean is deprecated and has no effect; use 'go install std cmd' instead\n")
+ }
+
// Set GOPATH to an internal directory. We shouldn't actually
// need to store files here, since the toolchain won't
// depend on modules outside of vendor directories, but if
diff --git a/src/make.bash b/src/make.bash
index f5e1b60bd5..7986125a06 100755
--- a/src/make.bash
+++ b/src/make.bash
@@ -203,16 +203,10 @@ if [ "$1" = "--dist-tool" ]; then
exit 0
fi
-buildall="-a"
-if [ "$1" = "--no-clean" ]; then
- buildall=""
- shift
-fi
-
# Run dist bootstrap to complete make.bash.
# Bootstrap installs a proper cmd/dist, built with the new toolchain.
# Throw ours, built with Go 1.4, away after bootstrap.
-./cmd/dist/dist bootstrap $buildall $vflag $GO_DISTFLAGS "$@"
+./cmd/dist/dist bootstrap -a $vflag $GO_DISTFLAGS "$@"
rm -f ./cmd/dist/dist
# DO NOT ADD ANY NEW CODE HERE.
diff --git a/src/make.bat b/src/make.bat
index b4a8e70849..8f2825b09a 100644
--- a/src/make.bat
+++ b/src/make.bat
@@ -112,20 +112,20 @@ if x%2==x--dist-tool goto copydist
if x%3==x--dist-tool goto copydist
if x%4==x--dist-tool goto copydist
-set buildall=-a
-if x%1==x--no-clean set buildall=
-if x%2==x--no-clean set buildall=
-if x%3==x--no-clean set buildall=
-if x%4==x--no-clean set buildall=
-if x%1==x--no-banner set buildall=%buildall% --no-banner
-if x%2==x--no-banner set buildall=%buildall% --no-banner
-if x%3==x--no-banner set buildall=%buildall% --no-banner
-if x%4==x--no-banner set buildall=%buildall% --no-banner
+set bootstrapflags=
+if x%1==x--no-clean set bootstrapflags=--no-clean
+if x%2==x--no-clean set bootstrapflags=--no-clean
+if x%3==x--no-clean set bootstrapflags=--no-clean
+if x%4==x--no-clean set bootstrapflags=--no-clean
+if x%1==x--no-banner set bootstrapflags=%bootstrapflags% --no-banner
+if x%2==x--no-banner set bootstrapflags=%bootstrapflags% --no-banner
+if x%3==x--no-banner set bootstrapflags=%bootstrapflags% --no-banner
+if x%4==x--no-banner set bootstrapflags=%bootstrapflags% --no-banner
:: Run dist bootstrap to complete make.bash.
:: Bootstrap installs a proper cmd/dist, built with the new toolchain.
:: Throw ours, built with Go 1.4, away after bootstrap.
-.\cmd\dist\dist.exe bootstrap %vflag% %buildall%
+.\cmd\dist\dist.exe bootstrap -a %vflag% %bootstrapflags%
if errorlevel 1 goto fail
del .\cmd\dist\dist.exe
goto end
diff --git a/src/make.rc b/src/make.rc
index f5e57e9755..7bdc7dea1c 100755
--- a/src/make.rc
+++ b/src/make.rc
@@ -92,15 +92,10 @@ if(~ $1 --dist-tool){
exit
}
-buildall = -a
-if(~ $1 --no-clean) {
- buildall = ()
- shift
-}
# Run dist bootstrap to complete make.bash.
# Bootstrap installs a proper cmd/dist, built with the new toolchain.
# Throw ours, built with Go 1.4, away after bootstrap.
-./cmd/dist/dist bootstrap $vflag $buildall $*
+./cmd/dist/dist bootstrap -a $vflag $*
rm -f ./cmd/dist/dist
# DO NOT ADD ANY NEW CODE HERE.
From 095bb790e132a498ba191ad6d27f89c1fc4c0232 Mon Sep 17 00:00:00 2001
From: Dmitri Shuralyov
Date: Wed, 11 Aug 2021 22:02:59 -0400
Subject: [PATCH 26/29] os/exec: re-enable LookPathTest/16
This failure was confirmed to be due to a bug in prerelease versions
of Windows, and has been fixed by now. Remove the skip for this test.
Fixes #44379.
Change-Id: Idfb92ffd6b9d416d4c78ef3800a5ffdda06c6562
Reviewed-on: https://go-review.googlesource.com/c/go/+/341455
Trust: Dmitri Shuralyov
Run-TryBot: Dmitri Shuralyov
TryBot-Result: Go Bot
Reviewed-by: Cherry Mui
---
src/os/exec/lp_windows_test.go | 3 ---
1 file changed, 3 deletions(-)
diff --git a/src/os/exec/lp_windows_test.go b/src/os/exec/lp_windows_test.go
index f834ffede0..bbf6a9b7f1 100644
--- a/src/os/exec/lp_windows_test.go
+++ b/src/os/exec/lp_windows_test.go
@@ -312,9 +312,6 @@ func TestLookPath(t *testing.T) {
// Run all tests.
for i, test := range lookPathTests {
t.Run(fmt.Sprint(i), func(t *testing.T) {
- if i == 16 {
- t.Skip("golang.org/issue/44379")
- }
dir := filepath.Join(tmp, "d"+strconv.Itoa(i))
err := os.Mkdir(dir, 0700)
if err != nil {
From 39634e7daee29a0c7d29ca74e32668d04c842758 Mon Sep 17 00:00:00 2001
From: Carlos Amedee
Date: Thu, 12 Aug 2021 12:10:47 -0400
Subject: [PATCH 27/29] CONTRIBUTORS: update for the Go 1.17 release
This update was created using the updatecontrib command:
go get golang.org/x/build/cmd/updatecontrib
cd gotip
GO111MODULE=off updatecontrib
With manual changes based on publicly available information
to canonicalize letter case and formatting for a few names.
For #12042.
Change-Id: I96718c0fe438cd97b62499a027252748a1fa0779
Reviewed-on: https://go-review.googlesource.com/c/go/+/341709
Trust: Carlos Amedee
Run-TryBot: Carlos Amedee
Reviewed-by: Dmitri Shuralyov
TryBot-Result: Go Bot
---
CONTRIBUTORS | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 135 insertions(+), 1 deletion(-)
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index ee50a4c049..1984d44c53 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -33,6 +33,7 @@ Aaron Jacobs
Aaron Jensen
Aaron Kemp
Aaron Patterson
+Aaron Sheah
Aaron Stein
Aaron Torres
Aaron Zinman
@@ -47,6 +48,7 @@ Adam Harvey
Adam Kisala
Adam Langley
Adam Medzinski
+Adam Mitha
Adam Shannon
Adam Shelton
Adam Sindelar
@@ -54,6 +56,8 @@ Adam Thomason
Adam Williams
Adam Woodbeck
Adarsh Ravichandran
+Adel Rodríguez
+Adin Scannell
Aditya Harindar
Aditya Mukerjee
Adrian Hesketh
@@ -68,6 +72,7 @@ Afanasev Stanislav
Agis Anastasopoulos
Agniva De Sarker
Ahmed W. Mones
+Ahmet Aktürk
Ahmet Alp Balkan
Ahmet Soormally
Ahmy Yulrizka
@@ -92,11 +97,13 @@ Alberto Bertogli
Alberto Donizetti
Alberto García Hierro
Alec Benzer
+Alejandro García Montoro
Aleksa Sarai
Aleksandar Dezelin
Aleksandr Lukinykh
Aleksandr Razumov
Alekseev Artem
+Aleksei Tirman
Alessandro Arzilli
Alessandro Baffa
Alex A Skinner
@@ -165,6 +172,7 @@ Ali Rizvi-Santiago
Aliaksandr Valialkin
Alice Merrick
Alif Rachmawadi
+Allan Guwatudde
Allan Simon
Allen Li
Alok Menghrajani
@@ -172,6 +180,7 @@ Alwin Doss
Aman Gupta
Amarjeet Anand
Amir Mohammad Saied
+Amit Kumar
Amr Mohammed
Amrut Joshi
An Long
@@ -185,6 +194,7 @@ André Carvalho
André Martins
Andre Nathan
Andrea Nodari
+Andrea Simonini
Andrea Spadaccini
Andreas Auernhammer
Andreas Jellinghaus
@@ -244,6 +254,7 @@ Andy Pan
Andy Walker
Andy Wang
Andy Williams
+Andy Zhao
Andzej Maciusovic
Anfernee Yongkun Gui
Angelo Bulfone
@@ -269,6 +280,7 @@ Anton Kuklin
Antonin Amand
Antonio Antelo
Antonio Bibiano
+Antonio Garcia
Antonio Huete Jimenez
Antonio Murdaca
Antonio Troina
@@ -292,8 +304,10 @@ Artem Khvastunov
Artem Kolin
Arthur Fabre
Arthur Khashaev
+Artur M. Wolff
Artyom Pervukhin
Arvindh Rajesh Tamilmani
+Ashish Bhate
Ashish Gandhi
Asim Shankar
Assel Meher
@@ -325,6 +339,7 @@ Baokun Lee
Barnaby Keene
Bartosz Grzybowski
Bartosz Oler
+Bassam Ojeil
Bastian Ike
Ben Burkert
Ben Cartwright-Cox
@@ -332,6 +347,7 @@ Ben Eitzen
Ben Fried
Ben Haines
Ben Hoyt
+Ben Hutchings
Ben Kraft
Ben Laurie
Ben Lubar
@@ -430,6 +446,7 @@ Carl Henrik Lunde
Carl Jackson
Carl Johnson
Carl Mastrangelo
+Carl Menezes
Carl Shapiro
Carlisia Campos
Carlo Alberto Ferraris
@@ -443,6 +460,7 @@ Carlos Iriarte
Carlos Souza
Carolyn Van Slyck
Carrie Bynon
+Carson Hoffman
Cary Hull
Case Nelson
Casey Callendrello
@@ -462,6 +480,7 @@ Charles Kenney
Charles L. Dorian
Charles Lee
Charles Weill
+Charlie Moog
Charlotte Brandhorst-Satzkorn
Chauncy Cullitan
Chen Zhidong
@@ -516,6 +535,7 @@ Christopher Nelson
Christopher Nielsen
Christopher Redden
Christopher Swenson
+Christopher Thomas <53317512+chrisssthomas@users.noreply.github.com>
Christopher Wedgwood
Christos Zoulas
Christy Perez
@@ -541,6 +561,8 @@ Cosmos Nicolaou
Costin Chirvasuta
Craig Citro
Cristian Staretu
+Cristo García
+cui fliter
Cuihtlauac ALVARADO
Cuong Manh Le
Curtis La Graff
@@ -560,6 +582,7 @@ Dan Callahan
Dan Harrington
Dan Jacques
Dan Johnson
+Dan McArdle
Dan Peterson
Dan Pupius
Dan Scales
@@ -611,6 +634,7 @@ Dave Russell
David Anderson
David Barnett
David Benjamin
+David Black
David Bond
David Brophy
David Bürgin <676c7473@gmail.com>
@@ -654,6 +678,7 @@ Davor Kapsa
Dean Eigenmann <7621705+decanus@users.noreply.github.com>
Dean Prichard
Deepak Jois
+Deepak S
Denis Bernard
Denis Brandolini
Denis Isaev
@@ -676,8 +701,10 @@ Dhiru Kholia
Dhruvdutt Jadhav
Di Xiao
Didier Spezia
+Diego Medina
Diego Siqueira
Dieter Plaetinck
+Dilyn Corner
Dimitri Sokolyuk
Dimitri Tcaciuc
Dina Garmash
@@ -714,6 +741,7 @@ Doug Fawley
Douglas Danger Manley
Drew Flower
Drew Hintz
+Drew Richardson
Duco van Amstel
Duncan Holm
Dustin Carlino
@@ -735,6 +763,7 @@ Egon Elbre
Ehren Kret
Eitan Adler
Eivind Uggedal
+El Mostafa Idrassi
Elbert Fliek
Eldar Rakhimberdin
Elena Grahovac
@@ -742,6 +771,7 @@ Eli Bendersky
Elias Naur
Elliot Morrison-Reed
Ellison Leão
+Elvina Yakubova
Emerson Lin
Emil Bektimirov
Emil Hessman
@@ -767,6 +797,7 @@ Eric Rescorla
Eric Roshan-Eisner
Eric Rutherford
Eric Rykwalder
+Eric Wang
Erick Tryzelaar
Erik Aigner
Erik Dubbelboer
@@ -778,6 +809,7 @@ Ernest Chiang
Erwin Oegema
Esko Luontola
Ethan Burns
+Ethan Hur
Ethan Miller
Euan Kemp
Eugene Formanenko
@@ -818,6 +850,7 @@ Felix Cornelius <9767036+fcornelius@users.noreply.github.com>
Felix Geisendörfer
Felix Kollmann
Ferenc Szabo