From 703fb665d68ac96ae193891ffae2774c2a3deb4b Mon Sep 17 00:00:00 2001 From: Jean de Klerk Date: Thu, 16 May 2019 18:15:39 -0600 Subject: [PATCH 01/50] errors: update As example to include else case The current example illustrates using As when the error is able to be interpreted as an os.PathError, but elides the "else" case. This CL adds the small extra else case to make it clear that it's not safe to assume As will return true. This CL also squash the err instantiation and the err nil check into one line for brevity. Change-Id: I3d3ab483ffb38fb2788d0498b3f03229a87dd7c3 Reviewed-on: https://go-review.googlesource.com/c/go/+/177717 Reviewed-by: Jonathan Amsterdam Reviewed-by: Damien Neil Run-TryBot: Emmanuel Odeke TryBot-Result: Gobot Gobot --- src/errors/example_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/errors/example_test.go b/src/errors/example_test.go index 7724c16cdf..d7dd782bef 100644 --- a/src/errors/example_test.go +++ b/src/errors/example_test.go @@ -36,11 +36,12 @@ func Example() { } func ExampleAs() { - _, err := os.Open("non-existing") - if err != nil { + if _, err := os.Open("non-existing"); err != nil { var pathError *os.PathError if errors.As(err, &pathError) { fmt.Println("Failed at path:", pathError.Path) + } else { + fmt.Println(err) } } From 06642d8e77ae23325de1db177366c902ec75ab1e Mon Sep 17 00:00:00 2001 From: Jay Conrod Date: Wed, 15 May 2019 12:47:05 -0400 Subject: [PATCH 02/50] cmd/go: don't attempt to downgrade to incompatible versions When we downgrade a module (using 'go get m@none' or similar), we exclude versions of other modules that depend on it. We'll try previous versions (in the "versions" list returned by the proxy or in codeRepo.Versions for vcs) until we find a version that doesn't require an excluded module version. If older versions of a module are broken for some reason, mvs.Downgrade currently panics. With this change, we ignore versions with errors during downgrade. A frequent cause of this is incompatible v2+ versions. These are common if a repository tagged v2.0.0 before migrating to modules, then tagged v2.0.1 with a go.mod file later. v2.0.0 is incorrectly considered part of the v2 module. Fixes #31942 Change-Id: Icaa75c5c93f73f18a400c22f18a8cc603aa4011a Reviewed-on: https://go-review.googlesource.com/c/go/+/177337 Run-TryBot: Jay Conrod TryBot-Result: Gobot Gobot Reviewed-by: Bryan C. Mills --- src/cmd/go/internal/mvs/mvs.go | 50 ++++++++++++------- .../mod/example.com_downgrade_v2.0.0.txt | 9 ++++ .../mod/example.com_downgrade_v2_v2.0.1.txt | 13 +++++ .../mod/example.com_latemigrate_v2_v2.0.0.txt | 14 ++++++ .../mod/example.com_latemigrate_v2_v2.0.1.txt | 20 ++++++++ .../go/testdata/script/mod_get_downgrade.txt | 17 ++++++- 6 files changed, 102 insertions(+), 21 deletions(-) create mode 100644 src/cmd/go/testdata/mod/example.com_downgrade_v2.0.0.txt create mode 100644 src/cmd/go/testdata/mod/example.com_downgrade_v2_v2.0.1.txt create mode 100644 src/cmd/go/testdata/mod/example.com_latemigrate_v2_v2.0.0.txt create mode 100644 src/cmd/go/testdata/mod/example.com_latemigrate_v2_v2.0.1.txt diff --git a/src/cmd/go/internal/mvs/mvs.go b/src/cmd/go/internal/mvs/mvs.go index 90f8f269b5..04273e733c 100644 --- a/src/cmd/go/internal/mvs/mvs.go +++ b/src/cmd/go/internal/mvs/mvs.go @@ -13,7 +13,6 @@ import ( "sync" "sync/atomic" - "cmd/go/internal/base" "cmd/go/internal/module" "cmd/go/internal/par" ) @@ -118,7 +117,7 @@ func BuildList(target module.Version, reqs Reqs) ([]module.Version, error) { return buildList(target, reqs, nil) } -func buildList(target module.Version, reqs Reqs, upgrade func(module.Version) module.Version) ([]module.Version, error) { +func buildList(target module.Version, reqs Reqs, upgrade func(module.Version) (module.Version, error)) ([]module.Version, error) { // Explore work graph in parallel in case reqs.Required // does high-latency network operations. type modGraphNode struct { @@ -133,6 +132,10 @@ func buildList(target module.Version, reqs Reqs, upgrade func(module.Version) mo min = map[string]string{} // maps module path to minimum required version haveErr int32 ) + setErr := func(n *modGraphNode, err error) { + n.err = err + atomic.StoreInt32(&haveErr, 1) + } var work par.Work work.Add(target) @@ -149,8 +152,7 @@ func buildList(target module.Version, reqs Reqs, upgrade func(module.Version) mo required, err := reqs.Required(m) if err != nil { - node.err = err - atomic.StoreInt32(&haveErr, 1) + setErr(node, err) return } node.required = required @@ -159,9 +161,9 @@ func buildList(target module.Version, reqs Reqs, upgrade func(module.Version) mo } if upgrade != nil { - u := upgrade(m) - if u.Path == "" { - base.Errorf("Upgrade(%v) returned zero module", m) + u, err := upgrade(m) + if err != nil { + setErr(node, err) return } if u != m { @@ -332,17 +334,12 @@ func Req(target module.Version, list []module.Version, base []string, reqs Reqs) // UpgradeAll returns a build list for the target module // in which every module is upgraded to its latest version. func UpgradeAll(target module.Version, reqs Reqs) ([]module.Version, error) { - return buildList(target, reqs, func(m module.Version) module.Version { + return buildList(target, reqs, func(m module.Version) (module.Version, error) { if m.Path == target.Path { - return target + return target, nil } - latest, err := reqs.Upgrade(m) - if err != nil { - panic(err) // TODO - } - m.Version = latest.Version - return m + return reqs.Upgrade(m) }) } @@ -351,7 +348,7 @@ func UpgradeAll(target module.Version, reqs Reqs) ([]module.Version, error) { func Upgrade(target module.Version, reqs Reqs, upgrade ...module.Version) ([]module.Version, error) { list, err := reqs.Required(target) if err != nil { - panic(err) // TODO + return nil, err } // TODO: Maybe if an error is given, // rerun with BuildList(upgrade[0], reqs) etc @@ -370,7 +367,7 @@ func Upgrade(target module.Version, reqs Reqs, upgrade ...module.Version) ([]mod func Downgrade(target module.Version, reqs Reqs, downgrade ...module.Version) ([]module.Version, error) { list, err := reqs.Required(target) if err != nil { - panic(err) // TODO + return nil, err } max := make(map[string]string) for _, r := range list { @@ -409,7 +406,17 @@ func Downgrade(target module.Version, reqs Reqs, downgrade ...module.Version) ([ } list, err := reqs.Required(m) if err != nil { - panic(err) // TODO + // If we can't load the requirements, we couldn't load the go.mod file. + // There are a number of reasons this can happen, but this usually + // means an older version of the module had a missing or invalid + // go.mod file. For example, if example.com/mod released v2.0.0 before + // migrating to modules (v2.0.0+incompatible), then added a valid go.mod + // in v2.0.1, downgrading from v2.0.1 would cause this error. + // + // TODO(golang.org/issue/31730, golang.org/issue/30134): if the error + // is transient (we couldn't download go.mod), return the error from + // Downgrade. Currently, we can't tell what kind of error it is. + exclude(m) } for _, r := range list { add(r) @@ -429,7 +436,12 @@ List: for excluded[r] { p, err := reqs.Previous(r) if err != nil { - return nil, err // TODO + // This is likely a transient error reaching the repository, + // rather than a permanent error with the retrieved version. + // + // TODO(golang.org/issue/31730, golang.org/issue/30134): + // decode what to do based on the actual error. + return nil, err } // If the target version is a pseudo-version, it may not be // included when iterating over prior versions using reqs.Previous. diff --git a/src/cmd/go/testdata/mod/example.com_downgrade_v2.0.0.txt b/src/cmd/go/testdata/mod/example.com_downgrade_v2.0.0.txt new file mode 100644 index 0000000000..88d50e5bba --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_downgrade_v2.0.0.txt @@ -0,0 +1,9 @@ +example.com/downgrade v2.0.0 +written by hand + +-- .mod -- +module example.com/downgrade + +require rsc.io/quote v1.5.2 +-- .info -- +{"Version":"v2.0.0"} diff --git a/src/cmd/go/testdata/mod/example.com_downgrade_v2_v2.0.1.txt b/src/cmd/go/testdata/mod/example.com_downgrade_v2_v2.0.1.txt new file mode 100644 index 0000000000..a4d665ff1b --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_downgrade_v2_v2.0.1.txt @@ -0,0 +1,13 @@ +example.com/downgrade/v2 v2.0.1 +written by hand + +-- .mod -- +module example.com/downgrade/v2 + +require rsc.io/quote v1.5.2 +-- .info -- +{"Version":"v2.0.1"} +-- go.mod -- +module example.com/downgrade/v2 + +require rsc.io/quote v1.5.2 diff --git a/src/cmd/go/testdata/mod/example.com_latemigrate_v2_v2.0.0.txt b/src/cmd/go/testdata/mod/example.com_latemigrate_v2_v2.0.0.txt new file mode 100644 index 0000000000..25bd3d9d8f --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_latemigrate_v2_v2.0.0.txt @@ -0,0 +1,14 @@ +example.com/latemigrate/v2 v2.0.0 +written by hand + +This repository migrated to modules in v2.0.1 after v2.0.0 was already tagged. +All versions require rsc.io/quote so we can test downgrades. + +v2.0.0 is technically part of example.com/latemigrate as v2.0.0+incompatible. +Proxies may serve it as part of the version list for example.com/latemigrate/v2. +'go get' must be able to ignore these versions. + +-- .mod -- +module example.com/latemigrate +-- .info -- +{"Version":"v2.0.0"} diff --git a/src/cmd/go/testdata/mod/example.com_latemigrate_v2_v2.0.1.txt b/src/cmd/go/testdata/mod/example.com_latemigrate_v2_v2.0.1.txt new file mode 100644 index 0000000000..be427a3185 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_latemigrate_v2_v2.0.1.txt @@ -0,0 +1,20 @@ +example.com/latemigrate/v2 v2.0.1 +written by hand + +This repository migrated to modules in v2.0.1 after v2.0.0 was already tagged. +All versions require rsc.io/quote so we can test downgrades. + +v2.0.1 belongs to example.com/latemigrate/v2. + +-- .mod -- +module example.com/latemigrate/v2 + +require rsc.io/quote v1.3.0 +-- .info -- +{"Version":"v2.0.1"} +-- go.mod -- +module example.com/latemigrate/v2 + +require rsc.io/quote v1.3.0 +-- late.go -- +package late diff --git a/src/cmd/go/testdata/script/mod_get_downgrade.txt b/src/cmd/go/testdata/script/mod_get_downgrade.txt index 00cd93e598..ee9ac96475 100644 --- a/src/cmd/go/testdata/script/mod_get_downgrade.txt +++ b/src/cmd/go/testdata/script/mod_get_downgrade.txt @@ -2,6 +2,7 @@ env GO111MODULE=on [short] skip # downgrade sampler should downgrade quote +cp go.mod.orig go.mod go get rsc.io/sampler@v1.0.0 go list -m all stdout 'rsc.io/quote v1.4.0' @@ -31,9 +32,21 @@ stdout 'rsc.io/quote v1.4.0' stdout 'rsc.io/sampler v1.0.0' ! stdout golang.org/x/text --- go.mod -- +# downgrading away quote should also downgrade away latemigrate/v2, +# since there are no older versions. v2.0.0 is incompatible. +cp go.mod.orig go.mod +go list -m -versions example.com/latemigrate/v2 +stdout v2.0.0 # proxy may serve incompatible versions +go get rsc.io/quote@none +go list -m all +! stdout 'example.com/latemigrate/v2' + +-- go.mod.orig -- module x -require rsc.io/quote v1.5.1 +require ( + rsc.io/quote v1.5.1 + example.com/latemigrate/v2 v2.0.1 +) -- go.mod.empty -- module x -- x.go -- From 3f7c5608299b56283a2c885b6146823d5b83b2f7 Mon Sep 17 00:00:00 2001 From: Dmitri Shuralyov Date: Sun, 12 May 2019 19:21:33 -0400 Subject: [PATCH 03/50] net/http/httputil: remove os.Stderr claim in ReverseProxy.ErrorLog docs The motivation for doing so is to avoid making inaccurate claims. Logging may not go to os.Stderr if anyone overrides the log package's default output via https://godoc.org/log#SetOutput. Saying that the standard logger is used should be sufficient to explain the behavior, and users can infer that os.Stderr is used by default, unless it's changed. This change is the same as what was applied to http.Server.ErrorLog documentation in CL 53950. Change-Id: I32873fc548ceee573f8616b4d49b8a8b98881803 Reviewed-on: https://go-review.googlesource.com/c/go/+/176817 Reviewed-by: Brad Fitzpatrick --- src/net/http/httputil/reverseproxy.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/net/http/httputil/reverseproxy.go b/src/net/http/httputil/reverseproxy.go index 7bb469e5c3..1d7b0efa11 100644 --- a/src/net/http/httputil/reverseproxy.go +++ b/src/net/http/httputil/reverseproxy.go @@ -51,8 +51,7 @@ type ReverseProxy struct { // ErrorLog specifies an optional logger for errors // that occur when attempting to proxy the request. - // If nil, logging goes to os.Stderr via the log package's - // standard logger. + // If nil, logging is done via the log package's standard logger. ErrorLog *log.Logger // BufferPool optionally specifies a buffer pool to From e22e2b371d5caa4144de1eedc8484def68f9d4d9 Mon Sep 17 00:00:00 2001 From: Filippo Valsorda Date: Fri, 17 May 2019 12:00:05 -0400 Subject: [PATCH 04/50] crypto/tls: fix TestVerifyHostnameResumed In TLS 1.3 session tickets are delivered after the handshake, and it looks like now the Google servers wait until the first flight of data to send them (or our timeout is too low). Cause some data to be sent so we can avoid the guessing game. Fixes #32090 Change-Id: I54af4acb3a89cc70c9e14a5dfe18a44c29a841a7 Reviewed-on: https://go-review.googlesource.com/c/go/+/177877 Reviewed-by: Brad Fitzpatrick --- src/crypto/tls/tls_test.go | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/crypto/tls/tls_test.go b/src/crypto/tls/tls_test.go index 0a3aeeff73..df39509a6d 100644 --- a/src/crypto/tls/tls_test.go +++ b/src/crypto/tls/tls_test.go @@ -372,7 +372,9 @@ func testVerifyHostnameResumed(t *testing.T, version uint16) { ClientSessionCache: NewLRUClientSessionCache(32), } for i := 0; i < 2; i++ { - c, err := Dial("tcp", "mail.google.com:https", config) + c, err := DialWithDialer(&net.Dialer{ + Timeout: 10 * time.Second, + }, "tcp", "mail.google.com:https", config) if err != nil { t.Fatalf("Dial #%d: %v", i, err) } @@ -389,12 +391,13 @@ func testVerifyHostnameResumed(t *testing.T, version uint16) { if err := c.VerifyHostname("mail.google.com"); err != nil { t.Fatalf("verify mail.google.com #%d: %v", i, err) } - // Give the client a chance to read the server session tickets. - c.SetReadDeadline(time.Now().Add(500 * time.Millisecond)) + // Have the server send some data so session tickets are delivered. + c.SetDeadline(time.Now().Add(5 * time.Second)) + if _, err := io.WriteString(c, "HEAD / HTTP/1.0\n\n"); err != nil { + t.Fatal(err) + } if _, err := c.Read(make([]byte, 1)); err != nil { - if err, ok := err.(net.Error); !ok || !err.Timeout() { - t.Fatal(err) - } + t.Fatal(err) } c.Close() } From 5c3f3fbd0f91cf642e2d5c9109a2b3a9c65fe14b Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Thu, 16 May 2019 15:39:34 -0700 Subject: [PATCH 05/50] cmd/compile: optimize postorder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit name old alloc/op new alloc/op delta Template 37.1MB ± 0% 36.8MB ± 0% -0.57% (p=0.008 n=5+5) Unicode 28.1MB ± 0% 28.1MB ± 0% -0.07% (p=0.008 n=5+5) GoTypes 125MB ± 0% 124MB ± 0% -0.61% (p=0.008 n=5+5) Compiler 571MB ± 0% 568MB ± 0% -0.60% (p=0.008 n=5+5) SSA 1.88GB ± 0% 1.86GB ± 0% -0.82% (p=0.008 n=5+5) Flate 22.9MB ± 0% 22.8MB ± 0% -0.59% (p=0.008 n=5+5) GoParser 27.5MB ± 0% 27.3MB ± 0% -0.53% (p=0.008 n=5+5) Reflect 79.8MB ± 0% 79.5MB ± 0% -0.40% (p=0.008 n=5+5) Tar 34.9MB ± 0% 34.7MB ± 0% -0.44% (p=0.008 n=5+5) XML 45.7MB ± 0% 45.4MB ± 0% -0.58% (p=0.008 n=5+5) [Geo mean] 80.3MB 79.9MB -0.52% name old allocs/op new allocs/op delta Template 380k ± 0% 378k ± 0% -0.57% (p=0.008 n=5+5) Unicode 340k ± 0% 340k ± 0% -0.08% (p=0.008 n=5+5) GoTypes 1.36M ± 0% 1.36M ± 0% -0.44% (p=0.008 n=5+5) Compiler 5.52M ± 0% 5.49M ± 0% -0.45% (p=0.008 n=5+5) SSA 17.6M ± 0% 17.5M ± 0% -0.42% (p=0.008 n=5+5) Flate 235k ± 0% 234k ± 0% -0.65% (p=0.008 n=5+5) GoParser 302k ± 0% 300k ± 0% -0.70% (p=0.008 n=5+5) Reflect 982k ± 0% 978k ± 0% -0.40% (p=0.008 n=5+5) Tar 353k ± 0% 351k ± 0% -0.53% (p=0.008 n=5+5) XML 437k ± 0% 435k ± 0% -0.48% (p=0.008 n=5+5) [Geo mean] 844k 840k -0.47% Updates #27739 Change-Id: I5d533013270cbbd7c0bad1b43da96c8499be76f5 Reviewed-on: https://go-review.googlesource.com/c/go/+/177917 Run-TryBot: Josh Bleecher Snyder Reviewed-by: Brad Fitzpatrick --- src/cmd/compile/internal/ssa/dom.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cmd/compile/internal/ssa/dom.go b/src/cmd/compile/internal/ssa/dom.go index ee2748e6df..3d186fc562 100644 --- a/src/cmd/compile/internal/ssa/dom.go +++ b/src/cmd/compile/internal/ssa/dom.go @@ -20,7 +20,7 @@ const ( // postorder computes a postorder traversal ordering for the // basic blocks in f. Unreachable blocks will not appear. func postorder(f *Func) []*Block { - return postorderWithNumbering(f, []int32{}) + return postorderWithNumbering(f, nil) } type blockAndIndex struct { @@ -34,7 +34,7 @@ func postorderWithNumbering(f *Func, ponums []int32) []*Block { mark := make([]markKind, f.NumBlocks()) // result ordering - var order []*Block + order := make([]*Block, 0, len(f.Blocks)) // stack of blocks and next child to visit // A constant bound allows this to be stack-allocated. 32 is From 1ab063ce532f72851cef735238ba656cc7680b66 Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Fri, 17 May 2019 13:31:12 -0700 Subject: [PATCH 06/50] testing: callerName only needs one PC in the traceback callerName requested 2 PCs from Callers, and that causes both to be looked up in the file/line mapping. We really only need to do the work for one PC. (And in fact the caller doesn't need file/line at all, but the Callers API can't express that.) We used to request 2 PCs because in 1.11 and earlier we stored an inline skip count in the second entry. That's not necessary any more (as of 1.12). Fixes #32093 Change-Id: I7b272626ef6496e848ee8af388cdaafd2556857b Reviewed-on: https://go-review.googlesource.com/c/go/+/177858 Run-TryBot: Keith Randall TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor Reviewed-by: Caleb Spare --- src/testing/testing.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/testing/testing.go b/src/testing/testing.go index 753de9f27c..339df13f43 100644 --- a/src/testing/testing.go +++ b/src/testing/testing.go @@ -771,7 +771,7 @@ func (c *common) Helper() { // for the caller after skip frames (where 0 means the current function). func callerName(skip int) string { // Make room for the skip PC. - var pc [2]uintptr + var pc [1]uintptr n := runtime.Callers(skip+2, pc[:]) // skip + runtime.Callers + callerName if n == 0 { panic("testing: zero callers found") From 5ca44dc403d4a609eeafb0f699a63f19ef045cd6 Mon Sep 17 00:00:00 2001 From: smasher164 Date: Thu, 4 Apr 2019 15:57:24 -0400 Subject: [PATCH 07/50] math/bits: make Add and Sub fallbacks constant time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the extended precision add-with-carry and sub-with-carry operations take a constant amount of time to execute, regardless of input. name old time/op new time/op delta Add-4 1.16ns ±11% 1.51ns ± 5% +30.52% (p=0.008 n=5+5) Add32-4 1.08ns ± 0% 1.03ns ± 1% -4.86% (p=0.029 n=4+4) Add64-4 1.09ns ± 1% 1.95ns ± 3% +79.23% (p=0.008 n=5+5) Add64multiple-4 4.03ns ± 1% 4.55ns ±11% +13.07% (p=0.008 n=5+5) Sub-4 1.08ns ± 1% 1.50ns ± 0% +38.17% (p=0.016 n=5+4) Sub32-4 1.09ns ± 2% 1.53ns ±10% +40.26% (p=0.008 n=5+5) Sub64-4 1.10ns ± 1% 1.47ns ± 1% +33.39% (p=0.008 n=5+5) Sub64multiple-4 4.30ns ± 2% 4.08ns ± 4% -5.07% (p=0.032 n=5+5) Fixes #31267 Change-Id: I1824b1b3ab8f09902ce8b5fef84ce2fdb8847ed9 Reviewed-on: https://go-review.googlesource.com/c/go/+/170758 Reviewed-by: Filippo Valsorda Reviewed-by: Keith Randall Run-TryBot: Filippo Valsorda TryBot-Result: Gobot Gobot --- src/math/bits/bits.go | 49 +++++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 30 deletions(-) diff --git a/src/math/bits/bits.go b/src/math/bits/bits.go index 24d910c27e..1a85485a5a 100644 --- a/src/math/bits/bits.go +++ b/src/math/bits/bits.go @@ -332,23 +332,21 @@ func Len64(x uint64) (n int) { // The carry input must be 0 or 1; otherwise the behavior is undefined. // The carryOut output is guaranteed to be 0 or 1. func Add(x, y, carry uint) (sum, carryOut uint) { - yc := y + carry - sum = x + yc - if sum < x || yc < y { - carryOut = 1 + if UintSize == 32 { + s32, c32 := Add32(uint32(x), uint32(y), uint32(carry)) + return uint(s32), uint(c32) } - return + s64, c64 := Add64(uint64(x), uint64(y), uint64(carry)) + return uint(s64), uint(c64) } // Add32 returns the sum with carry of x, y and carry: sum = x + y + carry. // The carry input must be 0 or 1; otherwise the behavior is undefined. // The carryOut output is guaranteed to be 0 or 1. func Add32(x, y, carry uint32) (sum, carryOut uint32) { - yc := y + carry - sum = x + yc - if sum < x || yc < y { - carryOut = 1 - } + sum64 := uint64(x) + uint64(y) + uint64(carry) + sum = uint32(sum64) + carryOut = uint32(sum64 >> 32) return } @@ -356,11 +354,8 @@ func Add32(x, y, carry uint32) (sum, carryOut uint32) { // The carry input must be 0 or 1; otherwise the behavior is undefined. // The carryOut output is guaranteed to be 0 or 1. func Add64(x, y, carry uint64) (sum, carryOut uint64) { - yc := y + carry - sum = x + yc - if sum < x || yc < y { - carryOut = 1 - } + sum = x + y + carry + carryOut = ((x & y) | ((x | y) &^ sum)) >> 63 return } @@ -370,23 +365,20 @@ func Add64(x, y, carry uint64) (sum, carryOut uint64) { // The borrow input must be 0 or 1; otherwise the behavior is undefined. // The borrowOut output is guaranteed to be 0 or 1. func Sub(x, y, borrow uint) (diff, borrowOut uint) { - yb := y + borrow - diff = x - yb - if diff > x || yb < y { - borrowOut = 1 + if UintSize == 32 { + d32, b32 := Sub32(uint32(x), uint32(y), uint32(borrow)) + return uint(d32), uint(b32) } - return + d64, b64 := Sub64(uint64(x), uint64(y), uint64(borrow)) + return uint(d64), uint(b64) } // Sub32 returns the difference of x, y and borrow, diff = x - y - borrow. // The borrow input must be 0 or 1; otherwise the behavior is undefined. // The borrowOut output is guaranteed to be 0 or 1. func Sub32(x, y, borrow uint32) (diff, borrowOut uint32) { - yb := y + borrow - diff = x - yb - if diff > x || yb < y { - borrowOut = 1 - } + diff = x - y - borrow + borrowOut = ((^x & y) | (^(x ^ y) & diff)) >> 31 return } @@ -394,11 +386,8 @@ func Sub32(x, y, borrow uint32) (diff, borrowOut uint32) { // The borrow input must be 0 or 1; otherwise the behavior is undefined. // The borrowOut output is guaranteed to be 0 or 1. func Sub64(x, y, borrow uint64) (diff, borrowOut uint64) { - yb := y + borrow - diff = x - yb - if diff > x || yb < y { - borrowOut = 1 - } + diff = x - y - borrow + borrowOut = ((^x & y) | (^(x ^ y) & diff)) >> 63 return } From 5eeb372418466920cad237a89846556453bd91ca Mon Sep 17 00:00:00 2001 From: taoyuanyuan Date: Sun, 19 May 2019 23:23:04 +0000 Subject: [PATCH 08/50] internal/poll: avoid memory leak in Writev The chunks that were referenced by fd.iovecs would not be GC. Change-Id: I7bfcb91a3fef57a4a1861168e9cd3ab55ce1334e GitHub-Last-Rev: e0b7f68447441fd89ed1a6e8aa37e2084fd863b2 GitHub-Pull-Request: golang/go#32138 Reviewed-on: https://go-review.googlesource.com/c/go/+/178037 Run-TryBot: Ian Lance Taylor TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- src/internal/poll/writev.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/internal/poll/writev.go b/src/internal/poll/writev.go index a48a38be08..6050d1f642 100644 --- a/src/internal/poll/writev.go +++ b/src/internal/poll/writev.go @@ -64,6 +64,9 @@ func (fd *FD) Writev(v *[][]byte) (int64, error) { TestHookDidWritev(int(wrote)) n += int64(wrote) consume(v, int64(wrote)) + for i := range iovecs { + iovecs[i] = syscall.Iovec{} + } if err != nil { if err.(syscall.Errno) == syscall.EAGAIN { if err = fd.pd.waitWrite(fd.isFile); err == nil { From be9f10b2b8a25095014b864512d1b6a70df2b61c Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Sun, 19 May 2019 17:02:01 +0000 Subject: [PATCH 09/50] cmd/go/internal/work: fix a couple typos Change-Id: I357669d8c9bc004031b17f057803c9b152edefee Reviewed-on: https://go-review.googlesource.com/c/go/+/178057 Reviewed-by: Ian Lance Taylor --- src/cmd/go/internal/work/buildid.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cmd/go/internal/work/buildid.go b/src/cmd/go/internal/work/buildid.go index 1a98980915..1f6d1e8e77 100644 --- a/src/cmd/go/internal/work/buildid.go +++ b/src/cmd/go/internal/work/buildid.go @@ -159,7 +159,7 @@ func hashToString(h [cache.HashSize]byte) string { // which influences the action ID half of the build ID, is based on the content ID, // then the Linux compiler binary and Mac compiler binary will have different tool IDs // and therefore produce executables with different action IDs. -// To avoids this problem, for releases we use the release version string instead +// To avoid this problem, for releases we use the release version string instead // of the compiler binary's content hash. This assumes that all compilers built // on all different systems are semantically equivalent, which is of course only true // modulo bugs. (Producing the exact same executables also requires that the different @@ -215,7 +215,7 @@ func (b *Builder) toolID(name string) string { } // gccToolID returns the unique ID to use for a tool that is invoked -// by the GCC driver. This is in particular gccgo, but this can also +// by the GCC driver. This is used particularly for gccgo, but this can also // be used for gcc, g++, gfortran, etc.; those tools all use the GCC // driver under different names. The approach used here should also // work for sufficiently new versions of clang. Unlike toolID, the From c6f9321b5a46e4af3233417d068c0efb4113d8e7 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Sun, 19 May 2019 17:06:24 +0000 Subject: [PATCH 10/50] net/http/httptest: update docs, remove old inaccurate sentence The "After it is called, changing rw.Header will not affect rw.HeaderMap" claim predates the Result method which changed how the Recorder should be used. Fixes #32144 Fixes #32136 Change-Id: I95bdfa5ac489ce7b0202824bb5663f4da188e8a7 Reviewed-on: https://go-review.googlesource.com/c/go/+/178058 Reviewed-by: Dmitri Shuralyov --- src/net/http/httptest/recorder.go | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/net/http/httptest/recorder.go b/src/net/http/httptest/recorder.go index f2350f0a8d..d0bc0fade9 100644 --- a/src/net/http/httptest/recorder.go +++ b/src/net/http/httptest/recorder.go @@ -59,7 +59,10 @@ func NewRecorder() *ResponseRecorder { // an explicit DefaultRemoteAddr isn't set on ResponseRecorder. const DefaultRemoteAddr = "1.2.3.4" -// Header returns the response headers. +// Header implements http.ResponseWriter. It returns the response +// headers to mutate within a handler. To test the headers that were +// written after a handler completes, use the Result method and see +// the returned Response value's Header. func (rw *ResponseRecorder) Header() http.Header { m := rw.HeaderMap if m == nil { @@ -98,7 +101,8 @@ func (rw *ResponseRecorder) writeHeader(b []byte, str string) { rw.WriteHeader(200) } -// Write always succeeds and writes to rw.Body, if not nil. +// Write implements http.ResponseWriter. The data in buf is written to +// rw.Body, if not nil. func (rw *ResponseRecorder) Write(buf []byte) (int, error) { rw.writeHeader(buf, "") if rw.Body != nil { @@ -107,7 +111,8 @@ func (rw *ResponseRecorder) Write(buf []byte) (int, error) { return len(buf), nil } -// WriteString always succeeds and writes to rw.Body, if not nil. +// WriteString implements io.StringWriter. The data in str is written +// to rw.Body, if not nil. func (rw *ResponseRecorder) WriteString(str string) (int, error) { rw.writeHeader(nil, str) if rw.Body != nil { @@ -116,8 +121,7 @@ func (rw *ResponseRecorder) WriteString(str string) (int, error) { return len(str), nil } -// WriteHeader sets rw.Code. After it is called, changing rw.Header -// will not affect rw.HeaderMap. +// WriteHeader implements http.ResponseWriter. func (rw *ResponseRecorder) WriteHeader(code int) { if rw.wroteHeader { return @@ -130,7 +134,8 @@ func (rw *ResponseRecorder) WriteHeader(code int) { rw.snapHeader = rw.HeaderMap.Clone() } -// Flush sets rw.Flushed to true. +// Flush implements http.Flusher. To test whether Flush was +// called, see rw.Flushed. func (rw *ResponseRecorder) Flush() { if !rw.wroteHeader { rw.WriteHeader(200) From 4ee4607c97a3968b7252fbcac4631a6b6b7b4537 Mon Sep 17 00:00:00 2001 From: LE Manh Cuong Date: Mon, 20 May 2019 15:07:01 +0700 Subject: [PATCH 11/50] cmd/compile: use internal/race CL 14870 added internal/race to factor out duplicated race thunks, we should use it. No signification changes in compile time and compile binary size. Change-Id: I786af44dd5bb0f4ab6709432eeb603f27a5b6c63 Reviewed-on: https://go-review.googlesource.com/c/go/+/178118 Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- src/cmd/compile/internal/gc/norace.go | 9 --------- src/cmd/compile/internal/gc/pgen.go | 5 +++-- src/cmd/compile/internal/gc/race.go | 9 --------- src/cmd/dist/buildtool.go | 1 + 4 files changed, 4 insertions(+), 20 deletions(-) delete mode 100644 src/cmd/compile/internal/gc/norace.go delete mode 100644 src/cmd/compile/internal/gc/race.go diff --git a/src/cmd/compile/internal/gc/norace.go b/src/cmd/compile/internal/gc/norace.go deleted file mode 100644 index e00f0c4a84..0000000000 --- a/src/cmd/compile/internal/gc/norace.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2017 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. - -// +build !race - -package gc - -const raceEnabled = false diff --git a/src/cmd/compile/internal/gc/pgen.go b/src/cmd/compile/internal/gc/pgen.go index 2ae7452e7d..dd2294e37f 100644 --- a/src/cmd/compile/internal/gc/pgen.go +++ b/src/cmd/compile/internal/gc/pgen.go @@ -13,6 +13,7 @@ import ( "cmd/internal/src" "cmd/internal/sys" "fmt" + "internal/race" "math/rand" "sort" "sync" @@ -325,7 +326,7 @@ func compileSSA(fn *Node, worker int) { } func init() { - if raceEnabled { + if race.Enabled { rand.Seed(time.Now().UnixNano()) } } @@ -336,7 +337,7 @@ func init() { func compileFunctions() { if len(compilequeue) != 0 { sizeCalculationDisabled = true // not safe to calculate sizes concurrently - if raceEnabled { + if race.Enabled { // Randomize compilation order to try to shake out races. tmp := make([]*Node, len(compilequeue)) perm := rand.Perm(len(compilequeue)) diff --git a/src/cmd/compile/internal/gc/race.go b/src/cmd/compile/internal/gc/race.go deleted file mode 100644 index 78e1997cf9..0000000000 --- a/src/cmd/compile/internal/gc/race.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2017 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. - -// +build race - -package gc - -const raceEnabled = true diff --git a/src/cmd/dist/buildtool.go b/src/cmd/dist/buildtool.go index 190b592b6e..b434d4f60f 100644 --- a/src/cmd/dist/buildtool.go +++ b/src/cmd/dist/buildtool.go @@ -90,6 +90,7 @@ var bootstrapDirs = []string{ "debug/macho", "debug/pe", "internal/goversion", + "internal/race", "internal/xcoff", "math/big", "math/bits", From 295c56627afaa9db19ee7fcb0df33c1d6fa3c9fa Mon Sep 17 00:00:00 2001 From: Shulhan Date: Fri, 10 May 2019 22:38:56 +0700 Subject: [PATCH 12/50] internal/envcmd: print GO111MODULE when executing "go env" If we look at the issues in the past releases that are related to go command that involved modules, its usually mention or ask about the value of GO111MODULE, either in separate line or in separate comment. There are quite long time range before GO111MODULE will be removed (unused). The next release is still default to auto [1], and until Go 1.13 unsupported (two releases after that) there is about one and half years after that. Since the change is not that big (one line) [2], maybe temporary adding it to "go env" give more clarity and benefit in issue reporting rather than not. [1] https://github.com/golang/go/issues/31857 Fixes #29656 Change-Id: I609ad6664774018e4f4147ec6158485172968e16 Reviewed-on: https://go-review.googlesource.com/c/go/+/176837 Run-TryBot: Bryan C. Mills TryBot-Result: Gobot Gobot Reviewed-by: Bryan C. Mills --- src/cmd/go/internal/envcmd/env.go | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cmd/go/internal/envcmd/env.go b/src/cmd/go/internal/envcmd/env.go index 00f10977bb..b3d12dd681 100644 --- a/src/cmd/go/internal/envcmd/env.go +++ b/src/cmd/go/internal/envcmd/env.go @@ -66,6 +66,7 @@ func MkEnv() []cfg.EnvVar { envFile, _ := cfg.EnvFile() env := []cfg.EnvVar{ + {Name: "GO111MODULE", Value: cfg.Getenv("GO111MODULE")}, {Name: "GOARCH", Value: cfg.Goarch}, {Name: "GOBIN", Value: cfg.GOBIN}, {Name: "GOCACHE", Value: cache.DefaultDir()}, From 82ee4e7f78bf34da31e1d050529ab82dc03cf13a Mon Sep 17 00:00:00 2001 From: Alex Myasoedov Date: Mon, 20 May 2019 18:15:05 +0300 Subject: [PATCH 13/50] context: document CancelFunc to be safe for simultaneous use by multiple goroutines Fixes #32145 Change-Id: If4c9dd3a2af748974141ad6e571f80efcbaad772 Reviewed-on: https://go-review.googlesource.com/c/go/+/177899 Reviewed-by: Brad Fitzpatrick --- src/context/context.go | 1 + 1 file changed, 1 insertion(+) diff --git a/src/context/context.go b/src/context/context.go index 0f36881b1e..05d01d0294 100644 --- a/src/context/context.go +++ b/src/context/context.go @@ -220,6 +220,7 @@ func TODO() Context { // A CancelFunc tells an operation to abandon its work. // A CancelFunc does not wait for the work to stop. +// A CancelFunc may be called by multiple goroutines simultaneously. // After the first call, subsequent calls to a CancelFunc do nothing. type CancelFunc func() From 5a90306344dab7a29979f066131bb62a75b69cbb Mon Sep 17 00:00:00 2001 From: Michael Anthony Knyszek Date: Tue, 14 May 2019 19:59:57 +0000 Subject: [PATCH 14/50] runtime: overhaul TestPhysicalMemoryUtilization Currently, this test allocates many objects and relies on heap-growth scavenging to happen unconditionally on heap-growth. However with the new pacing system for the scavenging, this is no longer true and the test is flaky. So, this change overhauls TestPhysicalMemoryUtilization to check the same aspect of the runtime, but in a much more robust way. Firstly, it sets up a much more constrained scenario: only 5 objects are allocated total with a maximum worst-case (i.e. the test fails) memory footprint of about 16 MiB. The test is now aware that scavenging will only happen if the heap growth causes us to push way past our scavenge goal, which is based on the heap goal. So, it makes the holes in the test much bigger and the actual retained allocations much smaller to keep the heap goal at the heap's minimum size. It does this twice to create exactly two unscavenged holes. Because the ratio between the size of the "saved" objects and the "condemned" object is so small, two holes are sufficient to create a consistent test. Then, the test allocates one enormous object (the size of the 4 other objects allocated, combined) with the intent that heap-growth scavenging should kick in and scavenge the holes. The heap goal will rise after this object is allocated, so it's very important we do all the scavenging in a single allocation that exceeds the heap goal because otherwise the rising heap goal could foil our test. Finally, we check memory use relative to HeapAlloc as before. Since the runtime should scavenge the entirety of the remaining holes, theoretically there should be no more free and unscavenged memory. However due to other allocations that may happen during the test we may still see unscavenged memory, so we need to have some threshold. We keep the current 10% threshold which, while arbitrary, is very conservative and should easily account for any other allocations the test makes. Before, we also had to ensure the allocations we were making looked large relative to the size of a heap arena since newly-mapped memory was considered unscavenged, and so that could significantly skew the test. However, thanks to the fix for #32012 we were able to reduce memory use to 16 MiB in the worst case. Fixes #32010. Change-Id: Ia38130481e292f581da7fa3289c98c99dc5394ed Reviewed-on: https://go-review.googlesource.com/c/go/+/177237 Reviewed-by: Brad Fitzpatrick --- src/runtime/testdata/testprog/gc.go | 99 +++++++++++++++-------------- 1 file changed, 53 insertions(+), 46 deletions(-) diff --git a/src/runtime/testdata/testprog/gc.go b/src/runtime/testdata/testprog/gc.go index ea6604f132..cca9c4556b 100644 --- a/src/runtime/testdata/testprog/gc.go +++ b/src/runtime/testdata/testprog/gc.go @@ -127,59 +127,58 @@ func GCFairness2() { fmt.Println("OK") } -var maybeSaved []byte - func GCPhys() { - // In this test, we construct a very specific scenario. We first - // allocate N objects and drop half of their pointers on the floor, - // effectively creating N/2 'holes' in our allocated arenas. We then - // try to allocate objects twice as big. At the end, we measure the - // physical memory overhead of large objects. + // This test ensures that heap-growth scavenging is working as intended. // - // The purpose of this test is to ensure that the GC scavenges free - // spans eagerly to ensure high physical memory utilization even - // during fragmentation. + // It sets up a specific scenario: it allocates two pairs of objects whose + // sizes sum to size. One object in each pair is "small" (though must be + // large enough to be considered a large object by the runtime) and one is + // large. The small objects are kept while the large objects are freed, + // creating two large unscavenged holes in the heap. The heap goal should + // also be small as a result (so size must be at least as large as the + // minimum heap size). We then allocate one large object, bigger than both + // pairs of objects combined. This allocation, because it will tip + // HeapSys-HeapReleased well above the heap goal, should trigger heap-growth + // scavenging and scavenge most, if not all, of the large holes we created + // earlier. const ( - // Unfortunately, measuring actual used physical pages is - // difficult because HeapReleased doesn't include the parts - // of an arena that haven't yet been touched. So, we just - // make objects and size sufficiently large such that even - // 64 MB overhead is relatively small in the final - // calculation. - // - // Currently, we target 480MiB worth of memory for our test, - // computed as size * objects + (size*2) * (objects/2) - // = 2 * size * objects - // // Size must be also large enough to be considered a large // object (not in any size-segregated span). - size = 1 << 20 - objects = 240 + size = 4 << 20 + split = 64 << 10 + objects = 2 ) + // Set GOGC so that this test operates under consistent assumptions. + debug.SetGCPercent(100) // Save objects which we want to survive, and condemn objects which we don't. // Note that we condemn objects in this way and release them all at once in // order to avoid having the GC start freeing up these objects while the loop // is still running and filling in the holes we intend to make. - saved := make([][]byte, 0, objects) - condemned := make([][]byte, 0, objects/2+1) - for i := 0; i < objects; i++ { - // Write into a global, to prevent this from being optimized away by - // the compiler in the future. - maybeSaved = make([]byte, size) + saved := make([][]byte, 0, objects+1) + condemned := make([][]byte, 0, objects) + for i := 0; i < 2*objects; i++ { if i%2 == 0 { - saved = append(saved, maybeSaved) + saved = append(saved, make([]byte, split)) } else { - condemned = append(condemned, maybeSaved) + condemned = append(condemned, make([]byte, size-split)) } } condemned = nil // Clean up the heap. This will free up every other object created above // (i.e. everything in condemned) creating holes in the heap. + // Also, if the condemned objects are still being swept, its possible that + // the scavenging that happens as a result of the next allocation won't see + // the holes at all. We call runtime.GC() twice here so that when we allocate + // our large object there's no race with sweeping. runtime.GC() - // Allocate many new objects of 2x size. - for i := 0; i < objects/2; i++ { - saved = append(saved, make([]byte, size*2)) - } + runtime.GC() + // Perform one big allocation which should also scavenge any holes. + // + // The heap goal will rise after this object is allocated, so it's very + // important that we try to do all the scavenging in a single allocation + // that exceeds the heap goal. Otherwise the rising heap goal could foil our + // test. + saved = append(saved, make([]byte, objects*size)) // Clean up the heap again just to put it in a known state. runtime.GC() // heapBacked is an estimate of the amount of physical memory used by @@ -191,21 +190,29 @@ func GCPhys() { var stats runtime.MemStats runtime.ReadMemStats(&stats) heapBacked := stats.HeapSys - stats.HeapReleased - // If heapBacked exceeds the amount of memory actually used for heap - // allocated objects by 10% (post-GC HeapAlloc should be quite close to - // the size of the working set), then fail. + // If heapBacked does not exceed the heap goal by more than retainExtraPercent + // then the scavenger is working as expected; the newly-created holes have been + // scavenged immediately as part of the allocations which cannot fit in the holes. // - // In the context of this test, that indicates a large amount of - // fragmentation with physical pages that are otherwise unused but not - // returned to the OS. + // Since the runtime should scavenge the entirety of the remaining holes, + // theoretically there should be no more free and unscavenged memory. However due + // to other allocations that happen during this test we may still see some physical + // memory over-use. 10% here is an arbitrary but very conservative threshold which + // should easily account for any other allocations this test may have done. overuse := (float64(heapBacked) - float64(stats.HeapAlloc)) / float64(stats.HeapAlloc) - if overuse > 0.1 { - fmt.Printf("exceeded physical memory overuse threshold of 10%%: %3.2f%%\n"+ - "(alloc: %d, sys: %d, rel: %d, objs: %d)\n", overuse*100, stats.HeapAlloc, - stats.HeapSys, stats.HeapReleased, len(saved)) + if overuse <= 0.10 { + fmt.Println("OK") return } - fmt.Println("OK") + // Physical memory utilization exceeds the threshold, so heap-growth scavenging + // did not operate as expected. + // + // In the context of this test, this indicates a large amount of + // fragmentation with physical pages that are otherwise unused but not + // returned to the OS. + fmt.Printf("exceeded physical memory overuse threshold of 10%%: %3.2f%%\n"+ + "(alloc: %d, goal: %d, sys: %d, rel: %d, objs: %d)\n", overuse*100, + stats.HeapAlloc, stats.NextGC, stats.HeapSys, stats.HeapReleased, len(saved)) runtime.KeepAlive(saved) } From c77a9e0aa5a8a238d68aa82b3b7e052a314a0060 Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Sun, 19 May 2019 12:07:45 -0700 Subject: [PATCH 15/50] runtime: In Frames.Next, delay file/line lookup until just before return MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit That way we will never have to look up the file/line for the frame that's next to be returned when the user stops calling Next. For the benchmark from #32093: name old time/op new time/op delta Helper-4 948ns ± 1% 836ns ± 3% -11.89% (p=0.000 n=9+9) (#32093 was fixed with a more specific, and better, fix, but this fix is much more general.) Change-Id: I89e796f80c9706706d8d8b30eb14be3a8a442846 Reviewed-on: https://go-review.googlesource.com/c/go/+/178077 Run-TryBot: Keith Randall Reviewed-by: Brad Fitzpatrick TryBot-Result: Gobot Gobot --- src/runtime/symtab.go | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/runtime/symtab.go b/src/runtime/symtab.go index c0e8dc279b..c2f32e0e5d 100644 --- a/src/runtime/symtab.go +++ b/src/runtime/symtab.go @@ -52,6 +52,11 @@ type Frame struct { // if not known. If Func is not nil then Entry == // Func.Entry(). Entry uintptr + + // The runtime's internal view of the function. This field + // is set (funcInfo.valid() returns true) only for Go functions, + // not for C functions. + funcInfo funcInfo } // CallersFrames takes a slice of PC values returned by Callers and @@ -95,7 +100,6 @@ func (ci *Frames) Next() (frame Frame, more bool) { pc-- } name := funcname(funcInfo) - file, line := funcline1(funcInfo, pc, false) if inldata := funcdata(funcInfo, _FUNCDATA_InlTree); inldata != nil { inltree := (*[1 << 20]inlinedCall)(inldata) ix := pcdatavalue(funcInfo, _PCDATA_InlTreeIndex, pc, nil) @@ -111,9 +115,9 @@ func (ci *Frames) Next() (frame Frame, more bool) { PC: pc, Func: f, Function: name, - File: file, - Line: int(line), Entry: entry, + funcInfo: funcInfo, + // Note: File,Line set below }) } @@ -121,6 +125,7 @@ func (ci *Frames) Next() (frame Frame, more bool) { // Avoid allocation in the common case, which is 1 or 2 frames. switch len(ci.frames) { case 0: // In the rare case when there are no frames at all, we return Frame{}. + return case 1: frame = ci.frames[0] ci.frames = ci.frameStore[:0] @@ -133,6 +138,13 @@ func (ci *Frames) Next() (frame Frame, more bool) { ci.frames = ci.frames[1:] } more = len(ci.frames) > 0 + if frame.funcInfo.valid() { + // Compute file/line just before we need to return it, + // as it can be expensive. This avoids computing file/line + // for the Frame we find but don't return. See issue 32093. + file, line := funcline1(frame.funcInfo, frame.PC, false) + frame.File, frame.Line = file, int(line) + } return } @@ -157,6 +169,8 @@ func expandCgoFrames(pc uintptr) []Frame { File: gostring(arg.file), Line: int(arg.lineno), Entry: arg.entry, + // funcInfo is zero, which implies !funcInfo.valid(). + // That ensures that we use the File/Line info given here. }) if arg.more == 0 { break From 776e1709e59c2c50d93467e666d4bb8955b32ed3 Mon Sep 17 00:00:00 2001 From: adarsh ravichandran Date: Mon, 20 May 2019 16:27:13 +0530 Subject: [PATCH 16/50] math/bits: add example for OnesCount function Change-Id: Id87db9bed5e8715d554c1bf95c063d7d0a03c3e9 Reviewed-on: https://go-review.googlesource.com/c/go/+/178117 Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- src/math/bits/example_test.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/math/bits/example_test.go b/src/math/bits/example_test.go index 18e026b9b4..b2ed2cba4b 100644 --- a/src/math/bits/example_test.go +++ b/src/math/bits/example_test.go @@ -59,6 +59,12 @@ func ExampleTrailingZeros64() { // TrailingZeros64(0000000000000000000000000000000000000000000000000000000000001110) = 1 } +func ExampleOnesCount() { + fmt.Printf("OnesCount(%b) = %d\n", 14, bits.OnesCount(14)) + // Output: + // OnesCount(1110) = 3 +} + func ExampleOnesCount8() { fmt.Printf("OnesCount8(%08b) = %d\n", 14, bits.OnesCount8(14)) // Output: From ab724d43efe7e1a7516c1d13e40b55dca26a61b4 Mon Sep 17 00:00:00 2001 From: Jay Conrod Date: Thu, 16 May 2019 18:35:48 -0400 Subject: [PATCH 17/50] cmd/go: make 'go get -t' consider test dependencies in module mode Fixes #32037 Change-Id: I696fe2029e383746252f37fe8d30df71b5ac8a6c Reviewed-on: https://go-review.googlesource.com/c/go/+/177677 Run-TryBot: Jay Conrod TryBot-Result: Gobot Gobot Reviewed-by: Bryan C. Mills --- src/cmd/go/alldocs.go | 8 ++- src/cmd/go/internal/modget/get.go | 37 +++++++------ src/cmd/go/internal/modload/load.go | 19 +++++-- src/cmd/go/testdata/script/mod_get_test.txt | 58 +++++++++++++++++++++ 4 files changed, 100 insertions(+), 22 deletions(-) create mode 100644 src/cmd/go/testdata/script/mod_get_test.txt diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go index b774ac2da7..1a7eff29a2 100644 --- a/src/cmd/go/alldocs.go +++ b/src/cmd/go/alldocs.go @@ -557,7 +557,7 @@ // // Usage: // -// go get [-d] [-m] [-u] [-v] [-insecure] [build flags] [packages] +// go get [-d] [-m] [-t] [-u] [-v] [-insecure] [build flags] [packages] // // Get resolves and adds dependencies to the current development module // and then builds and installs them. @@ -600,6 +600,9 @@ // are competing requirements for a particular module, then 'go get' resolves // those requirements by taking the maximum requested version.) // +// The -t flag instructs get to consider modules needed to build tests of +// packages specified on the command line. +// // The -u flag instructs get to update dependencies to use newer minor or // patch releases when available. Continuing the previous example, // 'go get -u A' will use the latest A with B v1.3.1 (not B v1.2.3). @@ -610,6 +613,9 @@ // 'go get -u=patch A@latest' will use the latest A with B v1.2.4 (not B v1.2.3), // while 'go get -u=patch A' will use a patch release of A instead. // +// When the -t and -u flags are used together, get will update +// test dependencies as well. +// // In general, adding a new dependency may require upgrading // existing dependencies to keep a working build, and 'go get' does // this automatically. Similarly, downgrading one dependency may diff --git a/src/cmd/go/internal/modget/get.go b/src/cmd/go/internal/modget/get.go index 7a5d550997..d5ab59490c 100644 --- a/src/cmd/go/internal/modget/get.go +++ b/src/cmd/go/internal/modget/get.go @@ -31,7 +31,7 @@ import ( var CmdGet = &base.Command{ // Note: -d -m -u are listed explicitly because they are the most common get flags. // Do not send CLs removing them because they're covered by [get flags]. - UsageLine: "go get [-d] [-m] [-u] [-v] [-insecure] [build flags] [packages]", + UsageLine: "go get [-d] [-m] [-t] [-u] [-v] [-insecure] [build flags] [packages]", Short: "add dependencies to current module and install them", Long: ` Get resolves and adds dependencies to the current development module @@ -75,6 +75,9 @@ will use the latest A but then use B v1.2.3, as requested by A. (If there are competing requirements for a particular module, then 'go get' resolves those requirements by taking the maximum requested version.) +The -t flag instructs get to consider modules needed to build tests of +packages specified on the command line. + The -u flag instructs get to update dependencies to use newer minor or patch releases when available. Continuing the previous example, 'go get -u A' will use the latest A with B v1.3.1 (not B v1.2.3). @@ -85,6 +88,9 @@ Continuing the previous example, 'go get -u=patch A@latest' will use the latest A with B v1.2.4 (not B v1.2.3), while 'go get -u=patch A' will use a patch release of A instead. +When the -t and -u flags are used together, get will update +test dependencies as well. + In general, adding a new dependency may require upgrading existing dependencies to keep a working build, and 'go get' does this automatically. Similarly, downgrading one dependency may @@ -261,9 +267,7 @@ func runGet(cmd *base.Command, args []string) { if *getFix { fmt.Fprintf(os.Stderr, "go get: -fix flag is a no-op when using modules\n") } - if *getT { - fmt.Fprintf(os.Stderr, "go get: -t flag is a no-op when using modules\n") - } + modload.LoadTests = *getT if cfg.BuildMod == "vendor" { base.Fatalf("go get: disabled by -mod=%s", cfg.BuildMod) @@ -781,25 +785,26 @@ func newUpgrader(cmdline map[string]*query, pkgs map[string]bool) *upgrader { // Initialize work queue with root packages. seen := make(map[string]bool) var work []string - for pkg := range pkgs { - seen[pkg] = true - for _, imp := range modload.PackageImports(pkg) { - if !pkgs[imp] && !seen[imp] { - seen[imp] = true - work = append(work, imp) - } + add := func(path string) { + if !seen[path] { + seen[path] = true + work = append(work, path) } } + for pkg := range pkgs { + add(pkg) + } for len(work) > 0 { pkg := work[0] work = work[1:] m := modload.PackageModule(pkg) u.upgrade[m.Path] = true - for _, imp := range modload.PackageImports(pkg) { - if !seen[imp] { - seen[imp] = true - work = append(work, imp) - } + imports, testImports := modload.PackageImports(pkg) + for _, imp := range imports { + add(imp) + } + for _, imp := range testImports { + add(imp) } } } diff --git a/src/cmd/go/internal/modload/load.go b/src/cmd/go/internal/modload/load.go index 579ef50382..b64b5b68cd 100644 --- a/src/cmd/go/internal/modload/load.go +++ b/src/cmd/go/internal/modload/load.go @@ -496,17 +496,26 @@ func PackageModule(path string) module.Version { } // PackageImports returns the imports for the package named by the import path. -// It does not include test imports. It returns nil for unknown packages. -func PackageImports(path string) []string { +// Test imports will be returned as well if tests were loaded for the package +// (i.e., if "all" was loaded or if LoadTests was set and the path was matched +// by a command line argument). PackageImports will return nil for +// unknown package paths. +func PackageImports(path string) (imports, testImports []string) { pkg, ok := loaded.pkgCache.Get(path).(*loadPkg) if !ok { - return nil + return nil, nil } - imports := make([]string, len(pkg.imports)) + imports = make([]string, len(pkg.imports)) for i, p := range pkg.imports { imports[i] = p.path } - return imports + if pkg.test != nil { + testImports = make([]string, len(pkg.test.imports)) + for i, p := range pkg.test.imports { + testImports[i] = p.path + } + } + return imports, testImports } // ModuleUsedDirectly reports whether the main module directly imports diff --git a/src/cmd/go/testdata/script/mod_get_test.txt b/src/cmd/go/testdata/script/mod_get_test.txt new file mode 100644 index 0000000000..f921168ad4 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_test.txt @@ -0,0 +1,58 @@ +env GO111MODULE=on + +# By default, 'go get' should ignore tests +cp go.mod.empty go.mod +go get m/a +! grep rsc.io/quote go.mod + +# 'go get -t' should consider test dependencies of the named package. +cp go.mod.empty go.mod +go get -d -t m/a +grep 'rsc.io/quote v1.5.2$' go.mod + +# 'go get -t' should not consider test dependencies of imported packages, +# including packages imported from tests. +cp go.mod.empty go.mod +go get -d -t m/b +! grep rsc.io/quote go.mod + +# 'go get -t -u' should update test dependencies of the named package. +cp go.mod.empty go.mod +go mod edit -require=rsc.io/quote@v1.5.1 +go get -d -t -u m/a +grep 'rsc.io/quote v1.5.2$' go.mod + +# 'go get -t -u' should not add or update test dependencies +# of imported packages, including packages imported from tests. +cp go.mod.empty go.mod +go get -d -t -u m/b +! grep rsc.io/quote go.mod +go mod edit -require=rsc.io/quote@v1.5.1 +go get -d -t -u m/b +grep 'rsc.io/quote v1.5.1$' go.mod + +# 'go get all' should consider test dependencies with or without -t. +cp go.mod.empty go.mod +go get all +grep 'rsc.io/quote v1.5.2$' go.mod + +-- go.mod.empty -- +module m + +-- a/a.go -- +package a + +-- a/a_test.go -- +package a_test + +import _ "rsc.io/quote" + +-- b/b.go -- +package b + +import _ "m/a" + +-- b/b_test.go -- +package b_test + +import _ "m/a" From 2d7cb295fdda94f3d62588b7bb01a4d8b445417a Mon Sep 17 00:00:00 2001 From: LE Manh Cuong Date: Sat, 4 May 2019 00:24:53 +0700 Subject: [PATCH 18/50] cmd/compile: clarify the difference between types.Sym and obj.LSym Both types.Sym and obj.LSym have the field Name, and that field is widely used in compiler source. It can lead to confusion that when to use which one. So, adding documentation for clarifying the difference between them, eliminate the confusion, or at least, make the code which use them clearer for the reader. See https://github.com/golang/go/issues/31252#issuecomment-481929174 Change-Id: I31f7fc6e4de4cf68f67ab2e3a385a7f451c796f5 Reviewed-on: https://go-review.googlesource.com/c/go/+/175019 Reviewed-by: Keith Randall Reviewed-by: Matthew Dempsky --- src/cmd/compile/internal/gc/syntax.go | 2 +- src/cmd/compile/internal/types/sym.go | 12 +++++++++--- src/cmd/internal/obj/link.go | 1 + 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/cmd/compile/internal/gc/syntax.go b/src/cmd/compile/internal/gc/syntax.go index 12bc9c3ae6..9f6646af44 100644 --- a/src/cmd/compile/internal/gc/syntax.go +++ b/src/cmd/compile/internal/gc/syntax.go @@ -280,7 +280,7 @@ func (n *Node) isMethodExpression() bool { return n.Op == ONAME && n.Left != nil && n.Left.Op == OTYPE && n.Right != nil && n.Right.Op == ONAME } -// funcname returns the name of the function n. +// funcname returns the name (without the package) of the function n. func (n *Node) funcname() string { if n == nil || n.Func == nil || n.Func.Nname == nil { return "" diff --git a/src/cmd/compile/internal/types/sym.go b/src/cmd/compile/internal/types/sym.go index 13761c7615..2779c368a9 100644 --- a/src/cmd/compile/internal/types/sym.go +++ b/src/cmd/compile/internal/types/sym.go @@ -11,14 +11,20 @@ import ( "unicode/utf8" ) -// Sym represents an object name. Most commonly, this is a Go identifier naming -// an object declared within a package, but Syms are also used to name internal -// synthesized objects. +// Sym represents an object name in a segmented (pkg, name) namespace. +// Most commonly, this is a Go identifier naming an object declared within a package, +// but Syms are also used to name internal synthesized objects. // // As an exception, field and method names that are exported use the Sym // associated with localpkg instead of the package that declared them. This // allows using Sym pointer equality to test for Go identifier uniqueness when // handling selector expressions. +// +// Ideally, Sym should be used for representing Go language constructs, +// while cmd/internal/obj.LSym is used for representing emitted artifacts. +// +// NOTE: In practice, things can be messier than the description above +// for various reasons (historical, convenience). type Sym struct { Importdef *Pkg // where imported definition was found Linkname string // link name diff --git a/src/cmd/internal/obj/link.go b/src/cmd/internal/obj/link.go index 3ea29a87a9..66748b25d2 100644 --- a/src/cmd/internal/obj/link.go +++ b/src/cmd/internal/obj/link.go @@ -377,6 +377,7 @@ const ( ) // An LSym is the sort of symbol that is written to an object file. +// It represents Go symbols in a flat pkg+"."+name namespace. type LSym struct { Name string Type objabi.SymKind From 4f248e988aa67a122d3355f6a22d50c1675697bb Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Thu, 16 May 2019 00:12:34 -0400 Subject: [PATCH 19/50] test: skip cross-arch codegen tests in all.bash The test/codegen tests check all architectures mentioned in the test file, but this requires building at least the runtime for that architecture. This CL changes the test to only check the local architecture, leaving checking of other architectures to the relevant builders, as usual. This cuts 'go run run.go codegen' by 12r 78u 21s. After this change, all.bash runs in ~4:40 on my laptop. For #26473. Change-Id: Ia0354d1aff2df2949f838528c8171410bc42dc8b Reviewed-on: https://go-review.googlesource.com/c/go/+/177577 Run-TryBot: Russ Cox Reviewed-by: Ian Lance Taylor --- test/run.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/run.go b/test/run.go index f66db630c5..84f5cd991c 100644 --- a/test/run.go +++ b/test/run.go @@ -34,6 +34,7 @@ var ( keep = flag.Bool("k", false, "keep. keep temporary directory.") numParallel = flag.Int("n", runtime.NumCPU(), "number of parallel tests to run") summary = flag.Bool("summary", false, "show summary of results") + allCodegen = flag.Bool("all_codegen", false, "run all goos/goarch for codegen") showSkips = flag.Bool("show_skips", false, "show skipped tests") runSkips = flag.Bool("run_skips", false, "run skipped tests (ignore skip and build tags)") linkshared = flag.Bool("linkshared", false, "") @@ -653,7 +654,13 @@ func (t *test) run() { // Compile Go file and match the generated assembly // against a set of regexps in comments. ops := t.wantedAsmOpcodes(long) + self := runtime.GOOS + "/" + runtime.GOARCH for _, env := range ops.Envs() { + // Only run checks relevant to the current GOOS/GOARCH, + // to avoid triggering a cross-compile of the runtime. + if string(env) != self && !strings.HasPrefix(string(env), self+"/") && !*allCodegen { + continue + } // -S=2 forces outermost line numbers when disassembling inlined code. cmdline := []string{"build", "-gcflags", "-S=2"} cmdline = append(cmdline, flags...) From 9b2bd2f7151381cc54638726808f55c6088fa30a Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Tue, 21 May 2019 06:06:11 +0000 Subject: [PATCH 20/50] mime: add .webp for builtin This change modifies Go to include image/webp as a built-in mime type for the .webp file extension. Change-Id: Id46d34fac8cc859ddd69aa8669294815654214f8 GitHub-Last-Rev: f191e1c325126e2caeb3123c912131ce5236542b GitHub-Pull-Request: golang/go#32157 Reviewed-on: https://go-review.googlesource.com/c/go/+/178317 Reviewed-by: Brad Fitzpatrick Run-TryBot: Brad Fitzpatrick --- src/mime/type.go | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mime/type.go b/src/mime/type.go index bf10de8d69..ad763133e6 100644 --- a/src/mime/type.go +++ b/src/mime/type.go @@ -69,6 +69,7 @@ var builtinTypesLower = map[string]string{ ".png": "image/png", ".svg": "image/svg+xml", ".wasm": "application/wasm", + ".webp": "image/webp", ".xml": "text/xml; charset=utf-8", } From d0aca5759e22dc00c06474c9123fb21129f6272b Mon Sep 17 00:00:00 2001 From: LE Manh Cuong Date: Tue, 21 May 2019 21:18:23 +0700 Subject: [PATCH 21/50] cmd/compile: fix doc typo in ssa.go Change-Id: Ie299a5eca6f6a7c5a37c00ff0de7ce322450375b Reviewed-on: https://go-review.googlesource.com/c/go/+/178123 Reviewed-by: Brad Fitzpatrick --- src/cmd/compile/internal/gc/ssa.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go index cafff01ddc..f9ccf84f72 100644 --- a/src/cmd/compile/internal/gc/ssa.go +++ b/src/cmd/compile/internal/gc/ssa.go @@ -5123,7 +5123,7 @@ func (s *SSAGenState) Br(op obj.As, target *ssa.Block) *obj.Prog { return p } -// DebugFriendlySetPos adjusts Pos.IsStmt subject to heuristics +// DebugFriendlySetPosFrom adjusts Pos.IsStmt subject to heuristics // that reduce "jumpy" line number churn when debugging. // Spill/fill/copy instructions from the register allocator, // phi functions, and instructions with a no-pos position From 1d1ba85d9986bb56226046c06dec4ce63ef9fe48 Mon Sep 17 00:00:00 2001 From: Caleb Spare Date: Wed, 8 May 2019 18:57:00 -0700 Subject: [PATCH 22/50] cmd/go: teach the build cache about -trimpath Fixes #31896 Change-Id: I228a809568cd37c599987f9f1e99df5c229e6c9b Reviewed-on: https://go-review.googlesource.com/c/go/+/176112 Run-TryBot: Caleb Spare TryBot-Result: Gobot Gobot Reviewed-by: Bryan C. Mills --- src/cmd/go/internal/work/exec.go | 6 ++++++ .../testdata/script/build_cache_trimpath.txt | 20 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 src/cmd/go/testdata/script/build_cache_trimpath.txt diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go index 35e70ddb1e..6f2d319bc2 100644 --- a/src/cmd/go/internal/work/exec.go +++ b/src/cmd/go/internal/work/exec.go @@ -211,6 +211,9 @@ func (b *Builder) buildActionID(a *Action) cache.ActionID { fmt.Fprintf(h, "goos %s goarch %s\n", cfg.Goos, cfg.Goarch) fmt.Fprintf(h, "import %q\n", p.ImportPath) fmt.Fprintf(h, "omitdebug %v standard %v local %v prefix %q\n", p.Internal.OmitDebug, p.Standard, p.Internal.Local, p.Internal.LocalPrefix) + if cfg.BuildTrimpath { + fmt.Fprintln(h, "trimpath") + } if p.Internal.ForceLibrary { fmt.Fprintf(h, "forcelibrary\n") } @@ -1116,6 +1119,9 @@ func (b *Builder) linkActionID(a *Action) cache.ActionID { fmt.Fprintf(h, "buildmode %s goos %s goarch %s\n", cfg.BuildBuildmode, cfg.Goos, cfg.Goarch) fmt.Fprintf(h, "import %q\n", p.ImportPath) fmt.Fprintf(h, "omitdebug %v standard %v local %v prefix %q\n", p.Internal.OmitDebug, p.Standard, p.Internal.Local, p.Internal.LocalPrefix) + if cfg.BuildTrimpath { + fmt.Fprintln(h, "trimpath") + } // Toolchain-dependent configuration, shared with b.linkSharedActionID. b.printLinkerConfig(h, p) diff --git a/src/cmd/go/testdata/script/build_cache_trimpath.txt b/src/cmd/go/testdata/script/build_cache_trimpath.txt new file mode 100644 index 0000000000..39367ae380 --- /dev/null +++ b/src/cmd/go/testdata/script/build_cache_trimpath.txt @@ -0,0 +1,20 @@ +env GO111MODULE=on + +# Set up fresh GOCACHE. +env GOCACHE=$WORK/gocache +mkdir $GOCACHE + +cd $WORK +go build -o a.out + +# Varying -trimpath should cause a rebuild. +go build -x -o a.out -trimpath +stderr '(compile|gccgo)( |\.exe)' +stderr 'link( |\.exe)' + +-- $WORK/hello.go -- +package main +func main() { println("hello") } + +-- $WORK/go.mod -- +module m From 2d357d8da864fc8d14e7e7834d521aa638243772 Mon Sep 17 00:00:00 2001 From: LE Manh Cuong Date: Thu, 16 May 2019 02:28:47 +0700 Subject: [PATCH 23/50] cmd/compile: fix typecheck type alias makes wrong export symbol metadata typecheck type alias always replaces the original definition of the symbol. This is wrong behavior because if the symbol's definition is replaced by a local type alias, it ends up being written to compiled file as an alias, instead of the original type. To fix, only replace the definition of symbol with global type alias. Fixes #31959 Change-Id: Id85a15e8a9d6a4b06727e655a95dc81e63df633a Reviewed-on: https://go-review.googlesource.com/c/go/+/177378 Run-TryBot: Emmanuel Odeke TryBot-Result: Gobot Gobot Reviewed-by: Matthew Dempsky --- src/cmd/compile/internal/gc/typecheck.go | 6 +++++- test/fixedbugs/issue31959.dir/a.go | 12 ++++++++++++ test/fixedbugs/issue31959.dir/main.go | 21 +++++++++++++++++++++ test/fixedbugs/issue31959.go | 7 +++++++ test/fixedbugs/issue31959.out | 2 ++ 5 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 test/fixedbugs/issue31959.dir/a.go create mode 100644 test/fixedbugs/issue31959.dir/main.go create mode 100644 test/fixedbugs/issue31959.go create mode 100644 test/fixedbugs/issue31959.out diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go index 81f59013f4..4cb28d6100 100644 --- a/src/cmd/compile/internal/gc/typecheck.go +++ b/src/cmd/compile/internal/gc/typecheck.go @@ -3671,7 +3671,11 @@ func typecheckdef(n *Node) { n.SetDiag(true) goto ret } - n.Sym.Def = asTypesNode(p.Ntype) + // For package-level type aliases, set n.Sym.Def so we can identify + // it as a type alias during export. See also #31959. + if n.Name.Curfn == nil { + n.Sym.Def = asTypesNode(p.Ntype) + } } break } diff --git a/test/fixedbugs/issue31959.dir/a.go b/test/fixedbugs/issue31959.dir/a.go new file mode 100644 index 0000000000..6c7ffa38c1 --- /dev/null +++ b/test/fixedbugs/issue31959.dir/a.go @@ -0,0 +1,12 @@ +// Copyright 2019 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 a + +type T struct{} + +func F() { + type T = int + println(T(0)) +} diff --git a/test/fixedbugs/issue31959.dir/main.go b/test/fixedbugs/issue31959.dir/main.go new file mode 100644 index 0000000000..895c4e5345 --- /dev/null +++ b/test/fixedbugs/issue31959.dir/main.go @@ -0,0 +1,21 @@ +// run + +// Copyright 2019 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. + +// Check import package contains type alias in function +// with the same name with an export type not panic + +package main + +import ( + "fmt" + + "a" +) + +func main() { + fmt.Println(a.T{}) + a.F() +} diff --git a/test/fixedbugs/issue31959.go b/test/fixedbugs/issue31959.go new file mode 100644 index 0000000000..af6f134172 --- /dev/null +++ b/test/fixedbugs/issue31959.go @@ -0,0 +1,7 @@ +// rundir + +// Copyright 2019 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 ignored diff --git a/test/fixedbugs/issue31959.out b/test/fixedbugs/issue31959.out new file mode 100644 index 0000000000..8ddcb67af1 --- /dev/null +++ b/test/fixedbugs/issue31959.out @@ -0,0 +1,2 @@ +{} +0 From b8648184941815d1466b09071e2907323b9283c6 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Thu, 16 May 2019 07:29:51 -0400 Subject: [PATCH 24/50] cmd/api: read std package info once, not per goos-goarch-cgo Cuts api test time from 12.7r 26.2u 14.2s to 7.5r 12.1u 2.2s. After this change, all.bash runs in ~4:36 on my laptop. For #26473. Change-Id: I4211e6afcd7ab61a4ed2c9a2aa5ac1ea04982695 Reviewed-on: https://go-review.googlesource.com/c/go/+/177597 Run-TryBot: Russ Cox TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- src/cmd/api/goapi.go | 101 +++++++++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 43 deletions(-) diff --git a/src/cmd/api/goapi.go b/src/cmd/api/goapi.go index c74ee9bfa2..b46b310267 100644 --- a/src/cmd/api/goapi.go +++ b/src/cmd/api/goapi.go @@ -144,7 +144,7 @@ func main() { } else { stds, err := exec.Command(goCmd(), "list", "std").Output() if err != nil { - log.Fatal(err) + log.Fatalf("go list std: %v\n%s", err, stds) } for _, pkg := range strings.Fields(string(stds)) { if !internalPkg.MatchString(pkg) { @@ -153,10 +153,25 @@ func main() { } } + importDir, importMap := loadImports() + + // The code below assumes that the import map can vary + // by package, so that an import in one package (directory) might mean + // something different from the same import in another. + // While this can happen in GOPATH mode with vendoring, + // it is not possible in the standard library: the one importMap + // returned by loadImports applies to all packages. + // Construct a per-directory importMap that resolves to + // that single map for all packages. + importMapForDir := make(map[string]map[string]string) + for _, dir := range importDir { + importMapForDir[dir] = importMap + } var featureCtx = make(map[string]map[string]bool) // feature -> context name -> true for _, context := range contexts { w := NewWalker(context, filepath.Join(build.Default.GOROOT, "src")) - w.loadImports(pkgNames, w.context) + w.importDir = importDir + w.importMap = importMapForDir for _, name := range pkgNames { // Vendored packages do not contribute to our @@ -440,58 +455,58 @@ func tagKey(dir string, context *build.Context, tags []string) string { return key } -func (w *Walker) loadImports(paths []string, context *build.Context) { - if context == nil { - context = &build.Default - } - - var ( - tags = context.BuildTags - cgoEnabled = "0" - ) - if context.CgoEnabled { - tags = append(tags[:len(tags):len(tags)], "cgo") - cgoEnabled = "1" - } - - // TODO(golang.org/issue/29666): Request only the fields that we need. - cmd := exec.Command(goCmd(), "list", "-e", "-deps", "-json") - if len(tags) > 0 { - cmd.Args = append(cmd.Args, "-tags", strings.Join(tags, " ")) - } - cmd.Args = append(cmd.Args, paths...) - - cmd.Env = append(os.Environ(), - "GOOS="+context.GOOS, - "GOARCH="+context.GOARCH, - "CGO_ENABLED="+cgoEnabled, - ) - - stdout := new(bytes.Buffer) - cmd.Stdout = stdout - cmd.Stderr = new(strings.Builder) - err := cmd.Run() +// loadImports returns information about the packages in the standard library +// and the packages they themselves import. +// importDir maps expanded import path to the directory containing that package. +// importMap maps source import path to expanded import path. +// The source import path and expanded import path are identical except for vendored packages. +// For example, on return: +// +// importMap["math"] = "math" +// importDir["math"] = "/src/math" +// +// importMap["golang.org/x/net/route"] = "vendor/golang.org/x/net/route" +// importDir["vendor/golang.org/x/net/route"] = "/src/vendor/golang.org/x/net/route" +// +// There are a few imports that only appear on certain platforms, +// including it turns out x/net/route, and we add those explicitly. +func loadImports() (importDir map[string]string, importMap map[string]string) { + out, err := exec.Command(goCmd(), "list", "-e", "-deps", "-json", "std").CombinedOutput() if err != nil { - log.Fatalf("%s failed: %v\n%s", strings.Join(cmd.Args, " "), err, cmd.Stderr) + log.Fatalf("loading imports: %v\n%s", err, out) } - w.importDir = make(map[string]string) - w.importMap = make(map[string]map[string]string) - dec := json.NewDecoder(stdout) + importDir = make(map[string]string) + importMap = make(map[string]string) + dec := json.NewDecoder(bytes.NewReader(out)) for { var pkg struct { ImportPath, Dir string ImportMap map[string]string } - if err := dec.Decode(&pkg); err == io.EOF { + err := dec.Decode(&pkg) + if err == io.EOF { break - } else if err != nil { - log.Fatalf("%s: invalid output: %v", strings.Join(cmd.Args, " "), err) + } + if err != nil { + log.Fatalf("go list: invalid output: %v", err) } - w.importDir[pkg.ImportPath] = pkg.Dir - w.importMap[pkg.Dir] = pkg.ImportMap + importDir[pkg.ImportPath] = pkg.Dir + for k, v := range pkg.ImportMap { + importMap[k] = v + } } + + // Fixup for vendor packages listed in args above. + fixup := []string{ + "vendor/golang.org/x/net/route", + } + for _, pkg := range fixup { + importDir[pkg] = filepath.Join(build.Default.GOROOT, "src", pkg) + importMap[strings.TrimPrefix(pkg, "vendor/")] = pkg + } + return } // Importing is a sentinel taking the place in Walker.imported @@ -523,7 +538,7 @@ func (w *Walker) ImportFrom(fromPath, fromDir string, mode types.ImportMode) (*t dir = filepath.Join(w.root, filepath.FromSlash(name)) } if fi, err := os.Stat(dir); err != nil || !fi.IsDir() { - log.Fatalf("no source in tree for import %q: %v", name, err) + log.Fatalf("no source in tree for import %q (from import %s in %s): %v", name, fromPath, fromDir, err) } context := w.context From 798e0b38ed8b23da010b1a8cd6c91f201248e40d Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Thu, 16 May 2019 10:00:10 -0400 Subject: [PATCH 25/50] misc/cgo/errors: consolidate test work Build a single binary containing all the TestPointerChecks instead of building many small binaries, each with its own cgo+compile+link invocation. This cuts 'go test -run=TestPointerChecks' from 6.7r 35.5u 26.1s to 2.1r 2.1u 1.4s. Move as many cgo checks as possible into fewer test files for TestReportsTypeErrors too. This cuts 'go test -run=TestReportsTypeErrors' from 2.1r 6.7u 6.7s to 1.5r 2.5u 2.5s. After this change, all.bash runs in ~4:30 on my laptop. For #26473. Change-Id: I3787448b03689a1f62dd810957ab6013bb75582f Reviewed-on: https://go-review.googlesource.com/c/go/+/177599 Run-TryBot: Russ Cox TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- misc/cgo/errors/errors_test.go | 13 +- misc/cgo/errors/ptr_test.go | 484 ++++++++++++++----------- misc/cgo/errors/testdata/err1.go | 4 + misc/cgo/errors/testdata/err2.go | 89 +++++ misc/cgo/errors/testdata/err3.go | 18 - misc/cgo/errors/testdata/issue13129.go | 14 - misc/cgo/errors/testdata/issue13423.go | 12 - misc/cgo/errors/testdata/issue13467.go | 15 - misc/cgo/errors/testdata/issue13635.go | 24 -- misc/cgo/errors/testdata/issue13830.go | 26 -- misc/cgo/errors/testdata/issue16116.go | 12 - misc/cgo/errors/testdata/issue16591.go | 17 - misc/cgo/errors/testdata/issue26745.go | 17 - misc/cgo/errors/testdata/issue7757.go | 14 - misc/cgo/errors/testdata/issue8442.go | 17 - 15 files changed, 357 insertions(+), 419 deletions(-) delete mode 100644 misc/cgo/errors/testdata/err3.go delete mode 100644 misc/cgo/errors/testdata/issue13129.go delete mode 100644 misc/cgo/errors/testdata/issue13423.go delete mode 100644 misc/cgo/errors/testdata/issue13467.go delete mode 100644 misc/cgo/errors/testdata/issue13635.go delete mode 100644 misc/cgo/errors/testdata/issue13830.go delete mode 100644 misc/cgo/errors/testdata/issue16116.go delete mode 100644 misc/cgo/errors/testdata/issue16591.go delete mode 100644 misc/cgo/errors/testdata/issue26745.go delete mode 100644 misc/cgo/errors/testdata/issue7757.go delete mode 100644 misc/cgo/errors/testdata/issue8442.go diff --git a/misc/cgo/errors/errors_test.go b/misc/cgo/errors/errors_test.go index f727158c48..e6bac0fff4 100644 --- a/misc/cgo/errors/errors_test.go +++ b/misc/cgo/errors/errors_test.go @@ -63,7 +63,7 @@ func expect(t *testing.T, file string, errors []*regexp.Regexp) { defer os.RemoveAll(dir) dst := filepath.Join(dir, strings.TrimSuffix(file, ".go")) - cmd := exec.Command("go", "build", "-gcflags=-L", "-o="+dst, path(file)) // TODO(gri) no need for -gcflags=-L if go tool is adjusted + cmd := exec.Command("go", "build", "-gcflags=-L -e", "-o="+dst, path(file)) // TODO(gri) no need for -gcflags=-L if go tool is adjusted out, err := cmd.CombinedOutput() if err == nil { t.Errorf("expected cgo to fail but it succeeded") @@ -107,21 +107,10 @@ func TestReportsTypeErrors(t *testing.T) { for _, file := range []string{ "err1.go", "err2.go", - "err3.go", - "issue7757.go", - "issue8442.go", "issue11097a.go", "issue11097b.go", - "issue13129.go", - "issue13423.go", - "issue13467.go", - "issue13635.go", - "issue13830.go", - "issue16116.go", - "issue16591.go", "issue18452.go", "issue18889.go", - "issue26745.go", "issue28721.go", } { check(t, file) diff --git a/misc/cgo/errors/ptr_test.go b/misc/cgo/errors/ptr_test.go index 629f4c9226..ba4f4ade64 100644 --- a/misc/cgo/errors/ptr_test.go +++ b/misc/cgo/errors/ptr_test.go @@ -7,21 +7,25 @@ package errorstest import ( - "bufio" "bytes" + "flag" "fmt" "io/ioutil" "os" "os/exec" "path/filepath" "strings" + "sync/atomic" "testing" ) +var tmp = flag.String("tmp", "", "use `dir` for temporary files and do not clean up") + // ptrTest is the tests without the boilerplate. type ptrTest struct { name string // for reporting c string // the cgo comment + c1 string // cgo comment forced into non-export cgo file imports []string // a list of imports support string // supporting functions body string // the body of the main function @@ -39,253 +43,248 @@ var ptrTests = []ptrTest{ { // Passing a pointer to a struct that contains a Go pointer. name: "ptr1", - c: `typedef struct s { int *p; } s; void f(s *ps) {}`, - body: `C.f(&C.s{new(C.int)})`, + c: `typedef struct s1 { int *p; } s1; void f1(s1 *ps) {}`, + body: `C.f1(&C.s1{new(C.int)})`, fail: true, }, { // Passing a pointer to a struct that contains a Go pointer. name: "ptr2", - c: `typedef struct s { int *p; } s; void f(s *ps) {}`, - body: `p := &C.s{new(C.int)}; C.f(p)`, + c: `typedef struct s2 { int *p; } s2; void f2(s2 *ps) {}`, + body: `p := &C.s2{new(C.int)}; C.f2(p)`, fail: true, }, { // Passing a pointer to an int field of a Go struct // that (irrelevantly) contains a Go pointer. name: "ok1", - c: `struct s { int i; int *p; }; void f(int *p) {}`, - body: `p := &C.struct_s{i: 0, p: new(C.int)}; C.f(&p.i)`, + c: `struct s3 { int i; int *p; }; void f3(int *p) {}`, + body: `p := &C.struct_s3{i: 0, p: new(C.int)}; C.f3(&p.i)`, fail: false, }, { // Passing a pointer to a pointer field of a Go struct. - name: "ptr-field", - c: `struct s { int i; int *p; }; void f(int **p) {}`, - body: `p := &C.struct_s{i: 0, p: new(C.int)}; C.f(&p.p)`, + name: "ptrfield", + c: `struct s4 { int i; int *p; }; void f4(int **p) {}`, + body: `p := &C.struct_s4{i: 0, p: new(C.int)}; C.f4(&p.p)`, fail: true, }, { // Passing a pointer to a pointer field of a Go // struct, where the field does not contain a Go // pointer, but another field (irrelevantly) does. - name: "ptr-field-ok", - c: `struct s { int *p1; int *p2; }; void f(int **p) {}`, - body: `p := &C.struct_s{p1: nil, p2: new(C.int)}; C.f(&p.p1)`, + name: "ptrfieldok", + c: `struct s5 { int *p1; int *p2; }; void f5(int **p) {}`, + body: `p := &C.struct_s5{p1: nil, p2: new(C.int)}; C.f5(&p.p1)`, fail: false, }, { // Passing the address of a slice with no Go pointers. - name: "slice-ok-1", - c: `void f(void **p) {}`, + name: "sliceok1", + c: `void f6(void **p) {}`, imports: []string{"unsafe"}, - body: `s := []unsafe.Pointer{nil}; C.f(&s[0])`, + body: `s := []unsafe.Pointer{nil}; C.f6(&s[0])`, fail: false, }, { // Passing the address of a slice with a Go pointer. - name: "slice-ptr-1", - c: `void f(void **p) {}`, + name: "sliceptr1", + c: `void f7(void **p) {}`, imports: []string{"unsafe"}, - body: `i := 0; s := []unsafe.Pointer{unsafe.Pointer(&i)}; C.f(&s[0])`, + body: `i := 0; s := []unsafe.Pointer{unsafe.Pointer(&i)}; C.f7(&s[0])`, fail: true, }, { // Passing the address of a slice with a Go pointer, // where we are passing the address of an element that // is not a Go pointer. - name: "slice-ptr-2", - c: `void f(void **p) {}`, + name: "sliceptr2", + c: `void f8(void **p) {}`, imports: []string{"unsafe"}, - body: `i := 0; s := []unsafe.Pointer{nil, unsafe.Pointer(&i)}; C.f(&s[0])`, + body: `i := 0; s := []unsafe.Pointer{nil, unsafe.Pointer(&i)}; C.f8(&s[0])`, fail: true, }, { // Passing the address of a slice that is an element // in a struct only looks at the slice. - name: "slice-ok-2", - c: `void f(void **p) {}`, + name: "sliceok2", + c: `void f9(void **p) {}`, imports: []string{"unsafe"}, - support: `type S struct { p *int; s []unsafe.Pointer }`, - body: `i := 0; p := &S{p:&i, s:[]unsafe.Pointer{nil}}; C.f(&p.s[0])`, + support: `type S9 struct { p *int; s []unsafe.Pointer }`, + body: `i := 0; p := &S9{p:&i, s:[]unsafe.Pointer{nil}}; C.f9(&p.s[0])`, fail: false, }, { // Passing the address of a slice of an array that is // an element in a struct, with a type conversion. - name: "slice-ok-3", - c: `void f(void* p) {}`, + name: "sliceok3", + c: `void f10(void* p) {}`, imports: []string{"unsafe"}, - support: `type S struct { p *int; a [4]byte }`, - body: `i := 0; p := &S{p:&i}; s := p.a[:]; C.f(unsafe.Pointer(&s[0]))`, + support: `type S10 struct { p *int; a [4]byte }`, + body: `i := 0; p := &S10{p:&i}; s := p.a[:]; C.f10(unsafe.Pointer(&s[0]))`, fail: false, }, { // Passing the address of a slice of an array that is // an element in a struct, with a type conversion. - name: "slice-ok-4", - c: `typedef void* PV; void f(PV p) {}`, + name: "sliceok4", + c: `typedef void* PV11; void f11(PV11 p) {}`, imports: []string{"unsafe"}, - support: `type S struct { p *int; a [4]byte }`, - body: `i := 0; p := &S{p:&i}; C.f(C.PV(unsafe.Pointer(&p.a[0])))`, + support: `type S11 struct { p *int; a [4]byte }`, + body: `i := 0; p := &S11{p:&i}; C.f11(C.PV11(unsafe.Pointer(&p.a[0])))`, fail: false, }, { // Passing the address of a static variable with no // pointers doesn't matter. name: "varok", - c: `void f(char** parg) {}`, - support: `var hello = [...]C.char{'h', 'e', 'l', 'l', 'o'}`, - body: `parg := [1]*C.char{&hello[0]}; C.f(&parg[0])`, + c: `void f12(char** parg) {}`, + support: `var hello12 = [...]C.char{'h', 'e', 'l', 'l', 'o'}`, + body: `parg := [1]*C.char{&hello12[0]}; C.f12(&parg[0])`, fail: false, }, { // Passing the address of a static variable with // pointers does matter. - name: "var", - c: `void f(char*** parg) {}`, - support: `var hello = [...]*C.char{new(C.char)}`, - body: `parg := [1]**C.char{&hello[0]}; C.f(&parg[0])`, + name: "var1", + c: `void f13(char*** parg) {}`, + support: `var hello13 = [...]*C.char{new(C.char)}`, + body: `parg := [1]**C.char{&hello13[0]}; C.f13(&parg[0])`, fail: true, }, { // Storing a Go pointer into C memory should fail. name: "barrier", c: `#include - char **f1() { return malloc(sizeof(char*)); } - void f2(char **p) {}`, - body: `p := C.f1(); *p = new(C.char); C.f2(p)`, + char **f14a() { return malloc(sizeof(char*)); } + void f14b(char **p) {}`, + body: `p := C.f14a(); *p = new(C.char); C.f14b(p)`, fail: true, expensive: true, }, { // Storing a Go pointer into C memory by assigning a // large value should fail. - name: "barrier-struct", + name: "barrierstruct", c: `#include - struct s { char *a[10]; }; - struct s *f1() { return malloc(sizeof(struct s)); } - void f2(struct s *p) {}`, - body: `p := C.f1(); p.a = [10]*C.char{new(C.char)}; C.f2(p)`, + struct s15 { char *a[10]; }; + struct s15 *f15() { return malloc(sizeof(struct s15)); } + void f15b(struct s15 *p) {}`, + body: `p := C.f15(); p.a = [10]*C.char{new(C.char)}; C.f15b(p)`, fail: true, expensive: true, }, { // Storing a Go pointer into C memory using a slice // copy should fail. - name: "barrier-slice", + name: "barrierslice", c: `#include - struct s { char *a[10]; }; - struct s *f1() { return malloc(sizeof(struct s)); } - void f2(struct s *p) {}`, - body: `p := C.f1(); copy(p.a[:], []*C.char{new(C.char)}); C.f2(p)`, + struct s16 { char *a[10]; }; + struct s16 *f16() { return malloc(sizeof(struct s16)); } + void f16b(struct s16 *p) {}`, + body: `p := C.f16(); copy(p.a[:], []*C.char{new(C.char)}); C.f16b(p)`, fail: true, expensive: true, }, { // A very large value uses a GC program, which is a // different code path. - name: "barrier-gcprog-array", + name: "barriergcprogarray", c: `#include - struct s { char *a[32769]; }; - struct s *f1() { return malloc(sizeof(struct s)); } - void f2(struct s *p) {}`, - body: `p := C.f1(); p.a = [32769]*C.char{new(C.char)}; C.f2(p)`, + struct s17 { char *a[32769]; }; + struct s17 *f17() { return malloc(sizeof(struct s17)); } + void f17b(struct s17 *p) {}`, + body: `p := C.f17(); p.a = [32769]*C.char{new(C.char)}; C.f17b(p)`, fail: true, expensive: true, }, { // Similar case, with a source on the heap. - name: "barrier-gcprog-array-heap", + name: "barriergcprogarrayheap", c: `#include - struct s { char *a[32769]; }; - struct s *f1() { return malloc(sizeof(struct s)); } - void f2(struct s *p) {} - void f3(void *p) {}`, + struct s18 { char *a[32769]; }; + struct s18 *f18() { return malloc(sizeof(struct s18)); } + void f18b(struct s18 *p) {} + void f18c(void *p) {}`, imports: []string{"unsafe"}, - body: `p := C.f1(); n := &[32769]*C.char{new(C.char)}; p.a = *n; C.f2(p); n[0] = nil; C.f3(unsafe.Pointer(n))`, + body: `p := C.f18(); n := &[32769]*C.char{new(C.char)}; p.a = *n; C.f18b(p); n[0] = nil; C.f18c(unsafe.Pointer(n))`, fail: true, expensive: true, }, { // A GC program with a struct. - name: "barrier-gcprog-struct", + name: "barriergcprogstruct", c: `#include - struct s { char *a[32769]; }; - struct s2 { struct s f; }; - struct s2 *f1() { return malloc(sizeof(struct s2)); } - void f2(struct s2 *p) {}`, - body: `p := C.f1(); p.f = C.struct_s{[32769]*C.char{new(C.char)}}; C.f2(p)`, + struct s19a { char *a[32769]; }; + struct s19b { struct s19a f; }; + struct s19b *f19() { return malloc(sizeof(struct s19b)); } + void f19b(struct s19b *p) {}`, + body: `p := C.f19(); p.f = C.struct_s19a{[32769]*C.char{new(C.char)}}; C.f19b(p)`, fail: true, expensive: true, }, { // Similar case, with a source on the heap. - name: "barrier-gcprog-struct-heap", + name: "barriergcprogstructheap", c: `#include - struct s { char *a[32769]; }; - struct s2 { struct s f; }; - struct s2 *f1() { return malloc(sizeof(struct s2)); } - void f2(struct s2 *p) {} - void f3(void *p) {}`, + struct s20a { char *a[32769]; }; + struct s20b { struct s20a f; }; + struct s20b *f20() { return malloc(sizeof(struct s20b)); } + void f20b(struct s20b *p) {} + void f20c(void *p) {}`, imports: []string{"unsafe"}, - body: `p := C.f1(); n := &C.struct_s{[32769]*C.char{new(C.char)}}; p.f = *n; C.f2(p); n.a[0] = nil; C.f3(unsafe.Pointer(n))`, + body: `p := C.f20(); n := &C.struct_s20a{[32769]*C.char{new(C.char)}}; p.f = *n; C.f20b(p); n.a[0] = nil; C.f20c(unsafe.Pointer(n))`, fail: true, expensive: true, }, { // Exported functions may not return Go pointers. name: "export1", - c: `extern unsigned char *GoFn();`, - support: `//export GoFn - func GoFn() *byte { return new(byte) }`, - body: `C.GoFn()`, + c: `extern unsigned char *GoFn21();`, + support: `//export GoFn21 + func GoFn21() *byte { return new(byte) }`, + body: `C.GoFn21()`, fail: true, }, { // Returning a C pointer is fine. name: "exportok", c: `#include - extern unsigned char *GoFn();`, - support: `//export GoFn - func GoFn() *byte { return (*byte)(C.malloc(1)) }`, - body: `C.GoFn()`, + extern unsigned char *GoFn22();`, + support: `//export GoFn22 + func GoFn22() *byte { return (*byte)(C.malloc(1)) }`, + body: `C.GoFn22()`, }, { // Passing a Go string is fine. - name: "pass-string", + name: "passstring", c: `#include - typedef struct { const char *p; ptrdiff_t n; } gostring; - gostring f(gostring s) { return s; }`, + typedef struct { const char *p; ptrdiff_t n; } gostring23; + gostring23 f23(gostring23 s) { return s; }`, imports: []string{"unsafe"}, - body: `s := "a"; r := C.f(*(*C.gostring)(unsafe.Pointer(&s))); if *(*string)(unsafe.Pointer(&r)) != s { panic(r) }`, + body: `s := "a"; r := C.f23(*(*C.gostring23)(unsafe.Pointer(&s))); if *(*string)(unsafe.Pointer(&r)) != s { panic(r) }`, }, { // Passing a slice of Go strings fails. - name: "pass-string-slice", - c: `void f(void *p) {}`, + name: "passstringslice", + c: `void f24(void *p) {}`, imports: []string{"strings", "unsafe"}, - support: `type S struct { a [1]string }`, - body: `s := S{a:[1]string{strings.Repeat("a", 2)}}; C.f(unsafe.Pointer(&s.a[0]))`, + support: `type S24 struct { a [1]string }`, + body: `s := S24{a:[1]string{strings.Repeat("a", 2)}}; C.f24(unsafe.Pointer(&s.a[0]))`, fail: true, }, { // Exported functions may not return strings. - name: "ret-string", - c: `extern void f();`, + name: "retstring", + c: `extern void f25();`, imports: []string{"strings"}, - support: `//export GoStr - func GoStr() string { return strings.Repeat("a", 2) }`, - body: `C.f()`, - extra: []extra{ - { - "call.c", - `#include - typedef struct { const char *p; ptrdiff_t n; } gostring; - extern gostring GoStr(); - void f() { GoStr(); }`, - }, - }, + support: `//export GoStr25 + func GoStr25() string { return strings.Repeat("a", 2) }`, + body: `C.f25()`, + c1: `#include + typedef struct { const char *p; ptrdiff_t n; } gostring25; + extern gostring25 GoStr25(); + void f25() { GoStr25(); }`, fail: true, }, { @@ -296,37 +295,37 @@ var ptrTests = []ptrTest{ // that is, we are testing something that is not unsafe. name: "ptrdata1", c: `#include - void f(void* p) {}`, + void f26(void* p) {}`, imports: []string{"unsafe"}, - support: `type S struct { p *int; a [8*8]byte; u uintptr }`, - body: `i := 0; p := &S{u:uintptr(unsafe.Pointer(&i))}; q := (*S)(C.malloc(C.size_t(unsafe.Sizeof(*p)))); *q = *p; C.f(unsafe.Pointer(q))`, + support: `type S26 struct { p *int; a [8*8]byte; u uintptr }`, + body: `i := 0; p := &S26{u:uintptr(unsafe.Pointer(&i))}; q := (*S26)(C.malloc(C.size_t(unsafe.Sizeof(*p)))); *q = *p; C.f26(unsafe.Pointer(q))`, fail: false, }, { // Like ptrdata1, but with a type that uses a GC program. name: "ptrdata2", c: `#include - void f(void* p) {}`, + void f27(void* p) {}`, imports: []string{"unsafe"}, - support: `type S struct { p *int; a [32769*8]byte; q *int; u uintptr }`, - body: `i := 0; p := S{u:uintptr(unsafe.Pointer(&i))}; q := (*S)(C.malloc(C.size_t(unsafe.Sizeof(p)))); *q = p; C.f(unsafe.Pointer(q))`, + support: `type S27 struct { p *int; a [32769*8]byte; q *int; u uintptr }`, + body: `i := 0; p := S27{u:uintptr(unsafe.Pointer(&i))}; q := (*S27)(C.malloc(C.size_t(unsafe.Sizeof(p)))); *q = p; C.f27(unsafe.Pointer(q))`, fail: false, }, { // Check deferred pointers when they are used, not // when the defer statement is run. - name: "defer", - c: `typedef struct s { int *p; } s; void f(s *ps) {}`, - body: `p := &C.s{}; defer C.f(p); p.p = new(C.int)`, + name: "defer1", + c: `typedef struct s28 { int *p; } s28; void f28(s28 *ps) {}`, + body: `p := &C.s28{}; defer C.f28(p); p.p = new(C.int)`, fail: true, }, { // Check a pointer to a union if the union has any // pointer fields. name: "union1", - c: `typedef union { char **p; unsigned long i; } u; void f(u *pu) {}`, + c: `typedef union { char **p; unsigned long i; } u29; void f29(u29 *pu) {}`, imports: []string{"unsafe"}, - body: `var b C.char; p := &b; C.f((*C.u)(unsafe.Pointer(&p)))`, + body: `var b C.char; p := &b; C.f29((*C.u29)(unsafe.Pointer(&p)))`, fail: true, }, { @@ -336,55 +335,55 @@ var ptrTests = []ptrTest{ // integer that happens to have the same // representation as a pointer. name: "union2", - c: `typedef union { unsigned long i; } u; void f(u *pu) {}`, + c: `typedef union { unsigned long i; } u39; void f39(u39 *pu) {}`, imports: []string{"unsafe"}, - body: `var b C.char; p := &b; C.f((*C.u)(unsafe.Pointer(&p)))`, + body: `var b C.char; p := &b; C.f39((*C.u39)(unsafe.Pointer(&p)))`, fail: false, }, { // Test preemption while entering a cgo call. Issue #21306. - name: "preempt-during-call", - c: `void f() {}`, + name: "preemptduringcall", + c: `void f30() {}`, imports: []string{"runtime", "sync"}, - body: `var wg sync.WaitGroup; wg.Add(100); for i := 0; i < 100; i++ { go func(i int) { for j := 0; j < 100; j++ { C.f(); runtime.GOMAXPROCS(i) }; wg.Done() }(i) }; wg.Wait()`, + body: `var wg sync.WaitGroup; wg.Add(100); for i := 0; i < 100; i++ { go func(i int) { for j := 0; j < 100; j++ { C.f30(); runtime.GOMAXPROCS(i) }; wg.Done() }(i) }; wg.Wait()`, fail: false, }, { // Test poller deadline with cgocheck=2. Issue #23435. name: "deadline", - c: `#define US 10`, + c: `#define US31 10`, imports: []string{"os", "time"}, - body: `r, _, _ := os.Pipe(); r.SetDeadline(time.Now().Add(C.US * time.Microsecond))`, + body: `r, _, _ := os.Pipe(); r.SetDeadline(time.Now().Add(C.US31 * time.Microsecond))`, fail: false, }, { // Test for double evaluation of channel receive. - name: "chan-recv", - c: `void f(char** p) {}`, + name: "chanrecv", + c: `void f32(char** p) {}`, imports: []string{"time"}, - body: `c := make(chan []*C.char, 2); c <- make([]*C.char, 1); go func() { time.Sleep(10 * time.Second); panic("received twice from chan") }(); C.f(&(<-c)[0]);`, + body: `c := make(chan []*C.char, 2); c <- make([]*C.char, 1); go func() { time.Sleep(10 * time.Second); panic("received twice from chan") }(); C.f32(&(<-c)[0]);`, fail: false, }, { // Test that converting the address of a struct field // to unsafe.Pointer still just checks that field. // Issue #25941. - name: "struct-field", - c: `void f(void* p) {}`, + name: "structfield", + c: `void f33(void* p) {}`, imports: []string{"unsafe"}, - support: `type S struct { p *int; a [8]byte; u uintptr }`, - body: `s := &S{p: new(int)}; C.f(unsafe.Pointer(&s.a))`, + support: `type S33 struct { p *int; a [8]byte; u uintptr }`, + body: `s := &S33{p: new(int)}; C.f33(unsafe.Pointer(&s.a))`, fail: false, }, { // Test that converting multiple struct field // addresses to unsafe.Pointer still just checks those // fields. Issue #25941. - name: "struct-field-2", - c: `void f(void* p, int r, void* s) {}`, + name: "structfield2", + c: `void f34(void* p, int r, void* s) {}`, imports: []string{"unsafe"}, - support: `type S struct { a [8]byte; p *int; b int64; }`, - body: `s := &S{p: new(int)}; C.f(unsafe.Pointer(&s.a), 32, unsafe.Pointer(&s.b))`, + support: `type S34 struct { a [8]byte; p *int; b int64; }`, + body: `s := &S34{p: new(int)}; C.f34(unsafe.Pointer(&s.a), 32, unsafe.Pointer(&s.b))`, fail: false, }, { @@ -392,18 +391,18 @@ var ptrTests = []ptrTest{ // evaluated when a deferred function is deferred, not // when it is run. name: "defer2", - c: `void f(char **pc) {}`, - support: `type S1 struct { s []*C.char }; type S2 struct { ps *S1 }`, - body: `p := &S2{&S1{[]*C.char{nil}}}; defer C.f(&p.ps.s[0]); p.ps = nil`, + c: `void f35(char **pc) {}`, + support: `type S35a struct { s []*C.char }; type S35b struct { ps *S35a }`, + body: `p := &S35b{&S35a{[]*C.char{nil}}}; defer C.f35(&p.ps.s[0]); p.ps = nil`, fail: false, }, { // Test that indexing into a function call still // examines only the slice being indexed. name: "buffer", - c: `void f(void *p) {}`, + c: `void f36(void *p) {}`, imports: []string{"bytes", "unsafe"}, - body: `var b bytes.Buffer; b.WriteString("a"); C.f(unsafe.Pointer(&b.Bytes()[0]))`, + body: `var b bytes.Buffer; b.WriteString("a"); C.f36(unsafe.Pointer(&b.Bytes()[0]))`, fail: false, }, { @@ -411,8 +410,8 @@ var ptrTests = []ptrTest{ name: "finalizer", c: `// Nothing to declare.`, imports: []string{"os"}, - support: `func open() { os.Open(os.Args[0]) }; var G [][]byte`, - body: `for i := 0; i < 10000; i++ { G = append(G, make([]byte, 4096)); if i % 100 == 0 { G = nil; open() } }`, + support: `func open37() { os.Open(os.Args[0]) }; var G37 [][]byte`, + body: `for i := 0; i < 10000; i++ { G37 = append(G37, make([]byte, 4096)); if i % 100 == 0 { G37 = nil; open37() } }`, fail: false, }, { @@ -420,103 +419,155 @@ var ptrTests = []ptrTest{ name: "structof", c: `// Nothing to declare.`, imports: []string{"reflect"}, - support: `type MyInt int; func (i MyInt) Get() int { return int(i) }; type Getter interface { Get() int }`, - body: `t := reflect.StructOf([]reflect.StructField{{Name: "MyInt", Type: reflect.TypeOf(MyInt(0)), Anonymous: true}}); v := reflect.New(t).Elem(); v.Interface().(Getter).Get()`, + support: `type MyInt38 int; func (i MyInt38) Get() int { return int(i) }; type Getter38 interface { Get() int }`, + body: `t := reflect.StructOf([]reflect.StructField{{Name: "MyInt38", Type: reflect.TypeOf(MyInt38(0)), Anonymous: true}}); v := reflect.New(t).Elem(); v.Interface().(Getter38).Get()`, fail: false, }, } func TestPointerChecks(t *testing.T) { + dir, exe := buildPtrTests(t) + + // We (TestPointerChecks) return before the parallel subtest functions do, + // so we can't just defer os.RemoveAll(dir). Instead we have to wait for + // the parallel subtests to finish. This code looks racy but is not: + // the add +1 run in serial before testOne blocks. The -1 run in parallel + // after testOne finishes. + var pending int32 for _, pt := range ptrTests { pt := pt t.Run(pt.name, func(t *testing.T) { - testOne(t, pt) + atomic.AddInt32(&pending, +1) + defer func() { + if atomic.AddInt32(&pending, -1) == 0 { + println("removing", dir) + os.RemoveAll(dir) + } + }() + testOne(t, pt, exe) }) } } -func testOne(t *testing.T, pt ptrTest) { - t.Parallel() - - gopath, err := ioutil.TempDir("", filepath.Base(t.Name())) - if err != nil { - t.Fatal(err) +func buildPtrTests(t *testing.T) (dir, exe string) { + var gopath string + if *tmp != "" { + gopath = *tmp + dir = "" + } else { + d, err := ioutil.TempDir("", filepath.Base(t.Name())) + if err != nil { + t.Fatal(err) + } + dir = d + gopath = d } - defer os.RemoveAll(gopath) src := filepath.Join(gopath, "src", "ptrtest") if err := os.MkdirAll(src, 0777); err != nil { t.Fatal(err) } - name := filepath.Join(src, fmt.Sprintf("%s.go", filepath.Base(t.Name()))) - f, err := os.Create(name) - if err != nil { - t.Fatal(err) - } + // Prepare two cgo inputs: one for standard cgo and one for //export cgo. + // (The latter cannot have C definitions, only declarations.) + var cgo1, cgo2 bytes.Buffer + fmt.Fprintf(&cgo1, "package main\n\n/*\n") + fmt.Fprintf(&cgo2, "package main\n\n/*\n") - b := bufio.NewWriter(f) - fmt.Fprintln(b, `package main`) - fmt.Fprintln(b) - fmt.Fprintln(b, `/*`) - fmt.Fprintln(b, pt.c) - fmt.Fprintln(b, `*/`) - fmt.Fprintln(b, `import "C"`) - fmt.Fprintln(b) - for _, imp := range pt.imports { - fmt.Fprintln(b, `import "`+imp+`"`) + // C code + for _, pt := range ptrTests { + cgo := &cgo1 + if strings.Contains(pt.support, "//export") { + cgo = &cgo2 + } + fmt.Fprintf(cgo, "%s\n", pt.c) + fmt.Fprintf(&cgo1, "%s\n", pt.c1) } - if len(pt.imports) > 0 { - fmt.Fprintln(b) - } - if len(pt.support) > 0 { - fmt.Fprintln(b, pt.support) - fmt.Fprintln(b) - } - fmt.Fprintln(b, `func main() {`) - fmt.Fprintln(b, pt.body) - fmt.Fprintln(b, `}`) + fmt.Fprintf(&cgo1, "*/\nimport \"C\"\n\n") + fmt.Fprintf(&cgo2, "*/\nimport \"C\"\n\n") - if err := b.Flush(); err != nil { - t.Fatalf("flushing %s: %v", name, err) - } - if err := f.Close(); err != nil { - t.Fatalf("closing %s: %v", name, err) - } + // Imports + did1 := make(map[string]bool) + did2 := make(map[string]bool) + did1["os"] = true // for ptrTestMain + fmt.Fprintf(&cgo1, "import \"os\"\n") - for _, e := range pt.extra { - if err := ioutil.WriteFile(filepath.Join(src, e.name), []byte(e.contents), 0644); err != nil { - t.Fatalf("writing %s: %v", e.name, err) + for _, pt := range ptrTests { + did := did1 + cgo := &cgo1 + if strings.Contains(pt.support, "//export") { + did = did2 + cgo = &cgo2 + } + for _, imp := range pt.imports { + if !did[imp] { + did[imp] = true + fmt.Fprintf(cgo, "import %q\n", imp) + } } } - gomod := fmt.Sprintf("module %s\n", filepath.Base(src)) - if err := ioutil.WriteFile(filepath.Join(src, "go.mod"), []byte(gomod), 0666); err != nil { - t.Fatalf("writing go.mod: %v", err) + // Func support and bodies. + for _, pt := range ptrTests { + cgo := &cgo1 + if strings.Contains(pt.support, "//export") { + cgo = &cgo2 + } + fmt.Fprintf(cgo, "%s\nfunc %s() {\n%s\n}\n", pt.support, pt.name, pt.body) } - args := func(cmd *exec.Cmd) string { - return strings.Join(cmd.Args, " ") + // Func list and main dispatch. + fmt.Fprintf(&cgo1, "var funcs = map[string]func() {\n") + for _, pt := range ptrTests { + fmt.Fprintf(&cgo1, "\t%q: %s,\n", pt.name, pt.name) + } + fmt.Fprintf(&cgo1, "}\n\n") + fmt.Fprintf(&cgo1, "%s\n", ptrTestMain) + + if err := ioutil.WriteFile(filepath.Join(src, "cgo1.go"), cgo1.Bytes(), 0666); err != nil { + t.Fatal(err) + } + if err := ioutil.WriteFile(filepath.Join(src, "cgo2.go"), cgo2.Bytes(), 0666); err != nil { + t.Fatal(err) } - cmd := exec.Command("go", "build") + cmd := exec.Command("go", "build", "-o", "ptrtest.exe") cmd.Dir = src cmd.Env = append(os.Environ(), "GOPATH="+gopath) - buf, err := cmd.CombinedOutput() + out, err := cmd.CombinedOutput() if err != nil { - t.Logf("%#q:\n%s", args(cmd), buf) - t.Fatalf("failed to build: %v", err) + t.Fatalf("go build: %v\n%s", err, out) } - exe := filepath.Join(src, filepath.Base(src)) - cmd = exec.Command(exe) - cmd.Dir = src + return dir, filepath.Join(src, "ptrtest.exe") +} + +const ptrTestMain = ` +func main() { + for _, arg := range os.Args[1:] { + f := funcs[arg] + if f == nil { + panic("missing func "+arg) + } + f() + } +} +` + +func testOne(t *testing.T, pt ptrTest, exe string) { + t.Parallel() + + newcmd := func(cgocheck string) *exec.Cmd { + cmd := exec.Command(exe, pt.name) + cmd.Env = append(os.Environ(), "GODEBUG=cgocheck="+cgocheck) + return cmd + } if pt.expensive { - cmd.Env = cgocheckEnv("1") + cmd := newcmd("1") buf, err := cmd.CombinedOutput() if err != nil { - t.Logf("%#q:\n%s", args(cmd), buf) + t.Logf("%s", buf) if pt.fail { t.Fatalf("test marked expensive, but failed when not expensive: %v", err) } else { @@ -524,54 +575,45 @@ func testOne(t *testing.T, pt ptrTest) { } } - cmd = exec.Command(exe) - cmd.Dir = src } + cmd := newcmd("") if pt.expensive { - cmd.Env = cgocheckEnv("2") + cmd = newcmd("2") } - buf, err = cmd.CombinedOutput() + buf, err := cmd.CombinedOutput() if pt.fail { if err == nil { - t.Logf("%#q:\n%s", args(cmd), buf) + t.Logf("%s", buf) t.Fatalf("did not fail as expected") } else if !bytes.Contains(buf, []byte("Go pointer")) { - t.Logf("%#q:\n%s", args(cmd), buf) + t.Logf("%s", buf) t.Fatalf("did not print expected error (failed with %v)", err) } } else { if err != nil { - t.Logf("%#q:\n%s", args(cmd), buf) + t.Logf("%s", buf) t.Fatalf("failed unexpectedly: %v", err) } if !pt.expensive { // Make sure it passes with the expensive checks. - cmd := exec.Command(exe) - cmd.Dir = src - cmd.Env = cgocheckEnv("2") + cmd := newcmd("2") buf, err := cmd.CombinedOutput() if err != nil { - t.Logf("%#q:\n%s", args(cmd), buf) + t.Logf("%s", buf) t.Fatalf("failed unexpectedly with expensive checks: %v", err) } } } if pt.fail { - cmd = exec.Command(exe) - cmd.Dir = src - cmd.Env = cgocheckEnv("0") + cmd := newcmd("0") buf, err := cmd.CombinedOutput() if err != nil { - t.Logf("%#q:\n%s", args(cmd), buf) + t.Logf("%s", buf) t.Fatalf("failed unexpectedly with GODEBUG=cgocheck=0: %v", err) } } } - -func cgocheckEnv(val string) []string { - return append(os.Environ(), "GODEBUG=cgocheck="+val) -} diff --git a/misc/cgo/errors/testdata/err1.go b/misc/cgo/errors/testdata/err1.go index 2c232cf58a..ced7443599 100644 --- a/misc/cgo/errors/testdata/err1.go +++ b/misc/cgo/errors/testdata/err1.go @@ -10,6 +10,10 @@ package main void test() { xxx; // ERROR HERE } + +// Issue 8442. Cgo output unhelpful error messages for +// invalid C preambles. +void issue8442foo(UNDEF*); // ERROR HERE */ import "C" diff --git a/misc/cgo/errors/testdata/err2.go b/misc/cgo/errors/testdata/err2.go index 3ab410bbaa..1d22401aee 100644 --- a/misc/cgo/errors/testdata/err2.go +++ b/misc/cgo/errors/testdata/err2.go @@ -4,10 +4,99 @@ package main +/* +#include + +typedef struct foo foo_t; +typedef struct bar bar_t; + +foo_t *foop; + +long double x = 0; + +static int transform(int x) { return x; } + +typedef void v; +void F(v** p) {} + +void fvi(void *p, int x) {} + +void fppi(int** p) {} + +int i; +void fi(int i) {} +*/ import "C" +import ( + "unsafe" +) func main() { s := "" _ = s C.malloc(s) // ERROR HERE + + x := (*C.bar_t)(nil) + C.foop = x // ERROR HERE + + // issue 13129: used to output error about C.unsignedshort with CC=clang + var x C.ushort + x = int(0) // ERROR HERE: C\.ushort + + // issue 13423 + _ = C.fopen() // ERROR HERE + + // issue 13467 + var x rune = '✈' + var _ rune = C.transform(x) // ERROR HERE: C\.int + + // issue 13635: used to output error about C.unsignedchar. + // This test tests all such types. + var ( + _ C.uchar = "uc" // ERROR HERE: C\.uchar + _ C.schar = "sc" // ERROR HERE: C\.schar + _ C.ushort = "us" // ERROR HERE: C\.ushort + _ C.uint = "ui" // ERROR HERE: C\.uint + _ C.ulong = "ul" // ERROR HERE: C\.ulong + _ C.longlong = "ll" // ERROR HERE: C\.longlong + _ C.ulonglong = "ull" // ERROR HERE: C\.ulonglong + _ C.complexfloat = "cf" // ERROR HERE: C\.complexfloat + _ C.complexdouble = "cd" // ERROR HERE: C\.complexdouble + ) + + // issue 13830 + // cgo converts C void* to Go unsafe.Pointer, so despite appearances C + // void** is Go *unsafe.Pointer. This test verifies that we detect the + // problem at build time. + { + type v [0]byte + + f := func(p **v) { + C.F((**C.v)(unsafe.Pointer(p))) // ERROR HERE + } + var p *v + f(&p) + } + + // issue 16116 + _ = C.fvi(1) // ERROR HERE + + // Issue 16591: Test that we detect an invalid call that was being + // hidden by a type conversion inserted by cgo checking. + { + type x *C.int + var p *x + C.fppi(p) // ERROR HERE + } + + // issue 26745 + _ = func(i int) int { + return C.i + 1 // ERROR HERE: :13 + } + _ = func(i int) { + C.fi(i) // ERROR HERE: :6 + } + + C.fi = C.fi // ERROR HERE + } diff --git a/misc/cgo/errors/testdata/err3.go b/misc/cgo/errors/testdata/err3.go deleted file mode 100644 index 609e1a0b74..0000000000 --- a/misc/cgo/errors/testdata/err3.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -/* -typedef struct foo foo_t; -typedef struct bar bar_t; - -foo_t *foop; -*/ -import "C" - -func main() { - x := (*C.bar_t)(nil) - C.foop = x // ERROR HERE -} diff --git a/misc/cgo/errors/testdata/issue13129.go b/misc/cgo/errors/testdata/issue13129.go deleted file mode 100644 index 057bce4b82..0000000000 --- a/misc/cgo/errors/testdata/issue13129.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// issue 13129: used to output error about C.unsignedshort with CC=clang - -package main - -import "C" - -func main() { - var x C.ushort - x = int(0) // ERROR HERE: C\.ushort -} diff --git a/misc/cgo/errors/testdata/issue13423.go b/misc/cgo/errors/testdata/issue13423.go deleted file mode 100644 index fc19157237..0000000000 --- a/misc/cgo/errors/testdata/issue13423.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// #include -import "C" - -func main() { - _ = C.fopen() // ERROR HERE -} diff --git a/misc/cgo/errors/testdata/issue13467.go b/misc/cgo/errors/testdata/issue13467.go deleted file mode 100644 index e061880dda..0000000000 --- a/misc/cgo/errors/testdata/issue13467.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package p - -/* -static int transform(int x) { return x; } -*/ -import "C" - -func F() { - var x rune = '✈' - var _ rune = C.transform(x) // ERROR HERE: C\.int -} diff --git a/misc/cgo/errors/testdata/issue13635.go b/misc/cgo/errors/testdata/issue13635.go deleted file mode 100644 index 3f38f5df4b..0000000000 --- a/misc/cgo/errors/testdata/issue13635.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// issue 13635: used to output error about C.unsignedchar. -// This test tests all such types. - -package pkg - -import "C" - -func main() { - var ( - _ C.uchar = "uc" // ERROR HERE: C\.uchar - _ C.schar = "sc" // ERROR HERE: C\.schar - _ C.ushort = "us" // ERROR HERE: C\.ushort - _ C.uint = "ui" // ERROR HERE: C\.uint - _ C.ulong = "ul" // ERROR HERE: C\.ulong - _ C.longlong = "ll" // ERROR HERE: C\.longlong - _ C.ulonglong = "ull" // ERROR HERE: C\.ulonglong - _ C.complexfloat = "cf" // ERROR HERE: C\.complexfloat - _ C.complexdouble = "cd" // ERROR HERE: C\.complexdouble - ) -} diff --git a/misc/cgo/errors/testdata/issue13830.go b/misc/cgo/errors/testdata/issue13830.go deleted file mode 100644 index ac20c82b81..0000000000 --- a/misc/cgo/errors/testdata/issue13830.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2016 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. - -// cgo converts C void* to Go unsafe.Pointer, so despite appearances C -// void** is Go *unsafe.Pointer. This test verifies that we detect the -// problem at build time. - -package main - -// typedef void v; -// void F(v** p) {} -import "C" - -import "unsafe" - -type v [0]byte - -func f(p **v) { - C.F((**C.v)(unsafe.Pointer(p))) // ERROR HERE -} - -func main() { - var p *v - f(&p) -} diff --git a/misc/cgo/errors/testdata/issue16116.go b/misc/cgo/errors/testdata/issue16116.go deleted file mode 100644 index 1e01cab844..0000000000 --- a/misc/cgo/errors/testdata/issue16116.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2016 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 - -// void f(void *p, int x) {} -import "C" - -func main() { - _ = C.f(1) // ERROR HERE -} diff --git a/misc/cgo/errors/testdata/issue16591.go b/misc/cgo/errors/testdata/issue16591.go deleted file mode 100644 index 10eb8403cf..0000000000 --- a/misc/cgo/errors/testdata/issue16591.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2016 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. - -// Issue 16591: Test that we detect an invalid call that was being -// hidden by a type conversion inserted by cgo checking. - -package p - -// void f(int** p) { } -import "C" - -type x *C.int - -func F(p *x) { - C.f(p) // ERROR HERE -} diff --git a/misc/cgo/errors/testdata/issue26745.go b/misc/cgo/errors/testdata/issue26745.go deleted file mode 100644 index 0e224538db..0000000000 --- a/misc/cgo/errors/testdata/issue26745.go +++ /dev/null @@ -1,17 +0,0 @@ -// 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 main - -// int a; -// void CF(int i) {} -import "C" - -func F1(i int) int { - return C.a + 1 // ERROR HERE: :13 -} - -func F2(i int) { - C.CF(i) // ERROR HERE: :6 -} diff --git a/misc/cgo/errors/testdata/issue7757.go b/misc/cgo/errors/testdata/issue7757.go deleted file mode 100644 index 0426e9fb7e..0000000000 --- a/misc/cgo/errors/testdata/issue7757.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -/* -void foo() {} -*/ -import "C" - -func main() { - C.foo = C.foo // ERROR HERE -} diff --git a/misc/cgo/errors/testdata/issue8442.go b/misc/cgo/errors/testdata/issue8442.go deleted file mode 100644 index 60477ad345..0000000000 --- a/misc/cgo/errors/testdata/issue8442.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// Issue 8442. Cgo output unhelpful error messages for -// invalid C preambles. - -/* -void issue8442foo(UNDEF*); // ERROR HERE -*/ -import "C" - -func main() { - C.issue8442foo(nil) -} From 02fe6ba95867b3858d62958ce487a47798bef1b5 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 21 May 2019 08:24:27 -0400 Subject: [PATCH 26/50] all: remove PEM-encoded private keys from tests Gerrit is complaining about pushes that affect these files and forcing people to use -o nokeycheck, which defeats the point of the check. Hide the keys from this kind of scan by marking them explicitly as testing keys. This is a little annoying but better than training everyone who ever edits one of these test files to reflexively override the Gerrit check. The only remaining keys explicitly marked as private instead of testing are in examples, and there's not much to do about those. Hopefully they are not edited as much. Change-Id: I4431592b5266cb39fe6a80b40e742d97da803a0b Reviewed-on: https://go-review.googlesource.com/c/go/+/178178 Run-TryBot: Russ Cox TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- src/crypto/rsa/pkcs1v15_test.go | 6 ++-- src/crypto/tls/handshake_server_test.go | 22 ++++++------- src/crypto/tls/tls_test.go | 22 +++++++------ src/crypto/x509/pem_decrypt_test.go | 44 +++++++++++++------------ src/crypto/x509/x509_test.go | 12 +++---- src/crypto/x509/x509_test_import.go | 9 +++-- src/encoding/pem/pem_test.go | 36 ++++++++++---------- src/net/http/internal/testcert.go | 8 +++-- src/net/smtp/smtp_test.go | 8 +++-- 9 files changed, 91 insertions(+), 76 deletions(-) diff --git a/src/crypto/rsa/pkcs1v15_test.go b/src/crypto/rsa/pkcs1v15_test.go index 47444f311c..7e62560a04 100644 --- a/src/crypto/rsa/pkcs1v15_test.go +++ b/src/crypto/rsa/pkcs1v15_test.go @@ -274,8 +274,8 @@ func TestShortSessionKey(t *testing.T) { } } -// In order to generate new test vectors you'll need the PEM form of this key: -// -----BEGIN RSA PRIVATE KEY----- +// In order to generate new test vectors you'll need the PEM form of this key (and s/TESTING/PRIVATE/): +// -----BEGIN RSA TESTING KEY----- // MIIBOgIBAAJBALKZD0nEffqM1ACuak0bijtqE2QrI/KLADv7l3kK3ppMyCuLKoF0 // fd7Ai2KW5ToIwzFofvJcS/STa6HA5gQenRUCAwEAAQJBAIq9amn00aS0h/CrjXqu // /ThglAXJmZhOMPVn4eiu7/ROixi9sex436MaVeMqSNf7Ex9a8fRNfWss7Sqd9eWu @@ -283,7 +283,7 @@ func TestShortSessionKey(t *testing.T) { // EO+ZJ79TJKN5yiGBRsv5yvx5UiHxajEXAiAhAol5N4EUyq6I9w1rYdhPMGpLfk7A // IU2snfRJ6Nq2CQIgFrPsWRCkV+gOYcajD17rEqmuLrdIRexpg8N1DOSXoJ8CIGlS // tAboUGBxTDq3ZroNism3DaMIbKPyYrAqhKov1h5V -// -----END RSA PRIVATE KEY----- +// -----END RSA TESTING KEY----- var rsaPrivateKey = &PrivateKey{ PublicKey: PublicKey{ diff --git a/src/crypto/tls/handshake_server_test.go b/src/crypto/tls/handshake_server_test.go index 131de0f2fc..843a0a70f0 100644 --- a/src/crypto/tls/handshake_server_test.go +++ b/src/crypto/tls/handshake_server_test.go @@ -1351,8 +1351,8 @@ o0RIvFkTgxYEiKSBXCUNmAysEbEoVr4dzWFihAm/1oDGRY2CLLTYg5vbySK3KhIR e/oCO8HJ/+rJnahJ05XX1Q7lNQ== -----END CERTIFICATE-----` -const clientKeyPEM = ` ------BEGIN RSA PRIVATE KEY----- +var clientKeyPEM = testingKey(` +-----BEGIN RSA TESTING KEY----- MIICXQIBAAKBgQC6b6qGvc+/n/LvXJRgeG/oE/LRlm/N2TJuIjfOQfnKXSms4Sfa YaLugcsQx980WJWG6T0Z5lwnc2DIjXgC9B2kmAmjGXBpPCViZiqrIiPFe4U4Ty4J czKnvT6brcqEB+YPOv93xZ1BhQCKtpvusKQ/LUxM5kI+u1HI3UhU9AyORwIDAQAB @@ -1366,7 +1366,7 @@ jUCVJzJA5ORJrn8g64u2eGK28z/LFQbv9wXgCwfc72R468BdawFSLa/m2EECQGbZ rWiFla26IVXV0xcD98VWJsTBZMlgPnSOqoMdM1kSEd4fUmlAYI/dFzV1XYSkOmVr FhdZnklmpVDeu27P4c0CQQCuCOup0FlJSBpWY1TTfun/KMBkBatMz0VMA3d7FKIU csPezl677Yjo8u1r/KzeI6zLg87Z8E6r6ZWNc9wBSZK6 ------END RSA PRIVATE KEY-----` +-----END RSA TESTING KEY-----`) const clientECDSACertificatePEM = ` -----BEGIN CERTIFICATE----- @@ -1383,17 +1383,17 @@ C3JosDJdYUoCdFzCgbkWqD8pyDbHgf9stlvZcPE4O1BIKJTLCRpS8V3ujfK58PDa jWVim34BmT0Y9hCaOGGbLlfk+syxis7iI6CH8OFnUes= -----END CERTIFICATE-----` -const clientECDSAKeyPEM = ` +var clientECDSAKeyPEM = testingKey(` -----BEGIN EC PARAMETERS----- BgUrgQQAIw== -----END EC PARAMETERS----- ------BEGIN EC PRIVATE KEY----- +-----BEGIN EC TESTING KEY----- MIHcAgEBBEIBkJN9X4IqZIguiEVKMqeBUP5xtRsEv4HJEtOpOGLELwO53SD78Ew8 k+wLWoqizS3NpQyMtrU8JFdWfj+C57UNkOugBwYFK4EEACOhgYkDgYYABACVjJF1 FMBexFe01MNvja5oHt1vzobhfm6ySD6B5U7ixohLZNz1MLvT/2XMW/TdtWo+PtAd 3kfDdq0Z9kUsjLzYHQFMH3CQRnZIi4+DzEpcj0B22uCJ7B0rxE4wdihBsmKo+1vx +U56jb0JuK7qixgnTy5w/hOWusPTQBbNZU6sER7m8Q== ------END EC PRIVATE KEY-----` +-----END EC TESTING KEY-----`) const clientEd25519CertificatePEM = ` -----BEGIN CERTIFICATE----- @@ -1406,10 +1406,10 @@ QQD8GRcqlKUx+inILn9boF2KTjRAOdazENwZ/qAicbP1j6FYDc308YUkv+Y9FN/f 7Q7hF9gRomDQijcjKsJGqjoI -----END CERTIFICATE-----` -const clientEd25519KeyPEM = ` ------BEGIN PRIVATE KEY----- +var clientEd25519KeyPEM = testingKey(` +-----BEGIN TESTING KEY----- MC4CAQAwBQYDK2VwBCIEINifzf07d9qx3d44e0FSbV4mC/xQxT644RRbpgNpin7I ------END PRIVATE KEY-----` +-----END TESTING KEY-----`) func TestClientAuth(t *testing.T) { var certPath, keyPath, ecdsaCertPath, ecdsaKeyPath, ed25519CertPath, ed25519KeyPath string @@ -1761,7 +1761,7 @@ nIPhKls4T0hFoLvjJnXpAgMBAAGjTTBLMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUE DDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMBYGA1UdEQQPMA2CC2V4YW1wbGUu Y29tMA0GCSqGSIb3DQEBCwUAA0EAxDuUS+BrrS3c+h+k+fQPOmOScy6yTX9mHw0Q KbucGamXYEy0URIwOdO0tQ3LHPc1YGvYSPwkDjkjqECs2Vm/AA== ------END CERTIFICATE-----`), []byte(`-----BEGIN RSA PRIVATE KEY----- +-----END CERTIFICATE-----`), []byte(testingKey(`-----BEGIN RSA TESTING KEY----- MIIBOgIBAAJBAN17PWsVQPBrHYdPFtycVQ/0CFyAQYwdVXaefhVURYUkHojwL82T HRfLJCWuYVgHMRCcg+EqWzhPSEWgu+MmdekCAwEAAQJBALjQYNTdXF4CFBbXwUz/ yt9QFDYT9B5WT/12jeGAe653gtYS6OOi/+eAkGmzg1GlRnw6fOfn+HYNFDORST7z @@ -1769,7 +1769,7 @@ yt9QFDYT9B5WT/12jeGAe653gtYS6OOi/+eAkGmzg1GlRnw6fOfn+HYNFDORST7z nKpbtU22+PbIMSJ+e80fmY9LIPx5N4HTAiAthGSimMR9bloz0EY3GyuUEyqoDgMd hXxjuno2WesoJQIgemilbcALXpxsLmZLgcQ2KSmaVr7jb5ECx9R+hYKTw1sCIG4s T+E0J8wlH24pgwQHzy7Ko2qLwn1b5PW8ecrlvP1g ------END RSA PRIVATE KEY-----`)) +-----END RSA TESTING KEY-----`))) if err != nil { t.Fatal(err) } diff --git a/src/crypto/tls/tls_test.go b/src/crypto/tls/tls_test.go index df39509a6d..a07727c92b 100644 --- a/src/crypto/tls/tls_test.go +++ b/src/crypto/tls/tls_test.go @@ -37,7 +37,7 @@ r5QuVbpQhH6u+0UgcW0jp9QwpxoPTLTWGXEWBBBurxFwiCBhkQ+V -----END CERTIFICATE----- ` -var rsaKeyPEM = `-----BEGIN RSA PRIVATE KEY----- +var rsaKeyPEM = testingKey(`-----BEGIN RSA TESTING KEY----- MIIBOwIBAAJBANLJhPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wo k/4xIA+ui35/MmNartNuC+BdZ1tMuVCPFZcCAwEAAQJAEJ2N+zsR0Xn8/Q6twa4G 6OB1M1WO+k+ztnX/1SvNeWu8D6GImtupLTYgjZcHufykj09jiHmjHx8u8ZZB/o1N @@ -45,12 +45,12 @@ MQIhAPW+eyZo7ay3lMz1V01WVjNKK9QSn1MJlb06h/LuYv9FAiEA25WPedKgVyCW SmUwbPw8fnTcpqDWE3yTO3vKcebqMSsCIBF3UmVue8YU3jybC3NxuXq3wNm34R8T xVLHwDXh/6NJAiEAl2oHGGLz64BuAfjKrqwz7qMYr9HCLIe/YsoWq/olzScCIQDi D2lWusoe2/nEqfDVVWGWlyJ7yOmqaVm/iNUN9B2N2g== ------END RSA PRIVATE KEY----- -` +-----END RSA TESTING KEY----- +`) // keyPEM is the same as rsaKeyPEM, but declares itself as just // "PRIVATE KEY", not "RSA PRIVATE KEY". https://golang.org/issue/4477 -var keyPEM = `-----BEGIN PRIVATE KEY----- +var keyPEM = testingKey(`-----BEGIN TESTING KEY----- MIIBOwIBAAJBANLJhPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wo k/4xIA+ui35/MmNartNuC+BdZ1tMuVCPFZcCAwEAAQJAEJ2N+zsR0Xn8/Q6twa4G 6OB1M1WO+k+ztnX/1SvNeWu8D6GImtupLTYgjZcHufykj09jiHmjHx8u8ZZB/o1N @@ -58,8 +58,8 @@ MQIhAPW+eyZo7ay3lMz1V01WVjNKK9QSn1MJlb06h/LuYv9FAiEA25WPedKgVyCW SmUwbPw8fnTcpqDWE3yTO3vKcebqMSsCIBF3UmVue8YU3jybC3NxuXq3wNm34R8T xVLHwDXh/6NJAiEAl2oHGGLz64BuAfjKrqwz7qMYr9HCLIe/YsoWq/olzScCIQDi D2lWusoe2/nEqfDVVWGWlyJ7yOmqaVm/iNUN9B2N2g== ------END PRIVATE KEY----- -` +-----END TESTING KEY----- +`) var ecdsaCertPEM = `-----BEGIN CERTIFICATE----- MIIB/jCCAWICCQDscdUxw16XFDAJBgcqhkjOPQQBMEUxCzAJBgNVBAYTAkFVMRMw @@ -76,17 +76,17 @@ H5jBImIxPL4WxQNiBTexAkF8D1EtpYuWdlVQ80/h/f4pBcGiXPqX5h2PQSQY7hP1 -----END CERTIFICATE----- ` -var ecdsaKeyPEM = `-----BEGIN EC PARAMETERS----- +var ecdsaKeyPEM = testingKey(`-----BEGIN EC PARAMETERS----- BgUrgQQAIw== -----END EC PARAMETERS----- ------BEGIN EC PRIVATE KEY----- +-----BEGIN EC TESTING KEY----- MIHcAgEBBEIBrsoKp0oqcv6/JovJJDoDVSGWdirrkgCWxrprGlzB9o0X8fV675X0 NwuBenXFfeZvVcwluO7/Q9wkYoPd/t3jGImgBwYFK4EEACOhgYkDgYYABAFj36bL 06h5JRGUNB1X/Hwuw64uKW2GGJLVPPhoYMcg/ALWaW+d/t+DmV5xikwKssuFq4Bz VQldyCXTXGgu7OC0AQCC/Y/+ODK3NFKlRi+AsG3VQDSV4tgHLqZBBus0S6pPcg1q kohxS/xfFg/TEwRSSws+roJr4JFKpO2t3/be5OdqmQ== ------END EC PRIVATE KEY----- -` +-----END EC TESTING KEY----- +`) var keyPairTests = []struct { algo string @@ -1142,3 +1142,5 @@ func TestBuildNameToCertificate_doesntModifyCertificates(t *testing.T) { t.Fatalf("Certificates were mutated by BuildNameToCertificate\nGot: %#v\nWant: %#v\n", got, want) } } + +func testingKey(s string) string { return strings.ReplaceAll(s, "TESTING KEY", "PRIVATE KEY") } diff --git a/src/crypto/x509/pem_decrypt_test.go b/src/crypto/x509/pem_decrypt_test.go index 685d5ee156..dacef8b861 100644 --- a/src/crypto/x509/pem_decrypt_test.go +++ b/src/crypto/x509/pem_decrypt_test.go @@ -80,8 +80,8 @@ var testData = []struct { { kind: PEMCipherDES, password: []byte("asdf"), - pemData: []byte(` ------BEGIN RSA PRIVATE KEY----- + pemData: []byte(testingKey(` +-----BEGIN RSA TESTING KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-CBC,34F09A4FC8DE22B5 @@ -92,7 +92,7 @@ qtHb1kirfGKEtgWTF+ynyco6+2gMXNu70L7nJcnxnV/RLFkHt7AUU1yrclxz7eZz XOH9VfTjb52q/I8Suozq9coVQwg4tXfIoYUdT//O+mB7zJb9HI9Ps77b9TxDE6Gm 4C9brwZ3zg2vqXcwwV6QRZMtyll9rOpxkbw6NPlpfBqkc3xS51bbxivbO/Nve4KD r12ymjFNF4stXCfJnNqKoZ50BHmEEUDu5Wb0fpVn82XrGw7CYc4iug== ------END RSA PRIVATE KEY-----`), +-----END RSA TESTING KEY-----`)), plainDER: ` MIIBPAIBAAJBAPASZe+tCPU6p80AjHhDkVsLYa51D35e/YGa8QcZyooeZM8EHozo KD0fNiKI+53bHdy07N+81VQ8/ejPcRoXPlsCAwEAAQJBAMTxIuSq27VpR+zZ7WJf @@ -105,8 +105,8 @@ glcRgT6QCEtz2wIhANSyqaFtosIkHKqrDUGfz/bb5tqMYTAnBruVPaf/WEOBAiEA { kind: PEMCipher3DES, password: []byte("asdf"), - pemData: []byte(` ------BEGIN RSA PRIVATE KEY----- + pemData: []byte(testingKey(` +-----BEGIN RSA TESTING KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,C1F4A6A03682C2C7 @@ -117,7 +117,7 @@ Fgx5f84nT+/ovvreG+xeOzWgvtKo0UUZVrhGOgfKLpa57adumcJ6SkUuBtEFpZFB ldw5w7WC7d13x2LsRkwo8ZrDKgIV+Y9GNvhuCCkTzNP0V3gNeJpd201HZHR+9n3w 3z0VjR/MGqsfcy1ziEWMNOO53At3zlG6zP05aHMnMcZoVXadEK6L1gz++inSSDCq gI0UJP4e3JVB7AkgYymYAwiYALAkoEIuanxoc50njJk= ------END RSA PRIVATE KEY-----`), +-----END RSA TESTING KEY-----`)), plainDER: ` MIIBOwIBAAJBANOCXKdoNS/iP/MAbl9cf1/SF3P+Ns7ZeNL27CfmDh0O6Zduaax5 NBiumd2PmjkaCu7lQ5JOibHfWn+xJsc3kw0CAwEAAQJANX/W8d1Q/sCqzkuAn4xl @@ -130,8 +130,8 @@ tZZZxCtPAm7shftEib0VU77Lk8MsXJcx2C4voRsjEw==`, { kind: PEMCipherAES128, password: []byte("asdf"), - pemData: []byte(` ------BEGIN RSA PRIVATE KEY----- + pemData: []byte(testingKey(` +-----BEGIN RSA TESTING KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-128-CBC,D4492E793FC835CC038A728ED174F78A @@ -142,7 +142,7 @@ GZbBpf1jDH/pr0iGonuAdl2PCCZUiy+8eLsD2tyviHUkFLOB+ykYoJ5t8ngZ/B6D 3NbvRVvYTgs8K9EPk4K+5R+P2kD8J8KvEIGxVa1vz8QoCJ/jr7Ka2rvNgPCex5/E 080LzLHPCrXKdlr/f50yhNWq08ZxMWQFkui+FDHPDUaEELKAXV8/5PDxw80Rtybo AVYoCVIbZXZCuCO81op8UcOgEpTtyU5Lgh3Mw5scQL0= ------END RSA PRIVATE KEY-----`), +-----END RSA TESTING KEY-----`)), plainDER: ` MIIBOgIBAAJBAMBlj5FxYtqbcy8wY89d/S7n0+r5MzD9F63BA/Lpl78vQKtdJ5dT cDGh/rBt1ufRrNp0WihcmZi7Mpl/3jHjiWECAwEAAQJABNOHYnKhtDIqFYj1OAJ3 @@ -155,8 +155,8 @@ B3WlRNTXR2WsJ5JdByezg9xzdXzULqmga0OE339a`, { kind: PEMCipherAES192, password: []byte("asdf"), - pemData: []byte(` ------BEGIN RSA PRIVATE KEY----- + pemData: []byte(testingKey(` +-----BEGIN RSA TESTING KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-192-CBC,E2C9FB02BCA23ADE1829F8D8BC5F5369 @@ -167,7 +167,7 @@ Rb7tshNTMqHbCpyo9Rn3UxeFIf9efdl8YLiMoIqc7J8E5e9VlbeQSdLMQOgDAQJG ReUtTw8exmKsY4gsSjhkg5uiw7/ZB1Ihto0qnfQJgjGc680qGkT1d6JfvOfeYAk6 xn5RqS/h8rYAYm64KnepfC9vIujo4NqpaREDmaLdX5MJPQ+SlytITQvgUsUq3q/t Ss85xjQEZH3hzwjQqdJvmA4hYP6SUjxYpBM+02xZ1Xw= ------END RSA PRIVATE KEY-----`), +-----END RSA TESTING KEY-----`)), plainDER: ` MIIBOwIBAAJBAMGcRrZiNNmtF20zyS6MQ7pdGx17aFDl+lTl+qnLuJRUCMUG05xs OmxmL/O1Qlf+bnqR8Bgg65SfKg21SYuLhiMCAwEAAQJBAL94uuHyO4wux2VC+qpj @@ -180,8 +180,8 @@ uZ3pWbaXf5PNuQIgAcdXarvhelH2w2piY1g3BPeFqhzBSCK/yLGxR82KIh8CIQDD { kind: PEMCipherAES256, password: []byte("asdf"), - pemData: []byte(` ------BEGIN RSA PRIVATE KEY----- + pemData: []byte(testingKey(` +-----BEGIN RSA TESTING KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-256-CBC,8E7ED5CD731902CE938957A886A5FFBD @@ -192,7 +192,7 @@ Pz3RZScwIuubzTGJ1x8EzdffYOsdCa9Mtgpp3L136+23dOd6L/qK2EG2fzrJSHs/ 2XugkleBFSMKzEp9mxXKRfa++uidQvMZTFLDK9w5YjrRvMBo/l2BoZIsq0jAIE1N sv5Z/KwlX+3MDEpPQpUwGPlGGdLnjI3UZ+cjgqBcoMiNc6HfgbBgYJSU6aDSHuCk clCwByxWkBNgJ2GrkwNrF26v+bGJJJNR4SKouY1jQf0= ------END RSA PRIVATE KEY-----`), +-----END RSA TESTING KEY-----`)), plainDER: ` MIIBOgIBAAJBAKy3GFkstoCHIEeUU/qO8207m8WSrjksR+p9B4tf1w5k+2O1V/GY AQ5WFCApItcOkQe/I0yZZJk/PmCqMzSxrc8CAwEAAQJAOCAz0F7AW9oNelVQSP8F @@ -207,15 +207,15 @@ PXHYtPqxQIbD2pScR5qum7iGUh11lEUPkmt+2uqS`, // openssl genrsa -aes128 -passout pass:asdf -out server.orig.key 128 kind: PEMCipherAES128, password: []byte("asdf"), - pemData: []byte(` ------BEGIN RSA PRIVATE KEY----- + pemData: []byte(testingKey(` +-----BEGIN RSA TESTING KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-128-CBC,74611ABC2571AF11B1BF9B69E62C89E7 6ei/MlytjE0FFgZOGQ+jrwomKfpl8kdefeE0NSt/DMRrw8OacHAzBNi3pPEa0eX3 eND9l7C9meCirWovjj9QWVHrXyugFuDIqgdhQ8iHTgCfF3lrmcttVrbIfMDw+smD hTP8O1mS/MHl92NE0nhv0w== ------END RSA PRIVATE KEY-----`), +-----END RSA TESTING KEY-----`)), plainDER: ` MGMCAQACEQC6ssxmYuauuHGOCDAI54RdAgMBAAECEQCWIn6Yv2O+kBcDF7STctKB AgkA8SEfu/2i3g0CCQDGNlXbBHX7kQIIK3Ww5o0cYbECCQDCimPb0dYGsQIIeQ7A @@ -223,14 +223,14 @@ jryIst8=`, }, } -const incompleteBlockPEM = ` ------BEGIN RSA PRIVATE KEY----- +var incompleteBlockPEM = testingKey(` +-----BEGIN RSA TESTING KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-128-CBC,74611ABC2571AF11B1BF9B69E62C89E7 6L8yXK2MTQUWBk4ZD6OvCiYp+mXyR1594TQ1K38MxGvDw5pwcDME2Lek8RrR5fd40P2XsL2Z4KKt ai+OP1BZUetfK6AW4MiqB2FDyIdOAJ8XeWuZy21Wtsh8wPD6yYOFM/w7WZL8weX3Y0TSeG/T ------END RSA PRIVATE KEY-----` +-----END RSA TESTING KEY-----`) func TestIncompleteBlock(t *testing.T) { // incompleteBlockPEM contains ciphertext that is not a multiple of the @@ -245,3 +245,5 @@ func TestIncompleteBlock(t *testing.T) { t.Fatalf("Expected error containing %q but got: %q", expectedSubstr, e) } } + +func testingKey(s string) string { return strings.ReplaceAll(s, "TESTING KEY", "PRIVATE KEY") } diff --git a/src/crypto/x509/x509_test.go b/src/crypto/x509/x509_test.go index 7dadb77dfd..833497d275 100644 --- a/src/crypto/x509/x509_test.go +++ b/src/crypto/x509/x509_test.go @@ -112,8 +112,8 @@ FF53oIpvxe/SCOymfWq/LW849Ytv3Xwod0+wzAP8STXG4HSELS4UedPYeHJJJYcZ -----END PUBLIC KEY----- ` -var pemPrivateKey = ` ------BEGIN RSA PRIVATE KEY----- +var pemPrivateKey = testingKey(` +-----BEGIN RSA TESTING KEY----- MIICXAIBAAKBgQCxoeCUW5KJxNPxMp+KmCxKLc1Zv9Ny+4CFqcUXVUYH69L3mQ7v IWrJ9GBfcaA7BPQqUlWxWM+OCEQZH1EZNIuqRMNQVuIGCbz5UQ8w6tS0gcgdeGX7 J7jgCQ4RK3F/PuCM38QBLaHx988qG8NMc6VKErBjctCXFHQt14lerd5KpQIDAQAB @@ -127,8 +127,8 @@ MTXIvf7Wmv6E++eFcnT461FlGAUHRV+bQQXGsItR/opIG7mGogIkVXa3E1MCQARX AAA7eoZ9AEHflUeuLn9QJI/r0hyQQLEtrpwv6rDT1GCWaLII5HJ6NUFVf4TTcqxo 6vdM4QGKTJoO+SaCyP0CQFdpcxSAuzpFcKv0IlJ8XzS/cy+mweCMwyJ1PFEc4FX6 wg/HcAJWY60xZTJDFN+Qfx8ZQvBEin6c2/h+zZi5IVY= ------END RSA PRIVATE KEY----- -` +-----END RSA TESTING KEY----- +`) // pemEd25519Key is the example from RFC 8410, Secrion 4. var pemEd25519Key = ` @@ -1245,8 +1245,8 @@ func TestParsePEMCRL(t *testing.T) { func TestImports(t *testing.T) { testenv.MustHaveGoRun(t) - if err := exec.Command(testenv.GoToolPath(t), "run", "x509_test_import.go").Run(); err != nil { - t.Errorf("failed to run x509_test_import.go: %s", err) + if out, err := exec.Command(testenv.GoToolPath(t), "run", "x509_test_import.go").CombinedOutput(); err != nil { + t.Errorf("failed to run x509_test_import.go: %s\n%s", err, out) } } diff --git a/src/crypto/x509/x509_test_import.go b/src/crypto/x509/x509_test_import.go index 3fda7da188..b778df261a 100644 --- a/src/crypto/x509/x509_test_import.go +++ b/src/crypto/x509/x509_test_import.go @@ -15,6 +15,7 @@ import ( "crypto/x509/pkix" "encoding/pem" "math/big" + "strings" "time" ) @@ -41,7 +42,7 @@ func main() { } } -var pemPrivateKey = `-----BEGIN RSA PRIVATE KEY----- +var pemPrivateKey = testingKey(`-----BEGIN RSA TESTING KEY----- MIIBOgIBAAJBALKZD0nEffqM1ACuak0bijtqE2QrI/KLADv7l3kK3ppMyCuLKoF0 fd7Ai2KW5ToIwzFofvJcS/STa6HA5gQenRUCAwEAAQJBAIq9amn00aS0h/CrjXqu /ThglAXJmZhOMPVn4eiu7/ROixi9sex436MaVeMqSNf7Ex9a8fRNfWss7Sqd9eWu @@ -49,5 +50,7 @@ RTUCIQDasvGASLqmjeffBNLTXV2A5g4t+kLVCpsEIZAycV5GswIhANEPLmax0ME/ EO+ZJ79TJKN5yiGBRsv5yvx5UiHxajEXAiAhAol5N4EUyq6I9w1rYdhPMGpLfk7A IU2snfRJ6Nq2CQIgFrPsWRCkV+gOYcajD17rEqmuLrdIRexpg8N1DOSXoJ8CIGlS tAboUGBxTDq3ZroNism3DaMIbKPyYrAqhKov1h5V ------END RSA PRIVATE KEY----- -` +-----END RSA TESTING KEY----- +`) + +func testingKey(s string) string { return strings.ReplaceAll(s, "TESTING KEY", "PRIVATE KEY") } diff --git a/src/encoding/pem/pem_test.go b/src/encoding/pem/pem_test.go index 204611bda0..8515b46498 100644 --- a/src/encoding/pem/pem_test.go +++ b/src/encoding/pem/pem_test.go @@ -285,7 +285,7 @@ func BenchmarkDecode(b *testing.B) { } } -var pemData = `verify return:0 +var pemData = testingKey(`verify return:0 -----BEGIN CERTIFICATE----- sdlfkjskldfj -----BEGIN CERTIFICATE----- @@ -296,13 +296,13 @@ Certificate chain -----BEGIN CERTIFICATE----- testing -----BEGIN CERTIFICATE----- ------BEGIN CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIID6TCCA1ICAQEwDQYJKoZIhvcNAQEFBQAwgYsxCzAJBgNVBAYTAlVTMRMwEQYD VQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRQwEgYDVQQK -EwtHb29nbGUgSW5jLjEMMAoGA1UECxMDRW5nMQwwCgYDVQQDEwNhZ2wxHTAbBgkq -hkiG9w0BCQEWDmFnbEBnb29nbGUuY29tMB4XDTA5MDkwOTIyMDU0M1oXDTEwMDkw -OTIyMDU0M1owajELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAf -BgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEjMCEGA1UEAxMaZXVyb3Bh +EwtHb29nbGUgSW5jLjEMMAoGA1UECxMDRW5nMQwwCgYDVQQDEwNhZ2wxHTAbBgkq +hkiG9w0BCQEWDmFnbEBnb29nbGUuY29tMB4XDTA5MDkwOTIyMDU0M1oXDTEwMDkw +OTIyMDU0M1owajELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAf +BgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEjMCEGA1UEAxMaZXVyb3Bh LnNmby5jb3JwLmdvb2dsZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK AoICAQC6pgYt7/EibBDumASF+S0qvqdL/f+nouJw2T1Qc8GmXF/iiUcrsgzh/Fd8 pDhz/T96Qg9IyR4ztuc2MXrmPra+zAuSf5bevFReSqvpIt8Duv0HbDbcqs/XKPfB @@ -318,15 +318,15 @@ Pomjn71GNTtDeWAXibjCgdL6iHACCF6Htbl0zGlG0OAK+bdn0QIDAQABMA0GCSqG SIb3DQEBBQUAA4GBAOKnQDtqBV24vVqvesL5dnmyFpFPXBn3WdFfwD6DzEb21UVG 5krmJiu+ViipORJPGMkgoL6BjU21XI95VQbun5P8vvg8Z+FnFsvRFY3e1CCzAVQY ZsUkLw2I7zI/dNlWdB8Xp7v+3w9sX5N3J/WuJ1KOO5m26kRlHQo7EzT3974g ------END CERTIFICATE----- +-----END CERTIFICATE----- 1 s:/C=ZA/O=Ca Inc./CN=CA Inc ------BEGIN RSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: DES-EDE3-CBC,80C7C7A09690757A - +-----BEGIN RSA TESTING KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,80C7C7A09690757A + eQp5ZkH6CyHBz7BZfUPxyLCCmftsBJ7HlqGb8Ld21cSwnzWZ4/SIlhyrUtsfw7VR -2TTwA+odo9ex7GdxOTaH8oZFumIRoiEjHsk8U7Bhntp+ekkPP79xunnN7hb7hkhr +2TTwA+odo9ex7GdxOTaH8oZFumIRoiEjHsk8U7Bhntp+ekkPP79xunnN7hb7hkhr yGDQZgA7s2cQHQ71v3gwT2BACAft26jCjbM1wgNzBnJ8M0Rzn68YWqaPtdBu8qb/ zVR5JB1mnqvTSbFsfF5yMc6o2WQ9jJCl6KypnMl+BpL+dlvdjYVK4l9lYsB1Hs3d +zDBbWxos818zzhS8/y6eIfiSG27cqrbhURbmgiSfDXjncK4m/pLcQ7mmBL6mFOr @@ -338,7 +338,7 @@ BTiHcL3s3KrJu1vDVrshvxfnz71KTeNnZH8UbOqT5i7fPGyXtY1XJddcbI/Q6tXf wHFsZc20TzSdsVLBtwksUacpbDogcEVMctnNrB8FIrB3vZEv9Q0Z1VeY7nmTpF+6 a+z2P7acL7j6A6Pr3+q8P9CPiPC7zFonVzuVPyB8GchGR2hytyiOVpuD9+k8hcuw ZWAaUoVtWIQ52aKS0p19G99hhb+IVANC4akkdHV4SP8i7MVNZhfUmg== ------END RSA PRIVATE KEY----- +-----END RSA TESTING KEY----- -----BEGIN EMPTY----- @@ -363,7 +363,7 @@ Header: 1 -----BEGIN HEADERS----- Header: 1 ------END HEADERS-----` +-----END HEADERS-----`) var certificate = &Block{Type: "CERTIFICATE", Headers: map[string]string{}, @@ -582,7 +582,7 @@ var privateKey2 = &Block{ }, } -var pemPrivateKey2 = `-----BEGIN RSA PRIVATE KEY----- +var pemPrivateKey2 = testingKey(`-----BEGIN RSA TESTING KEY----- Proc-Type: 4,ENCRYPTED Content-Domain: RFC822 DEK-Info: AES-128-CBC,BFCD243FEDBB40A4AA6DDAA1335473A4 @@ -594,8 +594,8 @@ y9QEsXO5czLWesYpJaXaF5N6EOhB+6UXIPhO6eOPUSATu963k64TivYJ9KZB4CtR GjA4DbE7Z4dk9coyZ9HIpT0jcsQGr497Jqw8dZGhABPGXEnVPOeyspng1SX64hKA N4XPksobn/NO2IDvPM7N9ZCe+aeyDEkE8QmP6mPScLuGvzSrsgOxWTMWF7Dbdzj0 tJQLJRZ+ItT5Irl4owSEBNLahC1j3fhQavbj9WVAfKk= ------END RSA PRIVATE KEY----- -` +-----END RSA TESTING KEY----- +`) func TestBadEncode(t *testing.T) { b := &Block{Type: "BAD", Headers: map[string]string{"X:Y": "Z"}} @@ -610,3 +610,5 @@ func TestBadEncode(t *testing.T) { t.Fatalf("EncodeToMemory returned non-nil data") } } + +func testingKey(s string) string { return strings.ReplaceAll(s, "TESTING KEY", "PRIVATE KEY") } diff --git a/src/net/http/internal/testcert.go b/src/net/http/internal/testcert.go index 407890920f..2284a836fb 100644 --- a/src/net/http/internal/testcert.go +++ b/src/net/http/internal/testcert.go @@ -4,6 +4,8 @@ package internal +import "strings" + // LocalhostCert is a PEM-encoded TLS cert with SAN IPs // "127.0.0.1" and "[::1]", expiring at Jan 29 16:00:00 2084 GMT. // generated from src/crypto/tls: @@ -24,7 +26,7 @@ fblo6RBxUQ== -----END CERTIFICATE-----`) // LocalhostKey is the private key for localhostCert. -var LocalhostKey = []byte(`-----BEGIN RSA PRIVATE KEY----- +var LocalhostKey = []byte(testingKey(`-----BEGIN RSA TESTING KEY----- MIICXgIBAAKBgQDuLnQAI3mDgey3VBzWnB2L39JUU4txjeVE6myuDqkM/uGlfjb9 SjY1bIw4iA5sBBZzHi3z0h1YV8QPuxEbi4nW91IJm2gsvvZhIrCHS3l6afab4pZB l2+XsDulrKBxKKtD1rGxlG4LjncdabFn9gvLZad2bSysqz/qTAUStTvqJQIDAQAB @@ -38,4 +40,6 @@ fQtuUE9txblTu14q3N7gHRZB4ZMhFYyDy8CKrN2cPg/Fvyt0Xlp/DoCzjA0CQQDU y2ptGsuSmgUtWj3NM9xuwYPm+Z/F84K6+ARYiZ6PYj013sovGKUFfYAqVXVlxtIX qyUBnu3X9ps8ZfjLZO7BAkEAlT4R5Yl6cGhaJQYZHOde3JEMhNRcVFMO8dJDaFeo f9Oeos0UUothgiDktdQHxdNEwLjQf7lJJBzV+5OtwswCWA== ------END RSA PRIVATE KEY-----`) +-----END RSA TESTING KEY-----`)) + +func testingKey(s string) string { return strings.ReplaceAll(s, "TESTING KEY", "PRIVATE KEY") } diff --git a/src/net/smtp/smtp_test.go b/src/net/smtp/smtp_test.go index e366ef8015..8195f91419 100644 --- a/src/net/smtp/smtp_test.go +++ b/src/net/smtp/smtp_test.go @@ -900,8 +900,8 @@ tN8URjVmyEo= -----END CERTIFICATE-----`) // localhostKey is the private key for localhostCert. -var localhostKey = []byte(` ------BEGIN RSA PRIVATE KEY----- +var localhostKey = []byte(testingKey(` +-----BEGIN RSA TESTING KEY----- MIICXgIBAAKBgQDScVtBC45ayNsa16NylbPXnc6XOJkzhtWMn2Niu43DmfZHLq5h AB9+Gpok4icKaZxV7ayImCWzIf1pGHq8qKhsFshRddRTUAF3np5sDOW3QuhsuXHu lkQzLfQuoiL0TrOYvdi90bOliWQVGdGurAS1ZhsYF/fOc7bnRLnoIJYfZQIDAQAB @@ -915,4 +915,6 @@ vNjJu3yvoEZeIeuzouX9TJE21/33FaeDdsXbRhQEj23cqR38qFHsF1qAYNMCQQDP QXLEiJoClkR2orAmqjPLVhR3t2oB3INcnEjLNSq8LHyQEfXyaFfu4U9l5+fRPL2i jiC0k/9L5dHUsF0XZothAkEA23ddgRs+Id/HxtojqqUT27B8MT/IGNrYsp4DvS/c qgkeluku4GjxRlDMBuXk94xOBEinUs+p/hwP1Alll80Tpg== ------END RSA PRIVATE KEY-----`) +-----END RSA TESTING KEY-----`)) + +func testingKey(s string) string { return strings.ReplaceAll(s, "TESTING KEY", "PRIVATE KEY") } From 41329c07f9a4dbbd041c8ee116d7876571c846ee Mon Sep 17 00:00:00 2001 From: Filippo Valsorda Date: Mon, 20 May 2019 15:24:44 -0400 Subject: [PATCH 27/50] math/bits: document that Add, Sub, Mul, RotateLeft, ReverseBytes are constant time Fixes #31267 Change-Id: I91e4aa8cf9d797689cb9612d0fe3bf1bb3ad15a6 Reviewed-on: https://go-review.googlesource.com/c/go/+/178177 Reviewed-by: Keith Randall --- src/math/bits/bits.go | 44 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/math/bits/bits.go b/src/math/bits/bits.go index 1a85485a5a..385c0648e3 100644 --- a/src/math/bits/bits.go +++ b/src/math/bits/bits.go @@ -165,6 +165,8 @@ func OnesCount64(x uint64) int { // RotateLeft returns the value of x rotated left by (k mod UintSize) bits. // To rotate x right by k bits, call RotateLeft(x, -k). +// +// This function's execution time does not depend on the inputs. func RotateLeft(x uint, k int) uint { if UintSize == 32 { return uint(RotateLeft32(uint32(x), k)) @@ -174,6 +176,8 @@ func RotateLeft(x uint, k int) uint { // RotateLeft8 returns the value of x rotated left by (k mod 8) bits. // To rotate x right by k bits, call RotateLeft8(x, -k). +// +// This function's execution time does not depend on the inputs. func RotateLeft8(x uint8, k int) uint8 { const n = 8 s := uint(k) & (n - 1) @@ -182,6 +186,8 @@ func RotateLeft8(x uint8, k int) uint8 { // RotateLeft16 returns the value of x rotated left by (k mod 16) bits. // To rotate x right by k bits, call RotateLeft16(x, -k). +// +// This function's execution time does not depend on the inputs. func RotateLeft16(x uint16, k int) uint16 { const n = 16 s := uint(k) & (n - 1) @@ -190,6 +196,8 @@ func RotateLeft16(x uint16, k int) uint16 { // RotateLeft32 returns the value of x rotated left by (k mod 32) bits. // To rotate x right by k bits, call RotateLeft32(x, -k). +// +// This function's execution time does not depend on the inputs. func RotateLeft32(x uint32, k int) uint32 { const n = 32 s := uint(k) & (n - 1) @@ -198,6 +206,8 @@ func RotateLeft32(x uint32, k int) uint32 { // RotateLeft64 returns the value of x rotated left by (k mod 64) bits. // To rotate x right by k bits, call RotateLeft64(x, -k). +// +// This function's execution time does not depend on the inputs. func RotateLeft64(x uint64, k int) uint64 { const n = 64 s := uint(k) & (n - 1) @@ -245,6 +255,8 @@ func Reverse64(x uint64) uint64 { // --- ReverseBytes --- // ReverseBytes returns the value of x with its bytes in reversed order. +// +// This function's execution time does not depend on the inputs. func ReverseBytes(x uint) uint { if UintSize == 32 { return uint(ReverseBytes32(uint32(x))) @@ -253,11 +265,15 @@ func ReverseBytes(x uint) uint { } // ReverseBytes16 returns the value of x with its bytes in reversed order. +// +// This function's execution time does not depend on the inputs. func ReverseBytes16(x uint16) uint16 { return x>>8 | x<<8 } // ReverseBytes32 returns the value of x with its bytes in reversed order. +// +// This function's execution time does not depend on the inputs. func ReverseBytes32(x uint32) uint32 { const m = 1<<32 - 1 x = x>>8&(m3&m) | x&(m3&m)<<8 @@ -265,6 +281,8 @@ func ReverseBytes32(x uint32) uint32 { } // ReverseBytes64 returns the value of x with its bytes in reversed order. +// +// This function's execution time does not depend on the inputs. func ReverseBytes64(x uint64) uint64 { const m = 1<<64 - 1 x = x>>8&(m3&m) | x&(m3&m)<<8 @@ -331,6 +349,8 @@ func Len64(x uint64) (n int) { // Add returns the sum with carry of x, y and carry: sum = x + y + carry. // The carry input must be 0 or 1; otherwise the behavior is undefined. // The carryOut output is guaranteed to be 0 or 1. +// +// This function's execution time does not depend on the inputs. func Add(x, y, carry uint) (sum, carryOut uint) { if UintSize == 32 { s32, c32 := Add32(uint32(x), uint32(y), uint32(carry)) @@ -343,6 +363,8 @@ func Add(x, y, carry uint) (sum, carryOut uint) { // Add32 returns the sum with carry of x, y and carry: sum = x + y + carry. // The carry input must be 0 or 1; otherwise the behavior is undefined. // The carryOut output is guaranteed to be 0 or 1. +// +// This function's execution time does not depend on the inputs. func Add32(x, y, carry uint32) (sum, carryOut uint32) { sum64 := uint64(x) + uint64(y) + uint64(carry) sum = uint32(sum64) @@ -353,8 +375,13 @@ func Add32(x, y, carry uint32) (sum, carryOut uint32) { // Add64 returns the sum with carry of x, y and carry: sum = x + y + carry. // The carry input must be 0 or 1; otherwise the behavior is undefined. // The carryOut output is guaranteed to be 0 or 1. +// +// This function's execution time does not depend on the inputs. func Add64(x, y, carry uint64) (sum, carryOut uint64) { sum = x + y + carry + // The sum will overflow if both top bits are set (x & y) or if one of them + // is (x | y), and a carry from the lower place happened. If such a carry + // happens, the top bit will be 1 + 0 + 1 = 0 (&^ sum). carryOut = ((x & y) | ((x | y) &^ sum)) >> 63 return } @@ -364,6 +391,8 @@ func Add64(x, y, carry uint64) (sum, carryOut uint64) { // Sub returns the difference of x, y and borrow: diff = x - y - borrow. // The borrow input must be 0 or 1; otherwise the behavior is undefined. // The borrowOut output is guaranteed to be 0 or 1. +// +// This function's execution time does not depend on the inputs. func Sub(x, y, borrow uint) (diff, borrowOut uint) { if UintSize == 32 { d32, b32 := Sub32(uint32(x), uint32(y), uint32(borrow)) @@ -376,8 +405,14 @@ func Sub(x, y, borrow uint) (diff, borrowOut uint) { // Sub32 returns the difference of x, y and borrow, diff = x - y - borrow. // The borrow input must be 0 or 1; otherwise the behavior is undefined. // The borrowOut output is guaranteed to be 0 or 1. +// +// This function's execution time does not depend on the inputs. func Sub32(x, y, borrow uint32) (diff, borrowOut uint32) { diff = x - y - borrow + // The difference will underflow if the top bit of x is not set and the top + // bit of y is set (^x & y) or if they are the same (^(x ^ y)) and a borrow + // from the lower place happens. If that borrow happens, the result will be + // 1 - 1 - 1 = 0 - 0 - 1 = 1 (& diff). borrowOut = ((^x & y) | (^(x ^ y) & diff)) >> 31 return } @@ -385,8 +420,11 @@ func Sub32(x, y, borrow uint32) (diff, borrowOut uint32) { // Sub64 returns the difference of x, y and borrow: diff = x - y - borrow. // The borrow input must be 0 or 1; otherwise the behavior is undefined. // The borrowOut output is guaranteed to be 0 or 1. +// +// This function's execution time does not depend on the inputs. func Sub64(x, y, borrow uint64) (diff, borrowOut uint64) { diff = x - y - borrow + // See Sub32 for the bit logic. borrowOut = ((^x & y) | (^(x ^ y) & diff)) >> 63 return } @@ -396,6 +434,8 @@ func Sub64(x, y, borrow uint64) (diff, borrowOut uint64) { // Mul returns the full-width product of x and y: (hi, lo) = x * y // with the product bits' upper half returned in hi and the lower // half returned in lo. +// +// This function's execution time does not depend on the inputs. func Mul(x, y uint) (hi, lo uint) { if UintSize == 32 { h, l := Mul32(uint32(x), uint32(y)) @@ -408,6 +448,8 @@ func Mul(x, y uint) (hi, lo uint) { // Mul32 returns the 64-bit product of x and y: (hi, lo) = x * y // with the product bits' upper half returned in hi and the lower // half returned in lo. +// +// This function's execution time does not depend on the inputs. func Mul32(x, y uint32) (hi, lo uint32) { tmp := uint64(x) * uint64(y) hi, lo = uint32(tmp>>32), uint32(tmp) @@ -417,6 +459,8 @@ func Mul32(x, y uint32) (hi, lo uint32) { // Mul64 returns the 128-bit product of x and y: (hi, lo) = x * y // with the product bits' upper half returned in hi and the lower // half returned in lo. +// +// This function's execution time does not depend on the inputs. func Mul64(x, y uint64) (hi, lo uint64) { const mask32 = 1<<32 - 1 x0 := x & mask32 From 24b43013a12ed8bab9adcce5b8265b1fb87ff506 Mon Sep 17 00:00:00 2001 From: Damien Neil Date: Thu, 16 May 2019 09:45:56 -0700 Subject: [PATCH 28/50] errors: remove mention of Wrapper interface The Wrapper type no longer exists. Change-Id: I21051f26c6722a957295819f2f385f2bbd0db355 Reviewed-on: https://go-review.googlesource.com/c/go/+/177618 Reviewed-by: Brad Fitzpatrick --- src/errors/wrap.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/errors/wrap.go b/src/errors/wrap.go index 62332b1a88..760a08a4ef 100644 --- a/src/errors/wrap.go +++ b/src/errors/wrap.go @@ -8,8 +8,9 @@ import ( "internal/reflectlite" ) -// Unwrap returns the result of calling the Unwrap method on err, if err -// implements Wrapper. Otherwise, Unwrap returns nil. +// Unwrap returns the result of calling the Unwrap method on err, if err's +// type contains an Unwrap method returning error. +// Otherwise, Unwrap returns nil. func Unwrap(err error) error { u, ok := err.(interface { Unwrap() error From 648c7b592a30b2280e8d23419224c657ab0a8332 Mon Sep 17 00:00:00 2001 From: Keegan Carruthers-Smith Date: Tue, 7 May 2019 15:49:56 +0200 Subject: [PATCH 29/50] regexp/syntax: exclude full range from String negation case If the char class is 0x0-0x10ffff we mistakenly would String that to `[^]`, which is not a valid regex. Fixes #31807 Change-Id: I9ceeaddc28b67b8e1de12b6703bcb124cc784556 Reviewed-on: https://go-review.googlesource.com/c/go/+/175679 Reviewed-by: Brad Fitzpatrick --- src/regexp/syntax/parse_test.go | 1 + src/regexp/syntax/regexp.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/regexp/syntax/parse_test.go b/src/regexp/syntax/parse_test.go index fe3d251761..5581ba1ca5 100644 --- a/src/regexp/syntax/parse_test.go +++ b/src/regexp/syntax/parse_test.go @@ -185,6 +185,7 @@ var parseTests = []parseTest{ {`(?-s).`, `dnl{}`}, {`(?:(?:^).)`, `cat{bol{}dot{}}`}, {`(?-s)(?:(?:^).)`, `cat{bol{}dnl{}}`}, + {`[\s\S]a`, `cat{cc{0x0-0x10ffff}lit{a}}`}, // RE2 prefix_tests {`abc|abd`, `cat{str{ab}cc{0x63-0x64}}`}, diff --git a/src/regexp/syntax/regexp.go b/src/regexp/syntax/regexp.go index ae5fa053f9..3a4d2d201c 100644 --- a/src/regexp/syntax/regexp.go +++ b/src/regexp/syntax/regexp.go @@ -139,7 +139,7 @@ func writeRegexp(b *strings.Builder, re *Regexp) { b.WriteRune('[') if len(re.Rune) == 0 { b.WriteString(`^\x00-\x{10FFFF}`) - } else if re.Rune[0] == 0 && re.Rune[len(re.Rune)-1] == unicode.MaxRune { + } else if re.Rune[0] == 0 && re.Rune[len(re.Rune)-1] == unicode.MaxRune && len(re.Rune) > 2 { // Contains 0 and MaxRune. Probably a negated class. // Print the gaps. b.WriteRune('^') From 6105e8b4193401cf3344471924025c8a293c8e40 Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Tue, 21 May 2019 01:01:12 -0400 Subject: [PATCH 30/50] runtime: revert init order changes First, remove the randomization of initialization order. Then, revert to source code order instead of sorted package path order. This restores the behavior that was in 1.12. A larger change which will implement the suggestion in #31636 will wait for 1.14. It's too complicated for 1.13 at this point (it has tricky interactions with plugins). Fixes #31636 Change-Id: I35b48e8cc21cf9f93c0973edd9193d2eac197628 Reviewed-on: https://go-review.googlesource.com/c/go/+/178297 Run-TryBot: Keith Randall TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- src/cmd/compile/internal/gc/init.go | 6 ++---- src/cmd/compile/internal/types/pkg.go | 3 ++- src/runtime/proc.go | 9 --------- test/fixedbugs/issue31636.dir/a.go | 9 +++++++++ test/fixedbugs/issue31636.dir/b.go | 9 +++++++++ test/fixedbugs/issue31636.dir/c.go | 9 +++++++++ test/fixedbugs/issue31636.dir/main.go | 20 ++++++++++++++++++++ test/fixedbugs/issue31636.go | 7 +++++++ test/fixedbugs/issue31636.out | 3 +++ 9 files changed, 61 insertions(+), 14 deletions(-) create mode 100644 test/fixedbugs/issue31636.dir/a.go create mode 100644 test/fixedbugs/issue31636.dir/b.go create mode 100644 test/fixedbugs/issue31636.dir/c.go create mode 100644 test/fixedbugs/issue31636.dir/main.go create mode 100644 test/fixedbugs/issue31636.go create mode 100644 test/fixedbugs/issue31636.out diff --git a/src/cmd/compile/internal/gc/init.go b/src/cmd/compile/internal/gc/init.go index 6467aafd53..8157292216 100644 --- a/src/cmd/compile/internal/gc/init.go +++ b/src/cmd/compile/internal/gc/init.go @@ -37,10 +37,8 @@ func fninit(n []*Node) { var fns []*obj.LSym // functions to call for package initialization // Find imported packages with init tasks. - for _, p := range types.ImportedPkgList() { - if s, ok := p.LookupOK(".inittask"); ok { - deps = append(deps, s.Linksym()) - } + for _, s := range types.InitSyms { + deps = append(deps, s.Linksym()) } // Make a function that contains all the initialization statements. diff --git a/src/cmd/compile/internal/types/pkg.go b/src/cmd/compile/internal/types/pkg.go index e502b986ae..bcc6789509 100644 --- a/src/cmd/compile/internal/types/pkg.go +++ b/src/cmd/compile/internal/types/pkg.go @@ -84,6 +84,7 @@ func (pkg *Pkg) Lookup(name string) *Sym { return s } +// List of .inittask entries in imported packages, in source code order. var InitSyms []*Sym // LookupOK looks up name in pkg and reports whether it previously existed. @@ -100,7 +101,7 @@ func (pkg *Pkg) LookupOK(name string) (s *Sym, existed bool) { Name: name, Pkg: pkg, } - if name == "init" { + if name == ".inittask" { InitSyms = append(InitSyms, s) } pkg.Syms[name] = s diff --git a/src/runtime/proc.go b/src/runtime/proc.go index bf7835eb19..e9eca23138 100644 --- a/src/runtime/proc.go +++ b/src/runtime/proc.go @@ -5211,15 +5211,6 @@ func doInit(t *initTask) { throw("recursive call during initialization - linker skew") default: // not initialized yet t.state = 1 // initialization in progress - if raceenabled { - // Randomize initialization order of packages t depends on. - // TODO: enable always instead of just for race? - s := *(*[]uintptr)(unsafe.Pointer(&slice{array: add(unsafe.Pointer(t), 3*sys.PtrSize), len: int(t.ndeps), cap: int(t.ndeps)})) - for i := len(s) - 1; i > 0; i-- { - j := int(fastrandn(uint32(i + 1))) - s[i], s[j] = s[j], s[i] - } - } for i := uintptr(0); i < t.ndeps; i++ { p := add(unsafe.Pointer(t), (3+i)*sys.PtrSize) t2 := *(**initTask)(p) diff --git a/test/fixedbugs/issue31636.dir/a.go b/test/fixedbugs/issue31636.dir/a.go new file mode 100644 index 0000000000..e57e0d5fb7 --- /dev/null +++ b/test/fixedbugs/issue31636.dir/a.go @@ -0,0 +1,9 @@ +// Copyright 2019 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 a + +func init() { + println("a") +} diff --git a/test/fixedbugs/issue31636.dir/b.go b/test/fixedbugs/issue31636.dir/b.go new file mode 100644 index 0000000000..990e68209b --- /dev/null +++ b/test/fixedbugs/issue31636.dir/b.go @@ -0,0 +1,9 @@ +// Copyright 2019 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 b + +func init() { + println("b") +} diff --git a/test/fixedbugs/issue31636.dir/c.go b/test/fixedbugs/issue31636.dir/c.go new file mode 100644 index 0000000000..e53529aa59 --- /dev/null +++ b/test/fixedbugs/issue31636.dir/c.go @@ -0,0 +1,9 @@ +// Copyright 2019 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 c + +func init() { + println("c") +} diff --git a/test/fixedbugs/issue31636.dir/main.go b/test/fixedbugs/issue31636.dir/main.go new file mode 100644 index 0000000000..d8ae902c64 --- /dev/null +++ b/test/fixedbugs/issue31636.dir/main.go @@ -0,0 +1,20 @@ +// Copyright 2019 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 + +// We want the initializers of these packages to occur in source code +// order. See issue 31636. This is the behavior up to and including +// 1.13. For 1.14, we will move to a variant of lexicographic ordering +// which will require a change to the test output of this test. +import ( + _ "c" + + _ "b" + + _ "a" +) + +func main() { +} diff --git a/test/fixedbugs/issue31636.go b/test/fixedbugs/issue31636.go new file mode 100644 index 0000000000..af6f134172 --- /dev/null +++ b/test/fixedbugs/issue31636.go @@ -0,0 +1,7 @@ +// rundir + +// Copyright 2019 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 ignored diff --git a/test/fixedbugs/issue31636.out b/test/fixedbugs/issue31636.out new file mode 100644 index 0000000000..e274b2bb10 --- /dev/null +++ b/test/fixedbugs/issue31636.out @@ -0,0 +1,3 @@ +c +b +a From b0e238add5dc8ab80b4eade78ca047f074658dcd Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Wed, 15 May 2019 20:47:25 -0400 Subject: [PATCH 31/50] misc/cgo/test: consolidate tests into fewer cgo source files Each different file that does import "C" must be compiled and analyzed separately by cgo. Having fewer files import "C" reduces the cost of building the test. This is especially important because this test is built and run four different times (with different settings) during all.bash. go test -c in this directory used to take over 20 seconds on my laptop. Now it takes under 5 seconds. Removes 23.4r 29.0u 21.5s from all.bash. For #26473. Change-Id: Ie7cb7b0d9d6138ebd2eb548d0d8ea6e409ae10b9 Reviewed-on: https://go-review.googlesource.com/c/go/+/177558 Run-TryBot: Russ Cox TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick Reviewed-by: Ian Lance Taylor --- misc/cgo/test/align.go | 76 - misc/cgo/test/api.go | 30 - misc/cgo/test/basic.go | 181 -- misc/cgo/test/cflags.go | 32 - misc/cgo/test/cgo_stubs_android_test.go | 1 - misc/cgo/test/checkconst.go | 33 - misc/cgo/test/complex.go | 24 - misc/cgo/test/cthread.go | 44 - misc/cgo/test/duplicate_symbol.go | 21 - misc/cgo/test/env.go | 41 - misc/cgo/test/exports.go | 18 - misc/cgo/test/fpvar.go | 50 - misc/cgo/test/helpers.go | 35 - misc/cgo/test/issue10303.go | 76 - misc/cgo/test/issue11925.go | 37 - misc/cgo/test/issue12030.go | 35 - misc/cgo/test/issue1222.go | 29 - misc/cgo/test/issue1328.go | 30 - misc/cgo/test/issue13930.go | 13 - misc/cgo/test/issue14838.go | 37 - misc/cgo/test/issue1560.go | 50 - misc/cgo/test/issue1635.go | 38 - misc/cgo/test/issue17065.go | 29 - misc/cgo/test/issue17537.go | 58 - misc/cgo/test/issue18126.go | 26 - misc/cgo/test/issue18146.go | 2 - misc/cgo/test/issue18720.go | 54 - misc/cgo/test/issue20129.go | 33 - misc/cgo/test/issue20369.go | 20 - misc/cgo/test/issue20910.go | 19 - misc/cgo/test/issue21668.go | 13 - misc/cgo/test/issue21708.go | 16 - misc/cgo/test/issue21809.go | 45 - misc/cgo/test/issue22958.go | 24 - misc/cgo/test/issue23356.go | 19 - misc/cgo/test/issue23720.go | 22 - misc/cgo/test/issue24206.go | 54 - misc/cgo/test/issue24206_generic.go | 13 - misc/cgo/test/issue2462.go | 102 - misc/cgo/test/issue25143.go | 22 - misc/cgo/test/issue26066.go | 19 - misc/cgo/test/issue26517.go | 23 - misc/cgo/test/issue28545.go | 26 - misc/cgo/test/issue28772.go | 12 - misc/cgo/test/issue28896.go | 83 - misc/cgo/test/issue29383.go | 19 - misc/cgo/test/issue29748.go | 22 - misc/cgo/test/issue29781.go | 28 - misc/cgo/test/issue29878.go | 20 - misc/cgo/test/issue30065.go | 38 - misc/cgo/test/issue3250.go | 95 - misc/cgo/test/issue3250w.go | 11 - misc/cgo/test/issue3261.go | 49 - misc/cgo/test/issue3729.go | 47 - misc/cgo/test/issue3729w.go | 16 - misc/cgo/test/issue3741.go | 22 - misc/cgo/test/issue3775.go | 39 - misc/cgo/test/issue3945.go | 22 - misc/cgo/test/issue4054a.go | 23 - misc/cgo/test/issue4054b.go | 23 - misc/cgo/test/issue4339.go | 17 - misc/cgo/test/issue4417.go | 42 - misc/cgo/test/issue4857.go | 15 - misc/cgo/test/issue5227.go | 38 - misc/cgo/test/issue5242.go | 31 - misc/cgo/test/issue5337.go | 31 - misc/cgo/test/issue5337w.go | 11 - misc/cgo/test/issue5548.go | 27 - misc/cgo/test/issue5603.go | 32 - misc/cgo/test/issue5740.go | 15 - misc/cgo/test/issue5986.go | 33 - misc/cgo/test/issue6128.go | 20 - misc/cgo/test/issue6390.go | 23 - misc/cgo/test/issue6472.go | 22 - misc/cgo/test/issue6506.go | 36 - misc/cgo/test/issue6612.go | 90 - misc/cgo/test/issue6833.go | 27 - misc/cgo/test/issue6907.go | 33 - misc/cgo/test/issue6907export.go | 30 - misc/cgo/test/issue7560.go | 44 - misc/cgo/test/issue7665.go | 25 - misc/cgo/test/issue7786.go | 51 - misc/cgo/test/issue7978.go | 133 -- misc/cgo/test/issue8092.go | 36 - misc/cgo/test/issue8331a.go | 15 - misc/cgo/test/issue8331b.go | 13 - misc/cgo/test/issue8428.go | 55 - misc/cgo/test/issue8441.go | 27 - misc/cgo/test/issue8811.go | 22 - misc/cgo/test/issue9557.go | 36 - misc/cgo/test/test.go | 2087 +++++++++++++++++ misc/cgo/test/test22906.go | 74 - misc/cgo/test/test27660.go | 54 - .../{issue29878export.go => test_unix.go} | 9 +- .../test/{issue13402.go => test_windows.go} | 7 +- misc/cgo/test/testx.go | 542 +++++ misc/cgo/test/twoargs.go | 22 - 97 files changed, 2636 insertions(+), 3328 deletions(-) delete mode 100644 misc/cgo/test/align.go delete mode 100644 misc/cgo/test/api.go delete mode 100644 misc/cgo/test/basic.go delete mode 100644 misc/cgo/test/cflags.go delete mode 100644 misc/cgo/test/checkconst.go delete mode 100644 misc/cgo/test/complex.go delete mode 100644 misc/cgo/test/cthread.go delete mode 100644 misc/cgo/test/duplicate_symbol.go delete mode 100644 misc/cgo/test/env.go delete mode 100644 misc/cgo/test/exports.go delete mode 100644 misc/cgo/test/fpvar.go delete mode 100644 misc/cgo/test/helpers.go delete mode 100644 misc/cgo/test/issue10303.go delete mode 100644 misc/cgo/test/issue11925.go delete mode 100644 misc/cgo/test/issue12030.go delete mode 100644 misc/cgo/test/issue1222.go delete mode 100644 misc/cgo/test/issue1328.go delete mode 100644 misc/cgo/test/issue13930.go delete mode 100644 misc/cgo/test/issue14838.go delete mode 100644 misc/cgo/test/issue1560.go delete mode 100644 misc/cgo/test/issue1635.go delete mode 100644 misc/cgo/test/issue17065.go delete mode 100644 misc/cgo/test/issue17537.go delete mode 100644 misc/cgo/test/issue18126.go delete mode 100644 misc/cgo/test/issue18720.go delete mode 100644 misc/cgo/test/issue20129.go delete mode 100644 misc/cgo/test/issue20369.go delete mode 100644 misc/cgo/test/issue20910.go delete mode 100644 misc/cgo/test/issue21668.go delete mode 100644 misc/cgo/test/issue21708.go delete mode 100644 misc/cgo/test/issue21809.go delete mode 100644 misc/cgo/test/issue22958.go delete mode 100644 misc/cgo/test/issue23356.go delete mode 100644 misc/cgo/test/issue23720.go delete mode 100644 misc/cgo/test/issue24206.go delete mode 100644 misc/cgo/test/issue24206_generic.go delete mode 100644 misc/cgo/test/issue2462.go delete mode 100644 misc/cgo/test/issue25143.go delete mode 100644 misc/cgo/test/issue26066.go delete mode 100644 misc/cgo/test/issue26517.go delete mode 100644 misc/cgo/test/issue28545.go delete mode 100644 misc/cgo/test/issue28772.go delete mode 100644 misc/cgo/test/issue28896.go delete mode 100644 misc/cgo/test/issue29383.go delete mode 100644 misc/cgo/test/issue29748.go delete mode 100644 misc/cgo/test/issue29781.go delete mode 100644 misc/cgo/test/issue29878.go delete mode 100644 misc/cgo/test/issue30065.go delete mode 100644 misc/cgo/test/issue3250.go delete mode 100644 misc/cgo/test/issue3250w.go delete mode 100644 misc/cgo/test/issue3261.go delete mode 100644 misc/cgo/test/issue3729.go delete mode 100644 misc/cgo/test/issue3729w.go delete mode 100644 misc/cgo/test/issue3741.go delete mode 100644 misc/cgo/test/issue3775.go delete mode 100644 misc/cgo/test/issue3945.go delete mode 100644 misc/cgo/test/issue4054a.go delete mode 100644 misc/cgo/test/issue4054b.go delete mode 100644 misc/cgo/test/issue4339.go delete mode 100644 misc/cgo/test/issue4417.go delete mode 100644 misc/cgo/test/issue4857.go delete mode 100644 misc/cgo/test/issue5227.go delete mode 100644 misc/cgo/test/issue5242.go delete mode 100644 misc/cgo/test/issue5337.go delete mode 100644 misc/cgo/test/issue5337w.go delete mode 100644 misc/cgo/test/issue5548.go delete mode 100644 misc/cgo/test/issue5603.go delete mode 100644 misc/cgo/test/issue5740.go delete mode 100644 misc/cgo/test/issue5986.go delete mode 100644 misc/cgo/test/issue6128.go delete mode 100644 misc/cgo/test/issue6390.go delete mode 100644 misc/cgo/test/issue6472.go delete mode 100644 misc/cgo/test/issue6506.go delete mode 100644 misc/cgo/test/issue6612.go delete mode 100644 misc/cgo/test/issue6833.go delete mode 100644 misc/cgo/test/issue6907.go delete mode 100644 misc/cgo/test/issue6907export.go delete mode 100644 misc/cgo/test/issue7560.go delete mode 100644 misc/cgo/test/issue7665.go delete mode 100644 misc/cgo/test/issue7786.go delete mode 100644 misc/cgo/test/issue7978.go delete mode 100644 misc/cgo/test/issue8092.go delete mode 100644 misc/cgo/test/issue8331a.go delete mode 100644 misc/cgo/test/issue8331b.go delete mode 100644 misc/cgo/test/issue8428.go delete mode 100644 misc/cgo/test/issue8441.go delete mode 100644 misc/cgo/test/issue8811.go delete mode 100644 misc/cgo/test/issue9557.go create mode 100644 misc/cgo/test/test.go delete mode 100644 misc/cgo/test/test22906.go delete mode 100644 misc/cgo/test/test27660.go rename misc/cgo/test/{issue29878export.go => test_unix.go} (63%) rename misc/cgo/test/{issue13402.go => test_windows.go} (52%) create mode 100644 misc/cgo/test/testx.go delete mode 100644 misc/cgo/test/twoargs.go diff --git a/misc/cgo/test/align.go b/misc/cgo/test/align.go deleted file mode 100644 index a23b44fc38..0000000000 --- a/misc/cgo/test/align.go +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2010 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 cgotest - -/* -#include - -typedef unsigned char Uint8; -typedef unsigned short Uint16; - -typedef enum { - MOD1 = 0x0000, - MODX = 0x8000 -} SDLMod; - -typedef enum { - A = 1, - B = 322, - SDLK_LAST -} SDLKey; - -typedef struct SDL_keysym { - Uint8 scancode; - SDLKey sym; - SDLMod mod; - Uint16 unicode; -} SDL_keysym; - -typedef struct SDL_KeyboardEvent { - Uint8 typ; - Uint8 which; - Uint8 state; - SDL_keysym keysym; -} SDL_KeyboardEvent; - -void makeEvent(SDL_KeyboardEvent *event) { - unsigned char *p; - int i; - - p = (unsigned char*)event; - for (i=0; ityp == typ && e->which == which && e->state == state && e->keysym.scancode == scan && e->keysym.sym == sym && e->keysym.mod == mod && e->keysym.unicode == uni; -} - -void cTest(SDL_KeyboardEvent *event) { - printf("C: %#x %#x %#x %#x %#x %#x %#x\n", event->typ, event->which, event->state, - event->keysym.scancode, event->keysym.sym, event->keysym.mod, event->keysym.unicode); - fflush(stdout); -} - -*/ -import "C" - -import ( - "testing" -) - -func testAlign(t *testing.T) { - var evt C.SDL_KeyboardEvent - C.makeEvent(&evt) - if C.same(&evt, evt.typ, evt.which, evt.state, evt.keysym.scancode, evt.keysym.sym, evt.keysym.mod, evt.keysym.unicode) == 0 { - t.Error("*** bad alignment") - C.cTest(&evt) - t.Errorf("Go: %#x %#x %#x %#x %#x %#x %#x\n", - evt.typ, evt.which, evt.state, evt.keysym.scancode, - evt.keysym.sym, evt.keysym.mod, evt.keysym.unicode) - t.Error(evt) - } -} diff --git a/misc/cgo/test/api.go b/misc/cgo/test/api.go deleted file mode 100644 index d2b09cbeff..0000000000 --- a/misc/cgo/test/api.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2013 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. - -// API Compatibility Checks for cgo - -package cgotest - -// #include -// -// // Test for issue 17723. -// typedef char *cstring_pointer; -// static void cstring_pointer_fun(cstring_pointer dummy) { } -// -// const char *api_hello = "hello!"; -import "C" -import "unsafe" - -func testAPI() { - var cs *C.char - cs = C.CString("hello") - defer C.free(unsafe.Pointer(cs)) - var s string - s = C.GoString((*C.char)(C.api_hello)) - s = C.GoStringN((*C.char)(C.api_hello), C.int(6)) - var b []byte - b = C.GoBytes(unsafe.Pointer(C.api_hello), C.int(6)) - _, _ = s, b - C.cstring_pointer_fun(nil) -} diff --git a/misc/cgo/test/basic.go b/misc/cgo/test/basic.go deleted file mode 100644 index 2655a66e38..0000000000 --- a/misc/cgo/test/basic.go +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright 2010 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. - -// Basic test cases for cgo. - -package cgotest - -/* -#include -#include -#include -#include - -#define SHIFT(x, y) ((x)<<(y)) -#define KILO SHIFT(1, 10) -#define UINT32VAL 0xc008427bU - -enum E { - Enum1 = 1, - Enum2 = 2, -}; - -typedef unsigned char cgo_uuid_t[20]; - -void uuid_generate(cgo_uuid_t x) { - x[0] = 0; -} - -struct S { - int x; -}; - -const char *cstr = "abcefghijklmnopqrstuvwxyzABCEFGHIJKLMNOPQRSTUVWXYZ1234567890"; - -extern enum E myConstFunc(struct S* const ctx, int const id, struct S **const filter); - -enum E myConstFunc(struct S *const ctx, int const id, struct S **const filter) { return 0; } - -// issue 1222 -typedef union { - long align; -} xxpthread_mutex_t; - -struct ibv_async_event { - union { - int x; - } element; -}; - -struct ibv_context { - xxpthread_mutex_t mutex; -}; - -int add(int x, int y) { - return x+y; -}; -*/ -import "C" -import ( - "runtime" - "syscall" - "testing" - "unsafe" -) - -const EINVAL = C.EINVAL /* test #define */ - -var KILO = C.KILO - -func uuidgen() { - var uuid C.cgo_uuid_t - C.uuid_generate(&uuid[0]) -} - -func Strtol(s string, base int) (int, error) { - p := C.CString(s) - n, err := C.strtol(p, nil, C.int(base)) - C.free(unsafe.Pointer(p)) - return int(n), err -} - -func Atol(s string) int { - p := C.CString(s) - n := C.atol(p) - C.free(unsafe.Pointer(p)) - return int(n) -} - -func testConst(t *testing.T) { - C.myConstFunc(nil, 0, nil) -} - -func testEnum(t *testing.T) { - if C.Enum1 != 1 || C.Enum2 != 2 { - t.Error("bad enum", C.Enum1, C.Enum2) - } -} - -func testAtol(t *testing.T) { - l := Atol("123") - if l != 123 { - t.Error("Atol 123: ", l) - } -} - -func testErrno(t *testing.T) { - p := C.CString("no-such-file") - m := C.CString("r") - f, err := C.fopen(p, m) - C.free(unsafe.Pointer(p)) - C.free(unsafe.Pointer(m)) - if err == nil { - C.fclose(f) - t.Fatalf("C.fopen: should fail") - } - if err != syscall.ENOENT { - t.Fatalf("C.fopen: unexpected error: %v", err) - } -} - -func testMultipleAssign(t *testing.T) { - p := C.CString("234") - n, m := C.strtol(p, nil, 345), C.strtol(p, nil, 10) - if runtime.GOOS == "openbsd" { - // Bug in OpenBSD strtol(3) - base > 36 succeeds. - if (n != 0 && n != 239089) || m != 234 { - t.Fatal("Strtol x2: ", n, m) - } - } else if n != 0 || m != 234 { - t.Fatal("Strtol x2: ", n, m) - } - C.free(unsafe.Pointer(p)) -} - -var ( - cuint = (C.uint)(0) - culong C.ulong - cchar C.char -) - -type Context struct { - ctx *C.struct_ibv_context -} - -func benchCgoCall(b *testing.B) { - const x = C.int(2) - const y = C.int(3) - for i := 0; i < b.N; i++ { - C.add(x, y) - } -} - -var sinkString string - -func benchGoString(b *testing.B) { - for i := 0; i < b.N; i++ { - sinkString = C.GoString(C.cstr) - } - const want = "abcefghijklmnopqrstuvwxyzABCEFGHIJKLMNOPQRSTUVWXYZ1234567890" - if sinkString != want { - b.Fatalf("%q != %q", sinkString, want) - } -} - -// Issue 2470. -func testUnsignedInt(t *testing.T) { - a := (int64)(C.UINT32VAL) - b := (int64)(0xc008427b) - if a != b { - t.Errorf("Incorrect unsigned int - got %x, want %x", a, b) - } -} - -// Static (build-time) test that syntax traversal visits all operands of s[i:j:k]. -func sliceOperands(array [2000]int) { - _ = array[C.KILO:C.KILO:C.KILO] // no type error -} - -// set in cgo_thread_lock.go init -var testThreadLockFunc = func(*testing.T) {} diff --git a/misc/cgo/test/cflags.go b/misc/cgo/test/cflags.go deleted file mode 100644 index bc290bfcd5..0000000000 --- a/misc/cgo/test/cflags.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2013 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. - -// Test that the #cgo CFLAGS directive works, -// with and without platform filters. -// See https://golang.org/issue/5224 for details. -package cgotest - -/* -#cgo CFLAGS: -DCOMMON_VALUE=123 -#cgo windows CFLAGS: -DIS_WINDOWS=1 -#cgo !windows CFLAGS: -DIS_WINDOWS=0 -int common = COMMON_VALUE; -int is_windows = IS_WINDOWS; -*/ -import "C" - -import ( - "runtime" - "testing" -) - -func testCflags(t *testing.T) { - is_windows := C.is_windows == 1 - if is_windows != (runtime.GOOS == "windows") { - t.Errorf("is_windows: %v, runtime.GOOS: %s", is_windows, runtime.GOOS) - } - if C.common != 123 { - t.Errorf("common: %v (expected 123)", C.common) - } -} diff --git a/misc/cgo/test/cgo_stubs_android_test.go b/misc/cgo/test/cgo_stubs_android_test.go index 710e094cf7..a1c2482ab8 100644 --- a/misc/cgo/test/cgo_stubs_android_test.go +++ b/misc/cgo/test/cgo_stubs_android_test.go @@ -8,6 +8,5 @@ import "testing" // Stubs for tests that fails to build on Android func test6997(t *testing.T) {} -func test3775(t *testing.T) {} func test8694(t *testing.T) {} func testSigaltstack(t *testing.T) {} diff --git a/misc/cgo/test/checkconst.go b/misc/cgo/test/checkconst.go deleted file mode 100644 index 0160c1e0ce..0000000000 --- a/misc/cgo/test/checkconst.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2016 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. - -// Test a constant in conjunction with pointer checking. - -package cgotest - -/* -#include - -#define CheckConstVal 0 - -typedef struct { - int *p; -} CheckConstStruct; - -static void CheckConstFunc(CheckConstStruct *p, int e) { -} -*/ -import "C" - -import ( - "testing" - "unsafe" -) - -func testCheckConst(t *testing.T) { - // The test is that this compiles successfully. - p := C.malloc(C.size_t(unsafe.Sizeof(C.int(0)))) - defer C.free(p) - C.CheckConstFunc(&C.CheckConstStruct{(*C.int)(p)}, C.CheckConstVal) -} diff --git a/misc/cgo/test/complex.go b/misc/cgo/test/complex.go deleted file mode 100644 index ca0a97d9b3..0000000000 --- a/misc/cgo/test/complex.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2016 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 cgotest - -/* -struct { - float x; - _Complex float y; -} cplxAlign = { 3.14, 2.17 }; -*/ -import "C" - -import "testing" - -func TestComplexAlign(t *testing.T) { - if C.cplxAlign.x != 3.14 { - t.Errorf("got %v, expected 3.14", C.cplxAlign.x) - } - if C.cplxAlign.y != 2.17 { - t.Errorf("got %v, expected 2.17", C.cplxAlign.y) - } -} diff --git a/misc/cgo/test/cthread.go b/misc/cgo/test/cthread.go deleted file mode 100644 index af44911756..0000000000 --- a/misc/cgo/test/cthread.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2013 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 cgotest - -// extern void doAdd(int, int); -import "C" - -import ( - "runtime" - "sync" - "testing" -) - -var sum struct { - sync.Mutex - i int -} - -//export Add -func Add(x int) { - defer func() { - recover() - }() - sum.Lock() - sum.i += x - sum.Unlock() - var p *int - *p = 2 -} - -func testCthread(t *testing.T) { - if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") { - t.Skip("the iOS exec wrapper is unable to properly handle the panic from Add") - } - sum.i = 0 - C.doAdd(10, 6) - - want := 10 * (10 - 1) / 2 * 6 - if sum.i != want { - t.Fatalf("sum=%d, want %d", sum.i, want) - } -} diff --git a/misc/cgo/test/duplicate_symbol.go b/misc/cgo/test/duplicate_symbol.go deleted file mode 100644 index 6144271321..0000000000 --- a/misc/cgo/test/duplicate_symbol.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2010 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. - -// This file contains test cases for cgo. - -package cgotest - -/* -int base_symbol = 0; - -#define alias_one base_symbol -#define alias_two base_symbol -*/ -import "C" - -import "fmt" - -func duplicateSymbols() { - fmt.Printf("%v %v %v\n", C.base_symbol, C.alias_one, C.alias_two) -} diff --git a/misc/cgo/test/env.go b/misc/cgo/test/env.go deleted file mode 100644 index e0703e1452..0000000000 --- a/misc/cgo/test/env.go +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -/* -#include -*/ -import "C" -import ( - "os" - "runtime" - "testing" - "unsafe" -) - -// This is really an os package test but here for convenience. -func testSetEnv(t *testing.T) { - if runtime.GOOS == "windows" { - // Go uses SetEnvironmentVariable on windows. However, - // C runtime takes a *copy* at process startup of the - // OS environment, and stores it in environ/envp. - // It is this copy that getenv/putenv manipulate. - t.Logf("skipping test") - return - } - const key = "CGO_OS_TEST_KEY" - const val = "CGO_OS_TEST_VALUE" - os.Setenv(key, val) - keyc := C.CString(key) - defer C.free(unsafe.Pointer(keyc)) - v := C.getenv(keyc) - if uintptr(unsafe.Pointer(v)) == 0 { - t.Fatal("getenv returned NULL") - } - vs := C.GoString(v) - if vs != val { - t.Fatalf("getenv() = %q; want %q", vs, val) - } -} diff --git a/misc/cgo/test/exports.go b/misc/cgo/test/exports.go deleted file mode 100644 index 71e5dcdd3d..0000000000 --- a/misc/cgo/test/exports.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -import "C" -import "runtime" - -//export ReturnIntLong -func ReturnIntLong() (int, C.long) { - return 1, 2 -} - -//export gc -func gc() { - runtime.GC() -} diff --git a/misc/cgo/test/fpvar.go b/misc/cgo/test/fpvar.go deleted file mode 100644 index 7aab8ca2fc..0000000000 --- a/misc/cgo/test/fpvar.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2013 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. - -// This file contains test cases for cgo with function pointer variables. - -package cgotest - -/* -typedef int (*intFunc) (); - -int -bridge_int_func(intFunc f) -{ - return f(); -} - -int fortytwo() -{ - return 42; -} - -*/ -import "C" -import "testing" - -func callBridge(f C.intFunc) int { - return int(C.bridge_int_func(f)) -} - -func callCBridge(f C.intFunc) C.int { - return C.bridge_int_func(f) -} - -func testFpVar(t *testing.T) { - const expected = 42 - f := C.intFunc(C.fortytwo) - res1 := C.bridge_int_func(f) - if r1 := int(res1); r1 != expected { - t.Errorf("got %d, want %d", r1, expected) - } - res2 := callCBridge(f) - if r2 := int(res2); r2 != expected { - t.Errorf("got %d, want %d", r2, expected) - } - r3 := callBridge(f) - if r3 != expected { - t.Errorf("got %d, want %d", r3, expected) - } -} diff --git a/misc/cgo/test/helpers.go b/misc/cgo/test/helpers.go deleted file mode 100644 index f6a822a106..0000000000 --- a/misc/cgo/test/helpers.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -// const char *greeting = "hello, world"; -import "C" - -import ( - "reflect" - "testing" - "unsafe" -) - -const greeting = "hello, world" - -type testPair struct { - Name string - Got, Want interface{} -} - -var testPairs = []testPair{ - {"GoString", C.GoString(C.greeting), greeting}, - {"GoStringN", C.GoStringN(C.greeting, 5), greeting[:5]}, - {"GoBytes", C.GoBytes(unsafe.Pointer(C.greeting), 5), []byte(greeting[:5])}, -} - -func testHelpers(t *testing.T) { - for _, pair := range testPairs { - if !reflect.DeepEqual(pair.Got, pair.Want) { - t.Errorf("%s: got %#v, want %#v", pair.Name, pair.Got, pair.Want) - } - } -} diff --git a/misc/cgo/test/issue10303.go b/misc/cgo/test/issue10303.go deleted file mode 100644 index 66e2644d06..0000000000 --- a/misc/cgo/test/issue10303.go +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 10303. Pointers passed to C were not marked as escaping (bug in cgo). - -package cgotest - -import "runtime" - -/* -typedef int *intptr; - -void setintstar(int *x) { - *x = 1; -} - -void setintptr(intptr x) { - *x = 1; -} - -void setvoidptr(void *x) { - *(int*)x = 1; -} - -typedef struct Struct Struct; -struct Struct { - int *P; -}; - -void setstruct(Struct s) { - *s.P = 1; -} - -*/ -import "C" - -import ( - "testing" - "unsafe" -) - -func test10303(t *testing.T, n int) { - if runtime.Compiler == "gccgo" { - t.Skip("gccgo permits C pointers on the stack") - } - - // Run at a few different stack depths just to avoid an unlucky pass - // due to variables ending up on different pages. - if n > 0 { - test10303(t, n-1) - } - if t.Failed() { - return - } - var x, y, z, v, si C.int - var s C.Struct - C.setintstar(&x) - C.setintptr(&y) - C.setvoidptr(unsafe.Pointer(&v)) - s.P = &si - C.setstruct(s) - - if uintptr(unsafe.Pointer(&x))&^0xfff == uintptr(unsafe.Pointer(&z))&^0xfff { - t.Error("C int* argument on stack") - } - if uintptr(unsafe.Pointer(&y))&^0xfff == uintptr(unsafe.Pointer(&z))&^0xfff { - t.Error("C intptr argument on stack") - } - if uintptr(unsafe.Pointer(&v))&^0xfff == uintptr(unsafe.Pointer(&z))&^0xfff { - t.Error("C void* argument on stack") - } - if uintptr(unsafe.Pointer(&si))&^0xfff == uintptr(unsafe.Pointer(&z))&^0xfff { - t.Error("C struct field pointer on stack") - } -} diff --git a/misc/cgo/test/issue11925.go b/misc/cgo/test/issue11925.go deleted file mode 100644 index c5c8a269f7..0000000000 --- a/misc/cgo/test/issue11925.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 11925. Structs with zero-length trailing fields are now -// padded by the Go compiler. - -package cgotest - -/* -struct a11925 { - int i; - char a[0]; - char b[0]; -}; - -struct b11925 { - int i; - char a[0]; - char b[]; -}; -*/ -import "C" - -import ( - "testing" - "unsafe" -) - -func test11925(t *testing.T) { - if C.sizeof_struct_a11925 != unsafe.Sizeof(C.struct_a11925{}) { - t.Errorf("size of a changed: C %d, Go %d", C.sizeof_struct_a11925, unsafe.Sizeof(C.struct_a11925{})) - } - if C.sizeof_struct_b11925 != unsafe.Sizeof(C.struct_b11925{}) { - t.Errorf("size of b changed: C %d, Go %d", C.sizeof_struct_b11925, unsafe.Sizeof(C.struct_b11925{})) - } -} diff --git a/misc/cgo/test/issue12030.go b/misc/cgo/test/issue12030.go deleted file mode 100644 index f863c58aa2..0000000000 --- a/misc/cgo/test/issue12030.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 12030. sprintf is defined in both ntdll and msvcrt, -// Normally we want the one in the msvcrt. - -package cgotest - -/* -#include -#include -void issue12030conv(char *buf, double x) { - sprintf(buf, "d=%g", x); -} -*/ -import "C" - -import ( - "fmt" - "testing" - "unsafe" -) - -func test12030(t *testing.T) { - buf := (*C.char)(C.malloc(256)) - defer C.free(unsafe.Pointer(buf)) - for _, f := range []float64{1.0, 2.0, 3.14} { - C.issue12030conv(buf, C.double(f)) - got := C.GoString(buf) - if want := fmt.Sprintf("d=%g", f); got != want { - t.Fatalf("C.sprintf failed for %g: %q != %q", f, got, want) - } - } -} diff --git a/misc/cgo/test/issue1222.go b/misc/cgo/test/issue1222.go deleted file mode 100644 index 4868da8e18..0000000000 --- a/misc/cgo/test/issue1222.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2010 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. - -// This file contains test cases for cgo. - -package cgotest - -/* -// issue 1222 -typedef union { - long align; -} xxpthread_mutex_t; - -struct ibv_async_event { - union { - int x; - } element; -}; - -struct ibv_context { - xxpthread_mutex_t mutex; -}; -*/ -import "C" - -type AsyncEvent struct { - event C.struct_ibv_async_event -} diff --git a/misc/cgo/test/issue1328.go b/misc/cgo/test/issue1328.go deleted file mode 100644 index 2401c10e30..0000000000 --- a/misc/cgo/test/issue1328.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -import "testing" - -// extern void BackIntoGo(void); -// void IntoC(void); -import "C" - -//export BackIntoGo -func BackIntoGo() { - x := 1 - - for i := 0; i < 10000; i++ { - xvariadic(x) - if x != 1 { - panic("x is not 1?") - } - } -} - -func xvariadic(x ...interface{}) { -} - -func test1328(t *testing.T) { - C.IntoC() -} diff --git a/misc/cgo/test/issue13930.go b/misc/cgo/test/issue13930.go deleted file mode 100644 index c4a08ee7c9..0000000000 --- a/misc/cgo/test/issue13930.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2016 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. - -// Issue 13930. Test that cgo's multiple-value special form for -// C function calls works in variable declaration statements. - -package cgotest - -// #include -import "C" - -var _, _ = C.abs(0) diff --git a/misc/cgo/test/issue14838.go b/misc/cgo/test/issue14838.go deleted file mode 100644 index c8e1681295..0000000000 --- a/misc/cgo/test/issue14838.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2016 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. - -// Issue 14838. add CBytes function - -package cgotest - -/* -#include - -int check_cbytes(char *b, size_t l) { - int i; - for (i = 0; i < l; i++) { - if (b[i] != i) { - return 0; - } - } - return 1; -} -*/ -import "C" - -import ( - "testing" - "unsafe" -) - -func test14838(t *testing.T) { - data := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} - cData := C.CBytes(data) - defer C.free(cData) - - if C.check_cbytes((*C.char)(cData), C.size_t(len(data))) == 0 { - t.Fatalf("mismatched data: expected %v, got %v", data, (*(*[10]byte)(unsafe.Pointer(cData)))[:]) - } -} diff --git a/misc/cgo/test/issue1560.go b/misc/cgo/test/issue1560.go deleted file mode 100644 index 30f6152225..0000000000 --- a/misc/cgo/test/issue1560.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -/* -// mysleep returns the absolute start time in ms. -long long mysleep(int seconds); - -// twoSleep returns the absolute start time of the first sleep -// in ms. -long long twoSleep(int); -*/ -import "C" - -import ( - "testing" - "time" -) - -var sleepDone = make(chan int64) - -// parallelSleep returns the absolute difference between the start time -// of the two sleeps. -func parallelSleep(n int) int64 { - t := int64(C.twoSleep(C.int(n))) - <-sleepDone - if t < 0 { - return -t - } - return t -} - -//export BackgroundSleep -func BackgroundSleep(n int32) { - go func() { - sleepDone <- int64(C.mysleep(C.int(n))) - }() -} - -func testParallelSleep(t *testing.T) { - sleepSec := 1 - dt := time.Duration(parallelSleep(sleepSec)) * time.Millisecond - t.Logf("difference in start time for two sleep(%d) is %v", sleepSec, dt) - // bug used to run sleeps in serial, producing a 2*sleepSec-second delay. - // we detect if the start times of those sleeps are > 0.5*sleepSec-second. - if dt >= time.Duration(sleepSec)*time.Second/2 { - t.Fatalf("parallel %d-second sleeps slept for %f seconds", sleepSec, dt.Seconds()) - } -} diff --git a/misc/cgo/test/issue1635.go b/misc/cgo/test/issue1635.go deleted file mode 100644 index 25899271c9..0000000000 --- a/misc/cgo/test/issue1635.go +++ /dev/null @@ -1,38 +0,0 @@ -// 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 cgotest - -/* -// Mac OS X's gcc will generate scattered relocation 2/1 for -// this function on Darwin/386, and 8l couldn't handle it. -// this example is in issue 1635 -#include -void scatter() { - void *p = scatter; - printf("scatter = %p\n", p); -} - -// Adding this explicit extern declaration makes this a test for -// https://gcc.gnu.org/PR68072 aka https://golang.org/issue/13344 . -// It used to cause a cgo error when building with GCC 6. -extern int hola; - -// this example is in issue 3253 -int hola = 0; -int testHola() { return hola; } -*/ -import "C" - -import "testing" - -func test1635(t *testing.T) { - C.scatter() - if v := C.hola; v != 0 { - t.Fatalf("C.hola is %d, should be 0", v) - } - if v := C.testHola(); v != 0 { - t.Fatalf("C.testHola() is %d, should be 0", v) - } -} diff --git a/misc/cgo/test/issue17065.go b/misc/cgo/test/issue17065.go deleted file mode 100644 index ede30bc3e6..0000000000 --- a/misc/cgo/test/issue17065.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2016 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 cgotest - -/* -// Test that C symbols larger than a page play nicely with the race detector. -// See issue 17065. - -int ii[65537]; -*/ -import "C" - -import ( - "runtime" - "testing" -) - -var sink C.int - -func test17065(t *testing.T) { - if runtime.GOOS == "darwin" { - t.Skip("broken on darwin; issue 17065") - } - for i := range C.ii { - sink = C.ii[i] - } -} diff --git a/misc/cgo/test/issue17537.go b/misc/cgo/test/issue17537.go deleted file mode 100644 index 777104e512..0000000000 --- a/misc/cgo/test/issue17537.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2016 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. - -// Issue 17537. The void* cast introduced by cgo to avoid problems -// with const/volatile qualifiers breaks C preprocessor macros that -// emulate functions. - -package cgotest - -/* -#include - -typedef struct { - int i; -} S17537; - -int I17537(S17537 *p); - -#define I17537(p) ((p)->i) - -// Calling this function used to fail without the cast. -const int F17537(const char **p) { - return **p; -} - -// Calling this function used to trigger an error from the C compiler -// (issue 18298). -void F18298(const void *const *p) { -} - -// Test that conversions between typedefs work as they used to. -typedef const void *T18298_1; -struct S18298 { int i; }; -typedef const struct S18298 *T18298_2; -void G18298(T18298_1 t) { -} -*/ -import "C" - -import "testing" - -func test17537(t *testing.T) { - v := C.S17537{i: 17537} - if got, want := C.I17537(&v), C.int(17537); got != want { - t.Errorf("got %d, want %d", got, want) - } - - p := (*C.char)(C.malloc(1)) - *p = 17 - if got, want := C.F17537(&p), C.int(17); got != want { - t.Errorf("got %d, want %d", got, want) - } - - C.F18298(nil) - var v18298 C.T18298_2 - C.G18298(C.T18298_1(v18298)) -} diff --git a/misc/cgo/test/issue18126.go b/misc/cgo/test/issue18126.go deleted file mode 100644 index ac94a66aab..0000000000 --- a/misc/cgo/test/issue18126.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2016 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. - -// Issue 18126: cgo check of void function returning errno. - -package cgotest - -/* -#include - -void Issue18126C(void **p) { -} -*/ -import "C" - -import ( - "testing" -) - -func test18126(t *testing.T) { - p := C.malloc(1) - _, err := C.Issue18126C(&p) - C.free(p) - _ = err -} diff --git a/misc/cgo/test/issue18146.go b/misc/cgo/test/issue18146.go index 0605a24ee9..196d98f507 100644 --- a/misc/cgo/test/issue18146.go +++ b/misc/cgo/test/issue18146.go @@ -8,8 +8,6 @@ package cgotest -import "C" - import ( "bytes" "crypto/md5" diff --git a/misc/cgo/test/issue18720.go b/misc/cgo/test/issue18720.go deleted file mode 100644 index 3d64003be7..0000000000 --- a/misc/cgo/test/issue18720.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2017 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 cgotest - -/* -#define HELLO "hello" -#define WORLD "world" -#define HELLO_WORLD HELLO "\000" WORLD - -struct foo { char c; }; -#define SIZE_OF(x) sizeof(x) -#define SIZE_OF_FOO SIZE_OF(struct foo) -#define VAR1 VAR -#define VAR var -int var = 5; - -#define ADDR &var - -#define CALL fn() -int fn(void) { - return ++var; -} -*/ -import "C" -import "testing" - -func test18720(t *testing.T) { - if got, want := C.HELLO_WORLD, "hello\000world"; got != want { - t.Errorf("C.HELLO_WORLD == %q, expected %q", got, want) - } - - if got, want := C.VAR1, C.int(5); got != want { - t.Errorf("C.VAR1 == %v, expected %v", got, want) - } - - if got, want := *C.ADDR, C.int(5); got != want { - t.Errorf("*C.ADDR == %v, expected %v", got, want) - } - - if got, want := C.CALL, C.int(6); got != want { - t.Errorf("C.CALL == %v, expected %v", got, want) - } - - if got, want := C.CALL, C.int(7); got != want { - t.Errorf("C.CALL == %v, expected %v", got, want) - } - - // Issue 20125. - if got, want := C.SIZE_OF_FOO, 1; got != want { - t.Errorf("C.SIZE_OF_FOO == %v, expected %v", got, want) - } -} diff --git a/misc/cgo/test/issue20129.go b/misc/cgo/test/issue20129.go deleted file mode 100644 index e69e0e16ef..0000000000 --- a/misc/cgo/test/issue20129.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2017 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 cgotest - -/* -int issue20129 = 0; -typedef void issue20129Void; -issue20129Void issue20129Foo() { - issue20129 = 1; -} -typedef issue20129Void issue20129Void2; -issue20129Void2 issue20129Bar() { - issue20129 = 2; -} -*/ -import "C" -import "testing" - -func test20129(t *testing.T) { - if C.issue20129 != 0 { - t.Fatal("test is broken") - } - C.issue20129Foo() - if C.issue20129 != 1 { - t.Errorf("got %v but expected %v", C.issue20129, 1) - } - C.issue20129Bar() - if C.issue20129 != 2 { - t.Errorf("got %v but expected %v", C.issue20129, 2) - } -} diff --git a/misc/cgo/test/issue20369.go b/misc/cgo/test/issue20369.go deleted file mode 100644 index 37b4b78dfe..0000000000 --- a/misc/cgo/test/issue20369.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2017 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 cgotest - -/* -#define UINT64_MAX 18446744073709551615ULL -*/ -import "C" -import ( - "math" - "testing" -) - -func test20369(t *testing.T) { - if C.UINT64_MAX != math.MaxUint64 { - t.Fatalf("got %v, want %v", uint64(C.UINT64_MAX), uint64(math.MaxUint64)) - } -} diff --git a/misc/cgo/test/issue20910.go b/misc/cgo/test/issue20910.go deleted file mode 100644 index 69d7d9249a..0000000000 --- a/misc/cgo/test/issue20910.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2017 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 cgotest - -//void callMulti(void); -import "C" - -import "testing" - -//export multi -func multi() (*C.char, C.int) { - return C.CString("multi"), 0 -} - -func test20910(t *testing.T) { - C.callMulti() -} diff --git a/misc/cgo/test/issue21668.go b/misc/cgo/test/issue21668.go deleted file mode 100644 index f15b9202ac..0000000000 --- a/misc/cgo/test/issue21668.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2017 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. - -// Fail to guess the kind of the constant "x". -// No runtime test; just make sure it compiles. - -package cgotest - -// const int x = 42; -import "C" - -var issue21668_X = C.x diff --git a/misc/cgo/test/issue21708.go b/misc/cgo/test/issue21708.go deleted file mode 100644 index d413e3c57a..0000000000 --- a/misc/cgo/test/issue21708.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2017 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 cgotest - -// #include -// #define CAST_TO_INT64 (int64_t)(-1) -import "C" -import "testing" - -func test21708(t *testing.T) { - if got, want := C.CAST_TO_INT64, -1; got != want { - t.Errorf("C.CAST_TO_INT64 == %v, expected %v", got, want) - } -} diff --git a/misc/cgo/test/issue21809.go b/misc/cgo/test/issue21809.go deleted file mode 100644 index a3a6b88897..0000000000 --- a/misc/cgo/test/issue21809.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2017 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 cgotest - -// Issue 21809. Compile C `typedef` to go type aliases. - -// typedef long MySigned_t; -// /* tests alias-to-alias */ -// typedef MySigned_t MySigned2_t; -// -// long takes_long(long x) { return x * x; } -// MySigned_t takes_typedef(MySigned_t x) { return x * x; } -import "C" - -import "testing" - -func test21809(t *testing.T) { - longVar := C.long(3) - typedefVar := C.MySigned_t(4) - typedefTypedefVar := C.MySigned2_t(5) - - // all three should be considered identical to `long` - if ret := C.takes_long(longVar); ret != 9 { - t.Errorf("got %v but expected %v", ret, 9) - } - if ret := C.takes_long(typedefVar); ret != 16 { - t.Errorf("got %v but expected %v", ret, 16) - } - if ret := C.takes_long(typedefTypedefVar); ret != 25 { - t.Errorf("got %v but expected %v", ret, 25) - } - - // They should also be identical to the typedef'd type - if ret := C.takes_typedef(longVar); ret != 9 { - t.Errorf("got %v but expected %v", ret, 9) - } - if ret := C.takes_typedef(typedefVar); ret != 16 { - t.Errorf("got %v but expected %v", ret, 16) - } - if ret := C.takes_typedef(typedefTypedefVar); ret != 25 { - t.Errorf("got %v but expected %v", ret, 25) - } -} diff --git a/misc/cgo/test/issue22958.go b/misc/cgo/test/issue22958.go deleted file mode 100644 index a5f058fdae..0000000000 --- a/misc/cgo/test/issue22958.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2017 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 cgotest - -// Test handling of bitfields. - -/* -typedef struct { - unsigned long long f8 : 8; - unsigned long long f16 : 16; - unsigned long long f24 : 24; - unsigned long long f32 : 32; - unsigned long long f40 : 40; - unsigned long long f48 : 48; - unsigned long long f56 : 56; - unsigned long long f64 : 64; -} issue22958Type; -*/ -import "C" - -// Nothing to run, just make sure this compiles. -var Vissue22958 C.issue22958Type diff --git a/misc/cgo/test/issue23356.go b/misc/cgo/test/issue23356.go deleted file mode 100644 index 1c390120c8..0000000000 --- a/misc/cgo/test/issue23356.go +++ /dev/null @@ -1,19 +0,0 @@ -// 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 cgotest - -// int a(void) { return 5; }; -// int r(void) { return 3; }; -import "C" -import "testing" - -func test23356(t *testing.T) { - if got, want := C.a(), C.int(5); got != want { - t.Errorf("C.a() == %v, expected %v", got, want) - } - if got, want := C.r(), C.int(3); got != want { - t.Errorf("C.r() == %v, expected %v", got, want) - } -} diff --git a/misc/cgo/test/issue23720.go b/misc/cgo/test/issue23720.go deleted file mode 100644 index 934fff3420..0000000000 --- a/misc/cgo/test/issue23720.go +++ /dev/null @@ -1,22 +0,0 @@ -// 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. - -// Test that we can pass compatible typedefs. -// No runtime test; just make sure it compiles. - -package cgotest - -/* -typedef int *issue23720A; - -typedef const int *issue23720B; - -void issue23720F(issue23720B a) {} -*/ -import "C" - -func Issue23720F() { - var x C.issue23720A - C.issue23720F(x) -} diff --git a/misc/cgo/test/issue24206.go b/misc/cgo/test/issue24206.go deleted file mode 100644 index 5fec68e880..0000000000 --- a/misc/cgo/test/issue24206.go +++ /dev/null @@ -1,54 +0,0 @@ -// +build amd64,linux - -// 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 cgotest - -// Test that C.GoString uses IndexByte in safe manner. - -/* -#include - -// Returns string with null byte at the last valid address -char* dangerousString1() { - int pageSize = 4096; - char *data = mmap(0, 2 * pageSize, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0); - mprotect(data + pageSize,pageSize,PROT_NONE); - int start = pageSize - 123 - 1; // last 123 bytes of first page + 1 null byte - int i = start; - for (; i < pageSize; i++) { - data[i] = 'x'; - } - data[pageSize -1 ] = 0; - return data+start; -} - -char* dangerousString2() { - int pageSize = 4096; - char *data = mmap(0, 3 * pageSize, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0); - mprotect(data + 2 * pageSize,pageSize,PROT_NONE); - int start = pageSize - 123 - 1; // last 123 bytes of first page + 1 null byte - int i = start; - for (; i < 2 * pageSize; i++) { - data[i] = 'x'; - } - data[2*pageSize -1 ] = 0; - return data+start; -} -*/ -import "C" - -import ( - "testing" -) - -func test24206(t *testing.T) { - if l := len(C.GoString(C.dangerousString1())); l != 123 { - t.Errorf("Incorrect string length - got %d, want 123", l) - } - if l := len(C.GoString(C.dangerousString2())); l != 4096+123 { - t.Errorf("Incorrect string length - got %d, want %d", l, 4096+123) - } -} diff --git a/misc/cgo/test/issue24206_generic.go b/misc/cgo/test/issue24206_generic.go deleted file mode 100644 index 27c4d65f28..0000000000 --- a/misc/cgo/test/issue24206_generic.go +++ /dev/null @@ -1,13 +0,0 @@ -// +build !amd64 !linux - -// 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 cgotest - -import "testing" - -func test24206(t *testing.T) { - t.Skip("Skipping on non-amd64 or non-linux system") -} diff --git a/misc/cgo/test/issue2462.go b/misc/cgo/test/issue2462.go deleted file mode 100644 index febca1eb08..0000000000 --- a/misc/cgo/test/issue2462.go +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -import "C" - -//export exportbyte -func exportbyte() byte { - return 0 -} - -//export exportbool -func exportbool() bool { - return false -} - -//export exportrune -func exportrune() rune { - return 0 -} - -//export exporterror -func exporterror() error { - return nil -} - -//export exportint -func exportint() int { - return 0 -} - -//export exportuint -func exportuint() uint { - return 0 -} - -//export exportuintptr -func exportuintptr() uintptr { - return (uintptr)(0) -} - -//export exportint8 -func exportint8() int8 { - return 0 -} - -//export exportuint8 -func exportuint8() uint8 { - return 0 -} - -//export exportint16 -func exportint16() int16 { - return 0 -} - -//export exportuint16 -func exportuint16() uint16 { - return 0 -} - -//export exportint32 -func exportint32() int32 { - return 0 -} - -//export exportuint32 -func exportuint32() uint32 { - return 0 -} - -//export exportint64 -func exportint64() int64 { - return 0 -} - -//export exportuint64 -func exportuint64() uint64 { - return 0 -} - -//export exportfloat32 -func exportfloat32() float32 { - return 0 -} - -//export exportfloat64 -func exportfloat64() float64 { - return 0 -} - -//export exportcomplex64 -func exportcomplex64() complex64 { - return 0 -} - -//export exportcomplex128 -func exportcomplex128() complex128 { - return 0 -} diff --git a/misc/cgo/test/issue25143.go b/misc/cgo/test/issue25143.go deleted file mode 100644 index 607bfe4ba0..0000000000 --- a/misc/cgo/test/issue25143.go +++ /dev/null @@ -1,22 +0,0 @@ -// 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 cgotest - -import "C" -import "testing" - -func issue25143sum(ns ...C.int) C.int { - total := C.int(0) - for _, n := range ns { - total += n - } - return total -} - -func test25143(t *testing.T) { - if got, want := issue25143sum(1, 2, 3), C.int(6); got != want { - t.Errorf("issue25143sum(1, 2, 3) == %v, expected %v", got, want) - } -} diff --git a/misc/cgo/test/issue26066.go b/misc/cgo/test/issue26066.go deleted file mode 100644 index 21028e7479..0000000000 --- a/misc/cgo/test/issue26066.go +++ /dev/null @@ -1,19 +0,0 @@ -// 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. - -// Wrong type of constant with GCC 8 and newer. - -package cgotest - -// const unsigned long long int issue26066 = (const unsigned long long) -1; -import "C" - -import "testing" - -func test26066(t *testing.T) { - var i = int64(C.issue26066) - if i != -1 { - t.Errorf("got %d, want -1", i) - } -} diff --git a/misc/cgo/test/issue26517.go b/misc/cgo/test/issue26517.go deleted file mode 100644 index c1bf1c9213..0000000000 --- a/misc/cgo/test/issue26517.go +++ /dev/null @@ -1,23 +0,0 @@ -// 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 cgotest - -// Introduce two pointer types which are distinct, but have the same -// base type. Make sure that both of those pointer types get resolved -// correctly. Before the fix for 26517 if one of these pointer types -// was resolved before the other one was processed, the second one -// would never be resolved. -// Before this issue was fixed this test failed on Windows, -// where va_list expands to a named char* type. - -/* -#include -typedef va_list TypeOne; -typedef char *TypeTwo; -*/ -import "C" - -var a C.TypeOne -var b C.TypeTwo diff --git a/misc/cgo/test/issue28545.go b/misc/cgo/test/issue28545.go deleted file mode 100644 index 8419b89c0a..0000000000 --- a/misc/cgo/test/issue28545.go +++ /dev/null @@ -1,26 +0,0 @@ -// 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. - -// Failed to add type conversion for negative constant. -// Issue 28772: Failed to add type conversion for Go constant set to C constant. -// No runtime test; just make sure it compiles. - -package cgotest - -/* -#include - -#define issue28772Constant 1 - -static void issue28545F(char **p, int n, complex double a) {} -*/ -import "C" - -const issue28772Constant = C.issue28772Constant - -func issue28545G(p **C.char) { - C.issue28545F(p, -1, (0)) - C.issue28545F(p, 2+3, complex(1, 1)) - C.issue28545F(p, issue28772Constant, issue28772Constant2) -} diff --git a/misc/cgo/test/issue28772.go b/misc/cgo/test/issue28772.go deleted file mode 100644 index bed786bf30..0000000000 --- a/misc/cgo/test/issue28772.go +++ /dev/null @@ -1,12 +0,0 @@ -// 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 cgotest - -// Constants didn't work if defined in different source file. - -// #define issue28772Constant2 2 -import "C" - -const issue28772Constant2 = C.issue28772Constant2 diff --git a/misc/cgo/test/issue28896.go b/misc/cgo/test/issue28896.go deleted file mode 100644 index 8796040f18..0000000000 --- a/misc/cgo/test/issue28896.go +++ /dev/null @@ -1,83 +0,0 @@ -// 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. - -// cgo was incorrectly adding padding after a packed struct. - -package cgotest - -/* -#include -#include -#include - -typedef struct { - void *f1; - uint32_t f2; -} __attribute__((__packed__)) innerPacked; - -typedef struct { - innerPacked g1; - uint64_t g2; -} outerPacked; - -typedef struct { - void *f1; - uint32_t f2; -} innerUnpacked; - -typedef struct { - innerUnpacked g1; - uint64_t g2; -} outerUnpacked; - -size_t offset(int x) { - switch (x) { - case 0: - return offsetof(innerPacked, f2); - case 1: - return offsetof(outerPacked, g2); - case 2: - return offsetof(innerUnpacked, f2); - case 3: - return offsetof(outerUnpacked, g2); - default: - abort(); - } -} -*/ -import "C" - -import ( - "testing" - "unsafe" -) - -func offset(i int) uintptr { - var pi C.innerPacked - var po C.outerPacked - var ui C.innerUnpacked - var uo C.outerUnpacked - switch i { - case 0: - return unsafe.Offsetof(pi.f2) - case 1: - return unsafe.Offsetof(po.g2) - case 2: - return unsafe.Offsetof(ui.f2) - case 3: - return unsafe.Offsetof(uo.g2) - default: - panic("can't happen") - } -} - -func test28896(t *testing.T) { - for i := 0; i < 4; i++ { - c := uintptr(C.offset(C.int(i))) - g := offset(i) - if c != g { - t.Errorf("%d: C: %d != Go %d", i, c, g) - } - } -} diff --git a/misc/cgo/test/issue29383.go b/misc/cgo/test/issue29383.go deleted file mode 100644 index 462c9a37df..0000000000 --- a/misc/cgo/test/issue29383.go +++ /dev/null @@ -1,19 +0,0 @@ -// 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. - -// cgo's /*line*/ comments failed when inserted after '/', -// because the result looked like a "//" comment. -// No runtime test; just make sure it compiles. - -package cgotest - -// #include -import "C" - -func Issue29383(n, size uint) int { - if ^C.size_t(0)/C.size_t(n) < C.size_t(size) { - return 0 - } - return 0 -} diff --git a/misc/cgo/test/issue29748.go b/misc/cgo/test/issue29748.go deleted file mode 100644 index 8229b3bcf0..0000000000 --- a/misc/cgo/test/issue29748.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2019 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. - -// Error handling a struct initializer that requires pointer checking. -// Compilation test only, nothing to run. - -package cgotest - -// typedef struct { char **p; } S29748; -// static int f29748(S29748 *p) { return 0; } -import "C" - -var Vissue29748 = C.f29748(&C.S29748{ - nil, -}) - -func Fissue299748() { - C.f29748(&C.S29748{ - nil, - }) -} diff --git a/misc/cgo/test/issue29781.go b/misc/cgo/test/issue29781.go deleted file mode 100644 index c80919dc17..0000000000 --- a/misc/cgo/test/issue29781.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2019 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. - -// Error with newline inserted into constant expression. -// Compilation test only, nothing to run. - -package cgotest - -// static void issue29781F(char **p, int n) {} -// #define ISSUE29781C 0 -import "C" - -var issue29781X struct{ X int } - -func issue29781F(...int) int { return 0 } - -func issue29781G() { - var p *C.char - C.issue29781F(&p, C.ISSUE29781C+1) - C.issue29781F(nil, (C.int)( - 0)) - C.issue29781F(&p, (C.int)(0)) - C.issue29781F(&p, (C.int)( - 0)) - C.issue29781F(&p, (C.int)(issue29781X. - X)) -} diff --git a/misc/cgo/test/issue29878.go b/misc/cgo/test/issue29878.go deleted file mode 100644 index c1aeaf9709..0000000000 --- a/misc/cgo/test/issue29878.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2019 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 cgotest - -// #include -// uint64_t issue29878exported(int8_t); // prototype must match -// int16_t issue29878function(uint32_t arg) { return issue29878exported(arg); } -import "C" - -import "testing" - -func test29878(t *testing.T) { - const arg uint32 = 123 // fits into all integer types - var ret int16 = C.issue29878function(arg) // no conversions needed - if int64(ret) != int64(arg) { - t.Errorf("return value unexpected: got %d, want %d", ret, arg) - } -} diff --git a/misc/cgo/test/issue30065.go b/misc/cgo/test/issue30065.go deleted file mode 100644 index 396d437f7a..0000000000 --- a/misc/cgo/test/issue30065.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2019 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. - -// Don't make a private copy of an array when taking the address of an -// element. - -package cgotest - -// #include -import "C" - -import ( - "testing" - "unsafe" -) - -func test30065(t *testing.T) { - var a [256]byte - b := []byte("a") - C.memcpy(unsafe.Pointer(&a), unsafe.Pointer(&b[0]), 1) - if a[0] != 'a' { - t.Errorf("&a failed: got %c, want %c", a[0], 'a') - } - - b = []byte("b") - C.memcpy(unsafe.Pointer(&a[0]), unsafe.Pointer(&b[0]), 1) - if a[0] != 'b' { - t.Errorf("&a[0] failed: got %c, want %c", a[0], 'b') - } - - d := make([]byte, 256) - b = []byte("c") - C.memcpy(unsafe.Pointer(&d[0]), unsafe.Pointer(&b[0]), 1) - if d[0] != 'c' { - t.Errorf("&d[0] failed: got %c, want %c", d[0], 'c') - } -} diff --git a/misc/cgo/test/issue3250.go b/misc/cgo/test/issue3250.go deleted file mode 100644 index f85c16b2dc..0000000000 --- a/misc/cgo/test/issue3250.go +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2013 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. - -// +build !windows - -package cgotest - -/* -#include -#include -#include -#include - -static void *thread(void *p) { - const int M = 100; - int i; - (void)p; - for (i = 0; i < M; i++) { - pthread_kill(pthread_self(), SIGCHLD); - usleep(rand() % 20 + 5); - } - return NULL; -} -void testSendSIG() { - const int N = 20; - int i; - pthread_t tid[N]; - for (i = 0; i < N; i++) { - usleep(rand() % 200 + 100); - pthread_create(&tid[i], 0, thread, NULL); - } - for (i = 0; i < N; i++) - pthread_join(tid[i], 0); -} -*/ -import "C" - -import ( - "os" - "os/signal" - "syscall" - "testing" - "time" -) - -func test3250(t *testing.T) { - t.Skip("skipped, see golang.org/issue/5885") - const ( - thres = 1 - sig = syscall.SIGCHLD - ) - type result struct { - n int - sig os.Signal - } - var ( - sigCh = make(chan os.Signal, 10) - waitStart = make(chan struct{}) - waitDone = make(chan result) - ) - - signal.Notify(sigCh, sig) - - go func() { - n := 0 - alarm := time.After(time.Second * 3) - for { - select { - case <-waitStart: - waitStart = nil - case v := <-sigCh: - n++ - if v != sig || n > thres { - waitDone <- result{n, v} - return - } - case <-alarm: - waitDone <- result{n, sig} - return - } - } - }() - - waitStart <- struct{}{} - C.testSendSIG() - r := <-waitDone - if r.sig != sig { - t.Fatalf("received signal %v, but want %v", r.sig, sig) - } - t.Logf("got %d signals\n", r.n) - if r.n <= thres { - t.Fatalf("expected more than %d", thres) - } -} diff --git a/misc/cgo/test/issue3250w.go b/misc/cgo/test/issue3250w.go deleted file mode 100644 index c2193aa1f1..0000000000 --- a/misc/cgo/test/issue3250w.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2013 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. - -// +build windows - -package cgotest - -import "testing" - -func test3250(t *testing.T) {} diff --git a/misc/cgo/test/issue3261.go b/misc/cgo/test/issue3261.go deleted file mode 100644 index 71375698d3..0000000000 --- a/misc/cgo/test/issue3261.go +++ /dev/null @@ -1,49 +0,0 @@ -// 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 cgotest - -/* -// libgcc on ARM might be compiled as thumb code, but our 5l -// can't handle that, so we have to disable this test on arm. -#ifdef __ARMEL__ -#include -int vabs(int x) { - puts("testLibgcc is disabled on ARM because 5l cannot handle thumb library."); - return (x < 0) ? -x : x; -} -#elif defined(__arm64__) && defined(__clang__) -#include -int vabs(int x) { - puts("testLibgcc is disabled on ARM64 with clang due to lack of libgcc."); - return (x < 0) ? -x : x; -} -#else -int __absvsi2(int); // dummy prototype for libgcc function -// we shouldn't name the function abs, as gcc might use -// the builtin one. -int vabs(int x) { return __absvsi2(x); } -#endif -*/ -import "C" - -import "testing" - -func testLibgcc(t *testing.T) { - var table = []struct { - in, out C.int - }{ - {0, 0}, - {1, 1}, - {-42, 42}, - {1000300, 1000300}, - {1 - 1<<31, 1<<31 - 1}, - } - for _, v := range table { - if o := C.vabs(v.in); o != v.out { - t.Fatalf("abs(%d) got %d, should be %d", v.in, o, v.out) - return - } - } -} diff --git a/misc/cgo/test/issue3729.go b/misc/cgo/test/issue3729.go deleted file mode 100644 index 947b90a00d..0000000000 --- a/misc/cgo/test/issue3729.go +++ /dev/null @@ -1,47 +0,0 @@ -// 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. - -// Issue 3729: cmd/cgo: access errno from void C function -// void f(void) returns [0]byte, error in Go world. - -// +build !windows - -package cgotest - -/* -#include - -void g(void) { - errno = E2BIG; -} - -// try to pass some non-trivial arguments to function g2 -const char _expA = 0x42; -const float _expB = 3.14159; -const short _expC = 0x55aa; -const int _expD = 0xdeadbeef; -void g2(int x, char a, float b, short c, int d) { - if (a == _expA && b == _expB && c == _expC && d == _expD) - errno = x; - else - errno = -1; -} -*/ -import "C" - -import ( - "syscall" - "testing" -) - -func test3729(t *testing.T) { - _, e := C.g() - if e != syscall.E2BIG { - t.Errorf("got %q, expect %q", e, syscall.E2BIG) - } - _, e = C.g2(C.EINVAL, C._expA, C._expB, C._expC, C._expD) - if e != syscall.EINVAL { - t.Errorf("got %q, expect %q", e, syscall.EINVAL) - } -} diff --git a/misc/cgo/test/issue3729w.go b/misc/cgo/test/issue3729w.go deleted file mode 100644 index 69296b506e..0000000000 --- a/misc/cgo/test/issue3729w.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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. - -// Issue 3729: cmd/cgo: access errno from void C function -// void f(void) returns [0]byte, error in Go world. - -// +build windows - -package cgotest - -import "testing" - -func test3729(t *testing.T) { - t.Log("skip errno test on Windows") -} diff --git a/misc/cgo/test/issue3741.go b/misc/cgo/test/issue3741.go deleted file mode 100644 index 314038c1fe..0000000000 --- a/misc/cgo/test/issue3741.go +++ /dev/null @@ -1,22 +0,0 @@ -// 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 cgotest - -import "C" - -//export exportSliceIn -func exportSliceIn(s []byte) bool { - return len(s) == cap(s) -} - -//export exportSliceOut -func exportSliceOut() []byte { - return []byte{1} -} - -//export exportSliceInOut -func exportSliceInOut(s []byte) []byte { - return s -} diff --git a/misc/cgo/test/issue3775.go b/misc/cgo/test/issue3775.go deleted file mode 100644 index 5aca7602c0..0000000000 --- a/misc/cgo/test/issue3775.go +++ /dev/null @@ -1,39 +0,0 @@ -// +build !android - -package cgotest - -/* -void lockOSThreadCallback(void); -inline static void lockOSThreadC(void) -{ - lockOSThreadCallback(); -} -int usleep(unsigned usec); -*/ -import "C" - -import ( - "runtime" - "testing" -) - -func init() { - // Same as test3775 but run during init so that - // there are two levels of internal runtime lock - // (1 for init, 1 for cgo). - // This would have been broken by CL 11663043. - C.lockOSThreadC() -} - -func test3775(t *testing.T) { - // Used to panic because of the UnlockOSThread below. - C.lockOSThreadC() -} - -//export lockOSThreadCallback -func lockOSThreadCallback() { - runtime.LockOSThread() - runtime.UnlockOSThread() - go C.usleep(10000) - runtime.Gosched() -} diff --git a/misc/cgo/test/issue3945.go b/misc/cgo/test/issue3945.go deleted file mode 100644 index 2f9fe23b8d..0000000000 --- a/misc/cgo/test/issue3945.go +++ /dev/null @@ -1,22 +0,0 @@ -// 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 cgotest - -// Test that cgo reserves enough stack space during cgo call. -// See https://golang.org/issue/3945 for details. - -// #include -// -// void say() { -// printf("%s from C\n", "hello"); -// } -// -import "C" - -import "testing" - -func testPrintf(t *testing.T) { - C.say() -} diff --git a/misc/cgo/test/issue4054a.go b/misc/cgo/test/issue4054a.go deleted file mode 100644 index 2abdac5904..0000000000 --- a/misc/cgo/test/issue4054a.go +++ /dev/null @@ -1,23 +0,0 @@ -// 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 cgotest - -/* -typedef enum { - A = 0, - B, - C, - D, - E, - F, - G, - H, - I, - J, -} issue4054a; -*/ -import "C" - -var issue4054a = []int{C.A, C.B, C.C, C.D, C.E, C.F, C.G, C.H, C.I, C.J} diff --git a/misc/cgo/test/issue4054b.go b/misc/cgo/test/issue4054b.go deleted file mode 100644 index 048964c893..0000000000 --- a/misc/cgo/test/issue4054b.go +++ /dev/null @@ -1,23 +0,0 @@ -// 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 cgotest - -/* -typedef enum { - A = 0, - B, - C, - D, - E, - F, - G, - H, - I, - J, -} issue4054b; -*/ -import "C" - -var issue4054b = []int{C.A, C.B, C.C, C.D, C.E, C.F, C.G, C.H, C.I, C.J} diff --git a/misc/cgo/test/issue4339.go b/misc/cgo/test/issue4339.go deleted file mode 100644 index 3715fde575..0000000000 --- a/misc/cgo/test/issue4339.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2013 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 cgotest - -/* -// We've historically permitted #include <>, so test it here. Issue 29333. -#include -*/ -import "C" - -import "testing" - -func test4339(t *testing.T) { - C.handle4339(&C.exported4339) -} diff --git a/misc/cgo/test/issue4417.go b/misc/cgo/test/issue4417.go deleted file mode 100644 index 9b182870d8..0000000000 --- a/misc/cgo/test/issue4417.go +++ /dev/null @@ -1,42 +0,0 @@ -// 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. - -// Issue 4417: cmd/cgo: bool alignment/padding issue. -// bool alignment is wrong and causing wrong arguments when calling functions. -// - -package cgotest - -/* -#include - -static int c_bool(bool a, bool b, int c, bool d, bool e) { - return c; -} -*/ -import "C" -import "testing" - -func testBoolAlign(t *testing.T) { - b := C.c_bool(true, true, 10, true, false) - if b != 10 { - t.Fatalf("found %d expected 10\n", b) - } - b = C.c_bool(true, true, 5, true, true) - if b != 5 { - t.Fatalf("found %d expected 5\n", b) - } - b = C.c_bool(true, true, 3, true, false) - if b != 3 { - t.Fatalf("found %d expected 3\n", b) - } - b = C.c_bool(false, false, 1, true, false) - if b != 1 { - t.Fatalf("found %d expected 1\n", b) - } - b = C.c_bool(false, true, 200, true, false) - if b != 200 { - t.Fatalf("found %d expected 200\n", b) - } -} diff --git a/misc/cgo/test/issue4857.go b/misc/cgo/test/issue4857.go deleted file mode 100644 index b18979b5f7..0000000000 --- a/misc/cgo/test/issue4857.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2013 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 cgotest - -/* -#cgo CFLAGS: -Werror -const struct { int a; } *issue4857() { return (void *)0; } -*/ -import "C" - -func test4857() { - _ = C.issue4857() -} diff --git a/misc/cgo/test/issue5227.go b/misc/cgo/test/issue5227.go deleted file mode 100644 index 53c3bf12d7..0000000000 --- a/misc/cgo/test/issue5227.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2013 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. - -// Issue 5227: linker incorrectly treats common symbols and -// leaves them undefined. - -package cgotest - -/* -typedef struct { - int Count; -} Fontinfo; - -Fontinfo SansTypeface; - -extern void init(); - -Fontinfo loadfont() { - Fontinfo f = {0}; - return f; -} - -void init() { - SansTypeface = loadfont(); -} -*/ -import "C" - -import "testing" - -func test5227(t *testing.T) { - C.init() -} - -func selectfont() C.Fontinfo { - return C.SansTypeface -} diff --git a/misc/cgo/test/issue5242.go b/misc/cgo/test/issue5242.go deleted file mode 100644 index c81cd40919..0000000000 --- a/misc/cgo/test/issue5242.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 5242. Cgo incorrectly computed the alignment of structs -// with no Go accessible fields as 0, and then panicked on -// modulo-by-zero computations. - -package cgotest - -/* -typedef struct { -} foo; - -typedef struct { - int x : 1; -} bar; - -int issue5242(foo f, bar b) { - return 5242; -} -*/ -import "C" - -import "testing" - -func test5242(t *testing.T) { - if got := C.issue5242(C.foo{}, C.bar{}); got != 5242 { - t.Errorf("got %v", got) - } -} diff --git a/misc/cgo/test/issue5337.go b/misc/cgo/test/issue5337.go deleted file mode 100644 index 9041d95168..0000000000 --- a/misc/cgo/test/issue5337.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2013 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. - -// +build !windows - -package cgotest - -/* -#include -#include - -static void *thread1(void *p) { - (void)p; - pthread_kill(pthread_self(), SIGPROF); - return NULL; -} -void test5337() { - pthread_t tid; - pthread_create(&tid, 0, thread1, NULL); - pthread_join(tid, 0); -} -*/ -import "C" - -import "testing" - -// Verify that we can withstand SIGPROF received on foreign threads -func test5337(t *testing.T) { - C.test5337() -} diff --git a/misc/cgo/test/issue5337w.go b/misc/cgo/test/issue5337w.go deleted file mode 100644 index 7b46757700..0000000000 --- a/misc/cgo/test/issue5337w.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2013 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. - -// +build windows - -package cgotest - -import "testing" - -func test5337(t *testing.T) {} diff --git a/misc/cgo/test/issue5548.go b/misc/cgo/test/issue5548.go deleted file mode 100644 index 0710da7950..0000000000 --- a/misc/cgo/test/issue5548.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2013 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 cgotest - -import "testing" - -/* -extern int issue5548_in_c(void); -*/ -import "C" - -//export issue5548FromC -func issue5548FromC(s string, i int) int { - if len(s) == 4 && s == "test" && i == 42 { - return 12345 - } - println("got", len(s), i) - return 9876 -} - -func test5548(t *testing.T) { - if x := C.issue5548_in_c(); x != 12345 { - t.Errorf("issue5548_in_c = %d, want %d", x, 12345) - } -} diff --git a/misc/cgo/test/issue5603.go b/misc/cgo/test/issue5603.go deleted file mode 100644 index ab84339e10..0000000000 --- a/misc/cgo/test/issue5603.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2013 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 cgotest - -/* -const long long issue5603exp = 0x12345678; -long long issue5603foo0() { return issue5603exp; } -long long issue5603foo1(void *p) { return issue5603exp; } -long long issue5603foo2(void *p, void *q) { return issue5603exp; } -long long issue5603foo3(void *p, void *q, void *r) { return issue5603exp; } -long long issue5603foo4(void *p, void *q, void *r, void *s) { return issue5603exp; } -*/ -import "C" - -import "testing" - -func test5603(t *testing.T) { - var x [5]int64 - exp := int64(C.issue5603exp) - x[0] = int64(C.issue5603foo0()) - x[1] = int64(C.issue5603foo1(nil)) - x[2] = int64(C.issue5603foo2(nil, nil)) - x[3] = int64(C.issue5603foo3(nil, nil, nil)) - x[4] = int64(C.issue5603foo4(nil, nil, nil, nil)) - for i, v := range x { - if v != exp { - t.Errorf("issue5603foo%d() returns %v, expected %v", i, v, exp) - } - } -} diff --git a/misc/cgo/test/issue5740.go b/misc/cgo/test/issue5740.go deleted file mode 100644 index 059e316119..0000000000 --- a/misc/cgo/test/issue5740.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2013 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 cgotest - -// int test5740a(void), test5740b(void); -import "C" -import "testing" - -func test5740(t *testing.T) { - if v := C.test5740a() + C.test5740b(); v != 5 { - t.Errorf("expected 5, got %v", v) - } -} diff --git a/misc/cgo/test/issue5986.go b/misc/cgo/test/issue5986.go deleted file mode 100644 index 9be1614233..0000000000 --- a/misc/cgo/test/issue5986.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2013 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 cgotest - -/* -#cgo LDFLAGS: -lm -#include -#include - -static void output5986() -{ - int current_row = 0, row_count = 0; - double sum_squares = 0; - double d; - do { - if (current_row == 10) { - current_row = 0; - } - ++row_count; - } - while (current_row++ != 1); - d = sqrt(sum_squares / row_count); - printf("sqrt is: %g\n", d); -} -*/ -import "C" -import "testing" - -func test5986(t *testing.T) { - C.output5986() -} diff --git a/misc/cgo/test/issue6128.go b/misc/cgo/test/issue6128.go deleted file mode 100644 index 9832d799b9..0000000000 --- a/misc/cgo/test/issue6128.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2013 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 cgotest - -// Test handling of #defined names in clang. -// golang.org/issue/6128. - -/* -// NOTE: Must use hex, or else a shortcut for decimals -// in cgo avoids trying to pass this to clang. -#define X 0x1 -*/ -import "C" - -func test6128() { - // nothing to run, just make sure this compiles. - _ = C.X -} diff --git a/misc/cgo/test/issue6390.go b/misc/cgo/test/issue6390.go deleted file mode 100644 index 5642899c58..0000000000 --- a/misc/cgo/test/issue6390.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2013 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 cgotest - -// #include -import "C" - -import "testing" - -func test6390(t *testing.T) { - p1 := C.malloc(1024) - if p1 == nil { - t.Fatalf("C.malloc(1024) returned nil") - } - p2 := C.malloc(0) - if p2 == nil { - t.Fatalf("C.malloc(0) returned nil") - } - C.free(p1) - C.free(p2) -} diff --git a/misc/cgo/test/issue6472.go b/misc/cgo/test/issue6472.go deleted file mode 100644 index d416a05e29..0000000000 --- a/misc/cgo/test/issue6472.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2013 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 cgotest - -/* -typedef struct -{ - struct - { - int x; - } y[16]; -} z; -*/ -import "C" - -func test6472() { - // nothing to run, just make sure this compiles - s := new(C.z) - println(s.y[0].x) -} diff --git a/misc/cgo/test/issue6506.go b/misc/cgo/test/issue6506.go deleted file mode 100644 index c54b54b64f..0000000000 --- a/misc/cgo/test/issue6506.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2013 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 cgotest - -// Test handling of size_t in the face of incorrect clang debug information. -// golang.org/issue/6506. - -/* -#include -#include -*/ -import "C" - -func test6506() { - // nothing to run, just make sure this compiles - var x C.size_t - - C.calloc(x, x) - C.malloc(x) - C.realloc(nil, x) - C.memcpy(nil, nil, x) - C.memcmp(nil, nil, x) - C.memmove(nil, nil, x) - C.strncpy(nil, nil, x) - C.strncmp(nil, nil, x) - C.strncat(nil, nil, x) - x = C.strxfrm(nil, nil, x) - C.memchr(nil, 0, x) - x = C.strcspn(nil, nil) - x = C.strspn(nil, nil) - C.memset(nil, 0, x) - x = C.strlen(nil) - _ = x -} diff --git a/misc/cgo/test/issue6612.go b/misc/cgo/test/issue6612.go deleted file mode 100644 index 15a12fab38..0000000000 --- a/misc/cgo/test/issue6612.go +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2013 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. - -// golang.org/issue/6612 -// Test new scheme for deciding whether C.name is an expression, type, constant. -// Clang silences some warnings when the name is a #defined macro, so test those too -// (even though we now use errors exclusively, not warnings). - -package cgotest - -/* -void myfunc(void) {} -int myvar = 5; -const char *mytext = "abcdef"; -typedef int mytype; -enum { - myenum = 1234, -}; - -#define myfunc_def myfunc -#define myvar_def myvar -#define mytext_def mytext -#define mytype_def mytype -#define myenum_def myenum -#define myint_def 12345 -#define myfloat_def 1.5 -#define mystring_def "hello" -*/ -import "C" - -import "testing" - -func testNaming(t *testing.T) { - C.myfunc() - C.myfunc_def() - if v := C.myvar; v != 5 { - t.Errorf("C.myvar = %d, want 5", v) - } - if v := C.myvar_def; v != 5 { - t.Errorf("C.myvar_def = %d, want 5", v) - } - if s := C.GoString(C.mytext); s != "abcdef" { - t.Errorf("C.mytext = %q, want %q", s, "abcdef") - } - if s := C.GoString(C.mytext_def); s != "abcdef" { - t.Errorf("C.mytext_def = %q, want %q", s, "abcdef") - } - if c := C.myenum; c != 1234 { - t.Errorf("C.myenum = %v, want 1234", c) - } - if c := C.myenum_def; c != 1234 { - t.Errorf("C.myenum_def = %v, want 1234", c) - } - { - const c = C.myenum - if c != 1234 { - t.Errorf("C.myenum as const = %v, want 1234", c) - } - } - { - const c = C.myenum_def - if c != 1234 { - t.Errorf("C.myenum as const = %v, want 1234", c) - } - } - if c := C.myint_def; c != 12345 { - t.Errorf("C.myint_def = %v, want 12345", c) - } - { - const c = C.myint_def - if c != 12345 { - t.Errorf("C.myint as const = %v, want 12345", c) - } - } - - if c := C.myfloat_def; c != 1.5 { - t.Errorf("C.myint_def = %v, want 1.5", c) - } - { - const c = C.myfloat_def - if c != 1.5 { - t.Errorf("C.myint as const = %v, want 1.5", c) - } - } - - if s := C.mystring_def; s != "hello" { - t.Errorf("C.mystring_def = %q, want %q", s, "hello") - } -} diff --git a/misc/cgo/test/issue6833.go b/misc/cgo/test/issue6833.go deleted file mode 100644 index de60dbfcf2..0000000000 --- a/misc/cgo/test/issue6833.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2013 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 cgotest - -/* -extern unsigned long long issue6833Func(unsigned int, unsigned long long); -*/ -import "C" - -import "testing" - -//export GoIssue6833Func -func GoIssue6833Func(aui uint, aui64 uint64) uint64 { - return aui64 + uint64(aui) -} - -func test6833(t *testing.T) { - ui := 7 - ull := uint64(0x4000300020001000) - v := uint64(C.issue6833Func(C.uint(ui), C.ulonglong(ull))) - exp := uint64(ui) + ull - if v != exp { - t.Errorf("issue6833Func() returns %x, expected %x", v, exp) - } -} diff --git a/misc/cgo/test/issue6907.go b/misc/cgo/test/issue6907.go deleted file mode 100644 index 00495ab8e2..0000000000 --- a/misc/cgo/test/issue6907.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2017 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 cgotest - -/* -#include -#include - -char* Issue6907CopyString(_GoString_ s) { - size_t n; - const char *p; - char *r; - - n = _GoStringLen(s); - p = _GoStringPtr(s); - r = malloc(n + 1); - memmove(r, p, n); - r[n] = '\0'; - return r; -} -*/ -import "C" - -import "testing" - -func test6907(t *testing.T) { - want := "yarn" - if got := C.GoString(C.Issue6907CopyString(want)); got != want { - t.Errorf("C.GoString(C.Issue6907CopyString(%q)) == %q, want %q", want, got, want) - } -} diff --git a/misc/cgo/test/issue6907export.go b/misc/cgo/test/issue6907export.go deleted file mode 100644 index d41899e1a6..0000000000 --- a/misc/cgo/test/issue6907export.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2017 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 cgotest - -/* -extern int CheckIssue6907C(_GoString_); -*/ -import "C" - -import ( - "testing" -) - -const CString = "C string" - -//export CheckIssue6907Go -func CheckIssue6907Go(s string) C.int { - if s == CString { - return 1 - } - return 0 -} - -func test6907Go(t *testing.T) { - if got := C.CheckIssue6907C(CString); got != 1 { - t.Errorf("C.CheckIssue6907C() == %d, want %d", got, 1) - } -} diff --git a/misc/cgo/test/issue7560.go b/misc/cgo/test/issue7560.go deleted file mode 100644 index f36d8a1023..0000000000 --- a/misc/cgo/test/issue7560.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -/* -#include - -typedef struct { - char x; - long y; -} __attribute__((__packed__)) misaligned; - -int -offset7560(void) -{ - return (uintptr_t)&((misaligned*)0)->y; -} -*/ -import "C" - -import ( - "reflect" - "testing" -) - -func test7560(t *testing.T) { - // some mingw don't implement __packed__ correctly. - if C.offset7560() != 1 { - t.Skip("C compiler did not pack struct") - } - - // C.misaligned should have x but then a padding field to get to the end of the struct. - // There should not be a field named 'y'. - var v C.misaligned - rt := reflect.TypeOf(&v).Elem() - if rt.NumField() != 2 || rt.Field(0).Name != "x" || rt.Field(1).Name != "_" { - t.Errorf("unexpected fields in C.misaligned:\n") - for i := 0; i < rt.NumField(); i++ { - t.Logf("%+v\n", rt.Field(i)) - } - } -} diff --git a/misc/cgo/test/issue7665.go b/misc/cgo/test/issue7665.go deleted file mode 100644 index ce0345845f..0000000000 --- a/misc/cgo/test/issue7665.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2013 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 cgotest - -import ( - "testing" - "unsafe" -) - -// extern void f7665(void); -import "C" - -//export f7665 -func f7665() {} - -var bad7665 unsafe.Pointer = C.f7665 -var good7665 uintptr = uintptr(C.f7665) - -func test7665(t *testing.T) { - if bad7665 == nil || uintptr(bad7665) != good7665 { - t.Errorf("ptrs = %p, %#x, want same non-nil pointer", bad7665, good7665) - } -} diff --git a/misc/cgo/test/issue7786.go b/misc/cgo/test/issue7786.go deleted file mode 100644 index 1344e9eda6..0000000000 --- a/misc/cgo/test/issue7786.go +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2013 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. - -// Issue 7786. No runtime test, just make sure that typedef and struct/union/class are interchangeable at compile time. - -package cgotest - -// struct test7786; -// typedef struct test7786 typedef_test7786; -// void f7786(struct test7786 *ctx) {} -// void g7786(typedef_test7786 *ctx) {} -// -// typedef struct body7786 typedef_body7786; -// struct body7786 { int x; }; -// void b7786(struct body7786 *ctx) {} -// void c7786(typedef_body7786 *ctx) {} -// -// typedef union union7786 typedef_union7786; -// void u7786(union union7786 *ctx) {} -// void v7786(typedef_union7786 *ctx) {} -import "C" - -func f() { - var x1 *C.typedef_test7786 - var x2 *C.struct_test7786 - x1 = x2 - x2 = x1 - C.f7786(x1) - C.f7786(x2) - C.g7786(x1) - C.g7786(x2) - - var b1 *C.typedef_body7786 - var b2 *C.struct_body7786 - b1 = b2 - b2 = b1 - C.b7786(b1) - C.b7786(b2) - C.c7786(b1) - C.c7786(b2) - - var u1 *C.typedef_union7786 - var u2 *C.union_union7786 - u1 = u2 - u2 = u1 - C.u7786(u1) - C.u7786(u2) - C.v7786(u1) - C.v7786(u2) -} diff --git a/misc/cgo/test/issue7978.go b/misc/cgo/test/issue7978.go deleted file mode 100644 index b057e3eacb..0000000000 --- a/misc/cgo/test/issue7978.go +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 7978. Stack tracing didn't work during cgo code after calling a Go -// callback. Make sure GC works and the stack trace is correct. - -package cgotest - -/* -#include - -void issue7978cb(void); - -#if defined(__APPLE__) && defined(__arm__) -// on Darwin/ARM, libSystem doesn't provide implementation of the __sync_fetch_and_add -// primitive, and although gcc supports it, it doesn't inline its definition. -// Clang could inline its definition, so we require clang on Darwin/ARM. -#if defined(__clang__) -#define HAS_SYNC_FETCH_AND_ADD 1 -#else -#define HAS_SYNC_FETCH_AND_ADD 0 -#endif -#else -#define HAS_SYNC_FETCH_AND_ADD 1 -#endif - -// use ugly atomic variable sync since that doesn't require calling back into -// Go code or OS dependencies -static void issue7978c(uint32_t *sync) { -#if HAS_SYNC_FETCH_AND_ADD - while(__sync_fetch_and_add(sync, 0) != 0) - ; - __sync_fetch_and_add(sync, 1); - while(__sync_fetch_and_add(sync, 0) != 2) - ; - issue7978cb(); - __sync_fetch_and_add(sync, 1); - while(__sync_fetch_and_add(sync, 0) != 6) - ; -#endif -} -*/ -import "C" - -import ( - "runtime" - "runtime/debug" - "strings" - "sync/atomic" - "testing" -) - -var issue7978sync uint32 - -func issue7978check(t *testing.T, wantFunc string, badFunc string, depth int) { - runtime.GC() - buf := make([]byte, 65536) - trace := string(buf[:runtime.Stack(buf, true)]) - for _, goroutine := range strings.Split(trace, "\n\n") { - if strings.Contains(goroutine, "test.issue7978go") { - trace := strings.Split(goroutine, "\n") - // look for the expected function in the stack - for i := 0; i < depth; i++ { - if badFunc != "" && strings.Contains(trace[1+2*i], badFunc) { - t.Errorf("bad stack: found %s in the stack:\n%s", badFunc, goroutine) - return - } - if strings.Contains(trace[1+2*i], wantFunc) { - return - } - } - t.Errorf("bad stack: didn't find %s in the stack:\n%s", wantFunc, goroutine) - return - } - } - t.Errorf("bad stack: goroutine not found. Full stack dump:\n%s", trace) -} - -func issue7978wait(store uint32, wait uint32) { - if store != 0 { - atomic.StoreUint32(&issue7978sync, store) - } - for atomic.LoadUint32(&issue7978sync) != wait { - runtime.Gosched() - } -} - -//export issue7978cb -func issue7978cb() { - // Force a stack growth from the callback to put extra - // pressure on the runtime. See issue #17785. - growStack(64) - issue7978wait(3, 4) -} - -func growStack(n int) int { - var buf [128]int - if n == 0 { - return 0 - } - return buf[growStack(n-1)] -} - -func issue7978go() { - C.issue7978c((*C.uint32_t)(&issue7978sync)) - issue7978wait(7, 8) -} - -func test7978(t *testing.T) { - if runtime.Compiler == "gccgo" { - t.Skip("gccgo can not do stack traces of C code") - } - if C.HAS_SYNC_FETCH_AND_ADD == 0 { - t.Skip("clang required for __sync_fetch_and_add support on darwin/arm") - } - debug.SetTraceback("2") - issue7978sync = 0 - go issue7978go() - // test in c code, before callback - issue7978wait(0, 1) - issue7978check(t, "_Cfunc_issue7978c(", "", 1) - // test in go code, during callback - issue7978wait(2, 3) - issue7978check(t, "test.issue7978cb(", "test.issue7978go", 3) - // test in c code, after callback - issue7978wait(4, 5) - issue7978check(t, "_Cfunc_issue7978c(", "_cgoexpwrap", 1) - // test in go code, after return from cgo - issue7978wait(6, 7) - issue7978check(t, "test.issue7978go(", "", 3) - atomic.StoreUint32(&issue7978sync, 8) -} diff --git a/misc/cgo/test/issue8092.go b/misc/cgo/test/issue8092.go deleted file mode 100644 index 19123e79cf..0000000000 --- a/misc/cgo/test/issue8092.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 8092. Test that linker defined symbols (e.g., text, data) don't -// conflict with C symbols. - -package cgotest - -/* -char text[] = "text"; -char data[] = "data"; -char *ctext(void) { return text; } -char *cdata(void) { return data; } -*/ -import "C" - -import "testing" - -func test8092(t *testing.T) { - tests := []struct { - s string - a, b *C.char - }{ - {"text", &C.text[0], C.ctext()}, - {"data", &C.data[0], C.cdata()}, - } - for _, test := range tests { - if test.a != test.b { - t.Errorf("%s: pointer mismatch: %v != %v", test.s, test.a, test.b) - } - if got := C.GoString(test.a); got != test.s { - t.Errorf("%s: points at %#v, want %#v", test.s, got, test.s) - } - } -} diff --git a/misc/cgo/test/issue8331a.go b/misc/cgo/test/issue8331a.go deleted file mode 100644 index 92e2579e7a..0000000000 --- a/misc/cgo/test/issue8331a.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 8331. A typedef of an unnamed struct is the same struct when -// #include'd twice. No runtime test; just make sure it compiles. - -package cgotest - -// #include "issue8331.h" -import "C" - -func issue8331a() C.issue8331 { - return issue8331Var -} diff --git a/misc/cgo/test/issue8331b.go b/misc/cgo/test/issue8331b.go deleted file mode 100644 index 5324aa2a17..0000000000 --- a/misc/cgo/test/issue8331b.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 8331. A typedef of an unnamed struct is the same struct when -// #include'd twice. No runtime test; just make sure it compiles. - -package cgotest - -// #include "issue8331.h" -import "C" - -var issue8331Var C.issue8331 diff --git a/misc/cgo/test/issue8428.go b/misc/cgo/test/issue8428.go deleted file mode 100644 index 2e5a555b58..0000000000 --- a/misc/cgo/test/issue8428.go +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This test fails on older versions of OS X because they use older buggy -// versions of Clang that emit ambiguous DWARF info. See issue 8611. -// +build !darwin - -package cgotest - -// Issue 8428. Cgo inconsistently translated zero size arrays. - -/* -struct issue8428one { - char b; - char rest[]; -}; - -struct issue8428two { - void *p; - char b; - char rest[0]; - char pad; -}; - -struct issue8428three { - char w[1][2][3][0]; - char x[2][3][0][1]; - char y[3][0][1][2]; - char z[0][1][2][3]; -}; -*/ -import "C" - -import "unsafe" - -var _ = C.struct_issue8428one{ - b: C.char(0), - // The trailing rest field is not available in cgo. - // See issue 11925. - // rest: [0]C.char{}, -} - -var _ = C.struct_issue8428two{ - p: unsafe.Pointer(nil), - b: C.char(0), - rest: [0]C.char{}, -} - -var _ = C.struct_issue8428three{ - w: [1][2][3][0]C.char{}, - x: [2][3][0][1]C.char{}, - y: [3][0][1][2]C.char{}, - z: [0][1][2][3]C.char{}, -} diff --git a/misc/cgo/test/issue8441.go b/misc/cgo/test/issue8441.go deleted file mode 100644 index 4489ca9eb6..0000000000 --- a/misc/cgo/test/issue8441.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 8368 and 8441. Recursive struct definitions didn't work. -// No runtime test; just make sure it compiles. - -package cgotest - -/* -typedef struct one one; -typedef struct two two; -struct one { - two *x; -}; -struct two { - one *x; -}; -*/ -import "C" - -func issue8368(one *C.struct_one, two *C.struct_two) { -} - -func issue8441(one *C.one, two *C.two) { - issue8441(two.x, one.x) -} diff --git a/misc/cgo/test/issue8811.go b/misc/cgo/test/issue8811.go deleted file mode 100644 index f812732cfd..0000000000 --- a/misc/cgo/test/issue8811.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -/* -extern int issue8811Initialized; -extern void issue8811Init(); - -void issue8811Execute() { - if(!issue8811Initialized) - issue8811Init(); -} -*/ -import "C" - -import "testing" - -func test8811(t *testing.T) { - C.issue8811Execute() -} diff --git a/misc/cgo/test/issue9557.go b/misc/cgo/test/issue9557.go deleted file mode 100644 index 4e8922a69c..0000000000 --- a/misc/cgo/test/issue9557.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// cgo rewrote C.var to *_Cvar_var, but left -// C.var.field as _Cvar.var.field. It now rewrites -// the latter as (*_Cvar_var).field. -// See https://golang.org/issue/9557. - -package cgotest - -// struct issue9557_t { -// int a; -// } test9557bar = { 42 }; -// -// struct issue9557_t *issue9557foo = &test9557bar; -import "C" -import "testing" - -func test9557(t *testing.T) { - // implicitly dereference a Go variable - foo := C.issue9557foo - if v := foo.a; v != 42 { - t.Fatalf("foo.a expected 42, but got %d", v) - } - - // explicitly dereference a C variable - if v := (*C.issue9557foo).a; v != 42 { - t.Fatalf("(*C.issue9557foo).a expected 42, but is %d", v) - } - - // implicitly dereference a C variable - if v := C.issue9557foo.a; v != 42 { - t.Fatalf("C.issue9557foo.a expected 42, but is %d", v) - } -} diff --git a/misc/cgo/test/test.go b/misc/cgo/test/test.go new file mode 100644 index 0000000000..b23fca0d0f --- /dev/null +++ b/misc/cgo/test/test.go @@ -0,0 +1,2087 @@ +// Copyright 2010 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. + +// Test cases for cgo. +// Both the import "C" prologue and the main file are sorted by issue number. +// This file contains C definitions (not just declarations) +// and so it must NOT contain any //export directives on Go functions. +// See testx.go for exports. + +package cgotest + +/* +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#cgo LDFLAGS: -lm + +#ifndef WIN32 +#include +#include +#endif + +// alignment tests + +typedef unsigned char Uint8; +typedef unsigned short Uint16; + +typedef enum { + MOD1 = 0x0000, + MODX = 0x8000 +} SDLMod; + +typedef enum { + A1 = 1, + B1 = 322, + SDLK_LAST +} SDLKey; + +typedef struct SDL_keysym { + Uint8 scancode; + SDLKey sym; + SDLMod mod; + Uint16 unicode; +} SDL_keysym; + +typedef struct SDL_KeyboardEvent { + Uint8 typ; + Uint8 which; + Uint8 state; + SDL_keysym keysym; +} SDL_KeyboardEvent; + +void makeEvent(SDL_KeyboardEvent *event) { + unsigned char *p; + int i; + + p = (unsigned char*)event; + for (i=0; ityp == typ && e->which == which && e->state == state && e->keysym.scancode == scan && e->keysym.sym == sym && e->keysym.mod == mod && e->keysym.unicode == uni; +} + +void cTest(SDL_KeyboardEvent *event) { + printf("C: %#x %#x %#x %#x %#x %#x %#x\n", event->typ, event->which, event->state, + event->keysym.scancode, event->keysym.sym, event->keysym.mod, event->keysym.unicode); + fflush(stdout); +} + +// api + +const char *greeting = "hello, world"; + +// basic test cases + +#define SHIFT(x, y) ((x)<<(y)) +#define KILO SHIFT(1, 10) +#define UINT32VAL 0xc008427bU + +enum E { + Enum1 = 1, + Enum2 = 2, +}; + +typedef unsigned char cgo_uuid_t[20]; + +void uuid_generate(cgo_uuid_t x) { + x[0] = 0; +} + +struct S { + int x; +}; + +const char *cstr = "abcefghijklmnopqrstuvwxyzABCEFGHIJKLMNOPQRSTUVWXYZ1234567890"; + +extern enum E myConstFunc(struct S* const ctx, int const id, struct S **const filter); + +enum E myConstFunc(struct S *const ctx, int const id, struct S **const filter) { return 0; } + +int add(int x, int y) { + return x+y; +}; + +// complex alignment + +struct { + float x; + _Complex float y; +} cplxAlign = { 3.14, 2.17 }; + +// constants and pointer checking + +#define CheckConstVal 0 + +typedef struct { + int *p; +} CheckConstStruct; + +static void CheckConstFunc(CheckConstStruct *p, int e) {} + +// duplicate symbol + +int base_symbol = 0; +#define alias_one base_symbol +#define alias_two base_symbol + +// function pointer variables + +typedef int (*intFunc) (); + +int +bridge_int_func(intFunc f) +{ + return f(); +} + +int fortytwo() +{ + return 42; +} + +// issue 1222 +typedef union { + long align; +} xxpthread_mutex_t; +struct ibv_async_event { + union { + int x; + } element; +}; +struct ibv_context { + xxpthread_mutex_t mutex; +}; + +// issue 1635 +// Mac OS X's gcc will generate scattered relocation 2/1 for +// this function on Darwin/386, and 8l couldn't handle it. +// this example is in issue 1635 +void scatter() { + void *p = scatter; + printf("scatter = %p\n", p); +} + +// Adding this explicit extern declaration makes this a test for +// https://gcc.gnu.org/PR68072 aka https://golang.org/issue/13344 . +// It used to cause a cgo error when building with GCC 6. +extern int hola; + +// this example is in issue 3253 +int hola = 0; +int testHola() { return hola; } + +// issue 3250 +#ifdef WIN32 +void testSendSIG() {} +#else +static void *thread(void *p) { + const int M = 100; + int i; + (void)p; + for (i = 0; i < M; i++) { + pthread_kill(pthread_self(), SIGCHLD); + usleep(rand() % 20 + 5); + } + return NULL; +} +void testSendSIG() { + const int N = 20; + int i; + pthread_t tid[N]; + for (i = 0; i < N; i++) { + usleep(rand() % 200 + 100); + pthread_create(&tid[i], 0, thread, NULL); + } + for (i = 0; i < N; i++) + pthread_join(tid[i], 0); +} +#endif + +// issue 3261 +// libgcc on ARM might be compiled as thumb code, but our 5l +// can't handle that, so we have to disable this test on arm. +#ifdef __ARMEL__ +int vabs(int x) { + puts("testLibgcc is disabled on ARM because 5l cannot handle thumb library."); + return (x < 0) ? -x : x; +} +#elif defined(__arm64__) && defined(__clang__) +int vabs(int x) { + puts("testLibgcc is disabled on ARM64 with clang due to lack of libgcc."); + return (x < 0) ? -x : x; +} +#else +int __absvsi2(int); // dummy prototype for libgcc function +// we shouldn't name the function abs, as gcc might use +// the builtin one. +int vabs(int x) { return __absvsi2(x); } +#endif + + +// issue 3729 +// access errno from void C function +const char _expA = 0x42; +const float _expB = 3.14159; +const short _expC = 0x55aa; +const int _expD = 0xdeadbeef; + +#ifdef WIN32 +void g(void) {} +void g2(int x, char a, float b, short c, int d) {} +#else + +void g(void) { + errno = E2BIG; +} + +// try to pass some non-trivial arguments to function g2 +void g2(int x, char a, float b, short c, int d) { + if (a == _expA && b == _expB && c == _expC && d == _expD) + errno = x; + else + errno = -1; +} +#endif + +// issue 3945 +// Test that cgo reserves enough stack space during cgo call. +// See https://golang.org/issue/3945 for details. +void say() { + printf("%s from C\n", "hello"); +} + +// issue 4054 part 1 - other half in testx.go + +typedef enum { + A = 0, + B, + C, + D, + E, + F, + G, + H, + II, + J, +} issue4054a; + +// issue 4339 +// We've historically permitted #include <>, so test it here. Issue 29333. +#include + +// issue 4417 +// cmd/cgo: bool alignment/padding issue. +// bool alignment is wrong and causing wrong arguments when calling functions. +static int c_bool(bool a, bool b, int c, bool d, bool e) { + return c; +} + +// issue 4857 +#cgo CFLAGS: -Werror +const struct { int a; } *issue4857() { return (void *)0; } + +// issue 5224 +// Test that the #cgo CFLAGS directive works, +// with and without platform filters. +#cgo CFLAGS: -DCOMMON_VALUE=123 +#cgo windows CFLAGS: -DIS_WINDOWS=1 +#cgo !windows CFLAGS: -DIS_WINDOWS=0 +int common = COMMON_VALUE; +int is_windows = IS_WINDOWS; + +// issue 5227 +// linker incorrectly treats common symbols and +// leaves them undefined. + +typedef struct { + int Count; +} Fontinfo; + +Fontinfo SansTypeface; + +extern void init(); + +Fontinfo loadfont() { + Fontinfo f = {0}; + return f; +} + +void init() { + SansTypeface = loadfont(); +} + +// issue 5242 +// Cgo incorrectly computed the alignment of structs +// with no Go accessible fields as 0, and then panicked on +// modulo-by-zero computations. +typedef struct { +} foo; + +typedef struct { + int x : 1; +} bar; + +int issue5242(foo f, bar b) { + return 5242; +} + +// issue 5337 +// Verify that we can withstand SIGPROF received on foreign threads + +#ifdef WIN32 +void test5337() {} +#else +static void *thread1(void *p) { + (void)p; + pthread_kill(pthread_self(), SIGPROF); + return NULL; +} +void test5337() { + pthread_t tid; + pthread_create(&tid, 0, thread1, NULL); + pthread_join(tid, 0); +} +#endif + +// issue 5603 + +const long long issue5603exp = 0x12345678; +long long issue5603foo0() { return issue5603exp; } +long long issue5603foo1(void *p) { return issue5603exp; } +long long issue5603foo2(void *p, void *q) { return issue5603exp; } +long long issue5603foo3(void *p, void *q, void *r) { return issue5603exp; } +long long issue5603foo4(void *p, void *q, void *r, void *s) { return issue5603exp; } + +// issue 5740 + +int test5740a(void), test5740b(void); + +// issue 5986 +static void output5986() +{ + int current_row = 0, row_count = 0; + double sum_squares = 0; + double d; + do { + if (current_row == 10) { + current_row = 0; + } + ++row_count; + } + while (current_row++ != 1); + d = sqrt(sum_squares / row_count); + printf("sqrt is: %g\n", d); +} + +// issue 6128 +// Test handling of #defined names in clang. +// NOTE: Must use hex, or else a shortcut for decimals +// in cgo avoids trying to pass this to clang. +#define X 0x1 + +// issue 6472 +typedef struct +{ + struct + { + int x; + } y[16]; +} z; + +// issue 6612 +// Test new scheme for deciding whether C.name is an expression, type, constant. +// Clang silences some warnings when the name is a #defined macro, so test those too +// (even though we now use errors exclusively, not warnings). + +void myfunc(void) {} +int myvar = 5; +const char *mytext = "abcdef"; +typedef int mytype; +enum { + myenum = 1234, +}; + +#define myfunc_def myfunc +#define myvar_def myvar +#define mytext_def mytext +#define mytype_def mytype +#define myenum_def myenum +#define myint_def 12345 +#define myfloat_def 1.5 +#define mystring_def "hello" + +// issue 6907 +char* Issue6907CopyString(_GoString_ s) { + size_t n; + const char *p; + char *r; + + n = _GoStringLen(s); + p = _GoStringPtr(s); + r = malloc(n + 1); + memmove(r, p, n); + r[n] = '\0'; + return r; +} + +// issue 7560 +typedef struct { + char x; + long y; +} __attribute__((__packed__)) misaligned; + +int +offset7560(void) +{ + return (uintptr_t)&((misaligned*)0)->y; +} + +// issue 7786 +// No runtime test, just make sure that typedef and struct/union/class are interchangeable at compile time. + +struct test7786; +typedef struct test7786 typedef_test7786; +void f7786(struct test7786 *ctx) {} +void g7786(typedef_test7786 *ctx) {} + +typedef struct body7786 typedef_body7786; +struct body7786 { int x; }; +void b7786(struct body7786 *ctx) {} +void c7786(typedef_body7786 *ctx) {} + +typedef union union7786 typedef_union7786; +void u7786(union union7786 *ctx) {} +void v7786(typedef_union7786 *ctx) {} + +// issue 8092 +// Test that linker defined symbols (e.g., text, data) don't +// conflict with C symbols. +char text[] = "text"; +char data[] = "data"; +char *ctext(void) { return text; } +char *cdata(void) { return data; } + +// issue 8428 +// Cgo inconsistently translated zero size arrays. + +struct issue8428one { + char b; + char rest[]; +}; + +struct issue8428two { + void *p; + char b; + char rest[0]; + char pad; +}; + +struct issue8428three { + char w[1][2][3][0]; + char x[2][3][0][1]; + char y[3][0][1][2]; + char z[0][1][2][3]; +}; + +// issue 8331 part 1 - part 2 in testx.go +// A typedef of an unnamed struct is the same struct when +// #include'd twice. No runtime test; just make sure it compiles. +#include "issue8331.h" + +// issue 8368 and 8441 +// Recursive struct definitions didn't work. +// No runtime test; just make sure it compiles. +typedef struct one one; +typedef struct two two; +struct one { + two *x; +}; +struct two { + one *x; +}; + +// issue 8811 + +extern int issue8811Initialized; +extern void issue8811Init(); + +void issue8811Execute() { + if(!issue8811Initialized) + issue8811Init(); +} + +// issue 9557 + +struct issue9557_t { + int a; +} test9557bar = { 42 }; +struct issue9557_t *issue9557foo = &test9557bar; + +// issue 10303 +// Pointers passed to C were not marked as escaping (bug in cgo). + +typedef int *intptr; + +void setintstar(int *x) { + *x = 1; +} + +void setintptr(intptr x) { + *x = 1; +} + +void setvoidptr(void *x) { + *(int*)x = 1; +} + +typedef struct Struct Struct; +struct Struct { + int *P; +}; + +void setstruct(Struct s) { + *s.P = 1; +} + +// issue 11925 +// Structs with zero-length trailing fields are now padded by the Go compiler. + +struct a11925 { + int i; + char a[0]; + char b[0]; +}; + +struct b11925 { + int i; + char a[0]; + char b[]; +}; + +// issue 12030 +void issue12030conv(char *buf, double x) { + sprintf(buf, "d=%g", x); +} + +// issue 14838 + +int check_cbytes(char *b, size_t l) { + int i; + for (i = 0; i < l; i++) { + if (b[i] != i) { + return 0; + } + } + return 1; +} + +// issue 17065 +// Test that C symbols larger than a page play nicely with the race detector. +int ii[65537]; + +// issue 17537 +// The void* cast introduced by cgo to avoid problems +// with const/volatile qualifiers breaks C preprocessor macros that +// emulate functions. + +typedef struct { + int i; +} S17537; + +int I17537(S17537 *p); + +#define I17537(p) ((p)->i) + +// Calling this function used to fail without the cast. +const int F17537(const char **p) { + return **p; +} + +// issue 17723 +// API compatibility checks + +typedef char *cstring_pointer; +static void cstring_pointer_fun(cstring_pointer dummy) { } +const char *api_hello = "hello!"; + +// Calling this function used to trigger an error from the C compiler +// (issue 18298). +void F18298(const void *const *p) { +} + +// Test that conversions between typedefs work as they used to. +typedef const void *T18298_1; +struct S18298 { int i; }; +typedef const struct S18298 *T18298_2; +void G18298(T18298_1 t) { +} + +// issue 18126 +// cgo check of void function returning errno. +void Issue18126C(void **p) {} + +// issue 18720 + +#define HELLO "hello" +#define WORLD "world" +#define HELLO_WORLD HELLO "\000" WORLD + +struct foo { char c; }; +#define SIZE_OF(x) sizeof(x) +#define SIZE_OF_FOO SIZE_OF(struct foo) +#define VAR1 VAR +#define VAR var +int var = 5; + +#define ADDR &var + +#define CALL fn() +int fn(void) { + return ++var; +} + +// issue 20129 + +int issue20129 = 0; +typedef void issue20129Void; +issue20129Void issue20129Foo() { + issue20129 = 1; +} +typedef issue20129Void issue20129Void2; +issue20129Void2 issue20129Bar() { + issue20129 = 2; +} + +// issue 20369 +#define XUINT64_MAX 18446744073709551615ULL + +// issue 21668 +// Fail to guess the kind of the constant "x". +// No runtime test; just make sure it compiles. +const int x21668 = 42; + +// issue 21708 +#define CAST_TO_INT64 (int64_t)(-1) + +// issue 21809 +// Compile C `typedef` to go type aliases. + +typedef long MySigned_t; +// tests alias-to-alias +typedef MySigned_t MySigned2_t; +long takes_long(long x) { return x * x; } +MySigned_t takes_typedef(MySigned_t x) { return x * x; } + +// issue 22906 + +// It's going to be hard to include a whole real JVM to test this. +// So we'll simulate a really easy JVM using just the parts we need. +// This is the relevant part of jni.h. + +struct _jobject; + +typedef struct _jobject *jobject; +typedef jobject jclass; +typedef jobject jthrowable; +typedef jobject jstring; +typedef jobject jarray; +typedef jarray jbooleanArray; +typedef jarray jbyteArray; +typedef jarray jcharArray; +typedef jarray jshortArray; +typedef jarray jintArray; +typedef jarray jlongArray; +typedef jarray jfloatArray; +typedef jarray jdoubleArray; +typedef jarray jobjectArray; + +typedef jobject jweak; + +// Note: jvalue is already a non-pointer type due to it being a C union. + +// issue 22958 + +typedef struct { + unsigned long long f8 : 8; + unsigned long long f16 : 16; + unsigned long long f24 : 24; + unsigned long long f32 : 32; + unsigned long long f40 : 40; + unsigned long long f48 : 48; + unsigned long long f56 : 56; + unsigned long long f64 : 64; +} issue22958Type; + +// issue 23356 +int a(void) { return 5; }; +int r(void) { return 3; }; + +// issue 23720 +typedef int *issue23720A; +typedef const int *issue23720B; +void issue23720F(issue23720B a) {} + +// issue 24206 +#if defined(__linux__) && defined(__x86_64__) +#include +// Returns string with null byte at the last valid address +char* dangerousString1() { + int pageSize = 4096; + char *data = mmap(0, 2 * pageSize, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0); + mprotect(data + pageSize,pageSize,PROT_NONE); + int start = pageSize - 123 - 1; // last 123 bytes of first page + 1 null byte + int i = start; + for (; i < pageSize; i++) { + data[i] = 'x'; + } + data[pageSize -1 ] = 0; + return data+start; +} + +char* dangerousString2() { + int pageSize = 4096; + char *data = mmap(0, 3 * pageSize, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0); + mprotect(data + 2 * pageSize,pageSize,PROT_NONE); + int start = pageSize - 123 - 1; // last 123 bytes of first page + 1 null byte + int i = start; + for (; i < 2 * pageSize; i++) { + data[i] = 'x'; + } + data[2*pageSize -1 ] = 0; + return data+start; +} +#else +char *dangerousString1() { return NULL; } +char *dangerousString2() { return NULL; } +#endif + +// issue 26066 +const unsigned long long int issue26066 = (const unsigned long long) -1; + +// issue 26517 +// Introduce two pointer types which are distinct, but have the same +// base type. Make sure that both of those pointer types get resolved +// correctly. Before the fix for 26517 if one of these pointer types +// was resolved before the other one was processed, the second one +// would never be resolved. +// Before this issue was fixed this test failed on Windows, +// where va_list expands to a named char* type. +typedef va_list TypeOne; +typedef char *TypeTwo; + +// issue 28540 + +static void twoargs1(void *p, int n) {} +static void *twoargs2() { return 0; } +static int twoargs3(void * p) { return 0; } + +// issue 28545 +// Failed to add type conversion for negative constant. + +static void issue28545F(char **p, int n, complex double a) {} + +// issue 28772 part 1 - part 2 in testx.go +// Failed to add type conversion for Go constant set to C constant. +// No runtime test; just make sure it compiles. + +#define issue28772Constant 1 + +// issue 28896 +// cgo was incorrectly adding padding after a packed struct. +typedef struct { + void *f1; + uint32_t f2; +} __attribute__((__packed__)) innerPacked; + +typedef struct { + innerPacked g1; + uint64_t g2; +} outerPacked; + +typedef struct { + void *f1; + uint32_t f2; +} innerUnpacked; + +typedef struct { + innerUnpacked g1; + uint64_t g2; +} outerUnpacked; + +size_t offset(int x) { + switch (x) { + case 0: + return offsetof(innerPacked, f2); + case 1: + return offsetof(outerPacked, g2); + case 2: + return offsetof(innerUnpacked, f2); + case 3: + return offsetof(outerUnpacked, g2); + default: + abort(); + } +} + +// issue 29748 + +typedef struct { char **p; } S29748; +static int f29748(S29748 *p) { return 0; } + +// issue 29781 +// Error with newline inserted into constant expression. +// Compilation test only, nothing to run. + +static void issue29781F(char **p, int n) {} +#define ISSUE29781C 0 + +// issue 29878 +uint64_t issue29878exported(int8_t); // prototype must match +int16_t issue29878function(uint32_t arg) { return issue29878exported(arg); } + +*/ +import "C" + +import ( + "context" + "fmt" + "math" + "math/rand" + "os" + "os/signal" + "reflect" + "runtime" + "sync" + "syscall" + "testing" + "time" + "unsafe" +) + +// alignment + +func testAlign(t *testing.T) { + var evt C.SDL_KeyboardEvent + C.makeEvent(&evt) + if C.same(&evt, evt.typ, evt.which, evt.state, evt.keysym.scancode, evt.keysym.sym, evt.keysym.mod, evt.keysym.unicode) == 0 { + t.Error("*** bad alignment") + C.cTest(&evt) + t.Errorf("Go: %#x %#x %#x %#x %#x %#x %#x\n", + evt.typ, evt.which, evt.state, evt.keysym.scancode, + evt.keysym.sym, evt.keysym.mod, evt.keysym.unicode) + t.Error(evt) + } +} + +// api + +const greeting = "hello, world" + +type testPair struct { + Name string + Got, Want interface{} +} + +var testPairs = []testPair{ + {"GoString", C.GoString(C.greeting), greeting}, + {"GoStringN", C.GoStringN(C.greeting, 5), greeting[:5]}, + {"GoBytes", C.GoBytes(unsafe.Pointer(C.greeting), 5), []byte(greeting[:5])}, +} + +func testHelpers(t *testing.T) { + for _, pair := range testPairs { + if !reflect.DeepEqual(pair.Got, pair.Want) { + t.Errorf("%s: got %#v, want %#v", pair.Name, pair.Got, pair.Want) + } + } +} + +// basic test cases + +const EINVAL = C.EINVAL /* test #define */ + +var KILO = C.KILO + +func uuidgen() { + var uuid C.cgo_uuid_t + C.uuid_generate(&uuid[0]) +} + +func Strtol(s string, base int) (int, error) { + p := C.CString(s) + n, err := C.strtol(p, nil, C.int(base)) + C.free(unsafe.Pointer(p)) + return int(n), err +} + +func Atol(s string) int { + p := C.CString(s) + n := C.atol(p) + C.free(unsafe.Pointer(p)) + return int(n) +} + +func testConst(t *testing.T) { + C.myConstFunc(nil, 0, nil) +} + +func testEnum(t *testing.T) { + if C.Enum1 != 1 || C.Enum2 != 2 { + t.Error("bad enum", C.Enum1, C.Enum2) + } +} + +func testAtol(t *testing.T) { + l := Atol("123") + if l != 123 { + t.Error("Atol 123: ", l) + } +} + +func testErrno(t *testing.T) { + p := C.CString("no-such-file") + m := C.CString("r") + f, err := C.fopen(p, m) + C.free(unsafe.Pointer(p)) + C.free(unsafe.Pointer(m)) + if err == nil { + C.fclose(f) + t.Fatalf("C.fopen: should fail") + } + if err != syscall.ENOENT { + t.Fatalf("C.fopen: unexpected error: %v", err) + } +} + +func testMultipleAssign(t *testing.T) { + p := C.CString("234") + n, m := C.strtol(p, nil, 345), C.strtol(p, nil, 10) + if runtime.GOOS == "openbsd" { + // Bug in OpenBSD strtol(3) - base > 36 succeeds. + if (n != 0 && n != 239089) || m != 234 { + t.Fatal("Strtol x2: ", n, m) + } + } else if n != 0 || m != 234 { + t.Fatal("Strtol x2: ", n, m) + } + C.free(unsafe.Pointer(p)) +} + +var ( + cuint = (C.uint)(0) + culong C.ulong + cchar C.char +) + +type Context struct { + ctx *C.struct_ibv_context +} + +func benchCgoCall(b *testing.B) { + const x = C.int(2) + const y = C.int(3) + for i := 0; i < b.N; i++ { + C.add(x, y) + } +} + +var sinkString string + +func benchGoString(b *testing.B) { + for i := 0; i < b.N; i++ { + sinkString = C.GoString(C.cstr) + } + const want = "abcefghijklmnopqrstuvwxyzABCEFGHIJKLMNOPQRSTUVWXYZ1234567890" + if sinkString != want { + b.Fatalf("%q != %q", sinkString, want) + } +} + +// Static (build-time) test that syntax traversal visits all operands of s[i:j:k]. +func sliceOperands(array [2000]int) { + _ = array[C.KILO:C.KILO:C.KILO] // no type error +} + +// set in cgo_thread_lock.go init +var testThreadLockFunc = func(*testing.T) {} + +// complex alignment + +func TestComplexAlign(t *testing.T) { + if C.cplxAlign.x != 3.14 { + t.Errorf("got %v, expected 3.14", C.cplxAlign.x) + } + if C.cplxAlign.y != 2.17 { + t.Errorf("got %v, expected 2.17", C.cplxAlign.y) + } +} + +// constants and pointer checking + +func testCheckConst(t *testing.T) { + // The test is that this compiles successfully. + p := C.malloc(C.size_t(unsafe.Sizeof(C.int(0)))) + defer C.free(p) + C.CheckConstFunc(&C.CheckConstStruct{(*C.int)(p)}, C.CheckConstVal) +} + +// duplicate symbol + +func duplicateSymbols() { + fmt.Printf("%v %v %v\n", C.base_symbol, C.alias_one, C.alias_two) +} + +// environment + +// This is really an os package test but here for convenience. +func testSetEnv(t *testing.T) { + if runtime.GOOS == "windows" { + // Go uses SetEnvironmentVariable on windows. However, + // C runtime takes a *copy* at process startup of the + // OS environment, and stores it in environ/envp. + // It is this copy that getenv/putenv manipulate. + t.Logf("skipping test") + return + } + const key = "CGO_OS_TEST_KEY" + const val = "CGO_OS_TEST_VALUE" + os.Setenv(key, val) + keyc := C.CString(key) + defer C.free(unsafe.Pointer(keyc)) + v := C.getenv(keyc) + if uintptr(unsafe.Pointer(v)) == 0 { + t.Fatal("getenv returned NULL") + } + vs := C.GoString(v) + if vs != val { + t.Fatalf("getenv() = %q; want %q", vs, val) + } +} + +// function pointer variables + +func callBridge(f C.intFunc) int { + return int(C.bridge_int_func(f)) +} + +func callCBridge(f C.intFunc) C.int { + return C.bridge_int_func(f) +} + +func testFpVar(t *testing.T) { + const expected = 42 + f := C.intFunc(C.fortytwo) + res1 := C.bridge_int_func(f) + if r1 := int(res1); r1 != expected { + t.Errorf("got %d, want %d", r1, expected) + } + res2 := callCBridge(f) + if r2 := int(res2); r2 != expected { + t.Errorf("got %d, want %d", r2, expected) + } + r3 := callBridge(f) + if r3 != expected { + t.Errorf("got %d, want %d", r3, expected) + } +} + +// issue 1222 +type AsyncEvent struct { + event C.struct_ibv_async_event +} + +// issue 1635 + +func test1635(t *testing.T) { + C.scatter() + if v := C.hola; v != 0 { + t.Fatalf("C.hola is %d, should be 0", v) + } + if v := C.testHola(); v != 0 { + t.Fatalf("C.testHola() is %d, should be 0", v) + } +} + +// issue 2470 + +func testUnsignedInt(t *testing.T) { + a := (int64)(C.UINT32VAL) + b := (int64)(0xc008427b) + if a != b { + t.Errorf("Incorrect unsigned int - got %x, want %x", a, b) + } +} + +// issue 3250 + +func test3250(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("not applicable on windows") + } + + t.Skip("skipped, see golang.org/issue/5885") + var ( + thres = 1 + sig = syscall_dot_SIGCHLD + ) + type result struct { + n int + sig os.Signal + } + var ( + sigCh = make(chan os.Signal, 10) + waitStart = make(chan struct{}) + waitDone = make(chan result) + ) + + signal.Notify(sigCh, sig) + + go func() { + n := 0 + alarm := time.After(time.Second * 3) + for { + select { + case <-waitStart: + waitStart = nil + case v := <-sigCh: + n++ + if v != sig || n > thres { + waitDone <- result{n, v} + return + } + case <-alarm: + waitDone <- result{n, sig} + return + } + } + }() + + waitStart <- struct{}{} + C.testSendSIG() + r := <-waitDone + if r.sig != sig { + t.Fatalf("received signal %v, but want %v", r.sig, sig) + } + t.Logf("got %d signals\n", r.n) + if r.n <= thres { + t.Fatalf("expected more than %d", thres) + } +} + +// issue 3261 + +func testLibgcc(t *testing.T) { + var table = []struct { + in, out C.int + }{ + {0, 0}, + {1, 1}, + {-42, 42}, + {1000300, 1000300}, + {1 - 1<<31, 1<<31 - 1}, + } + for _, v := range table { + if o := C.vabs(v.in); o != v.out { + t.Fatalf("abs(%d) got %d, should be %d", v.in, o, v.out) + return + } + } +} + +// issue 3729 + +func test3729(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("skipping on windows") + } + + _, e := C.g() + if e != syscall.E2BIG { + t.Errorf("got %q, expect %q", e, syscall.E2BIG) + } + _, e = C.g2(C.EINVAL, C._expA, C._expB, C._expC, C._expD) + if e != syscall.EINVAL { + t.Errorf("got %q, expect %q", e, syscall.EINVAL) + } +} + +// issue 3945 + +func testPrintf(t *testing.T) { + C.say() +} + +// issue 4054 + +var issue4054a = []int{C.A, C.B, C.C, C.D, C.E, C.F, C.G, C.H, C.I, C.J} + +// issue 4339 + +func test4339(t *testing.T) { + C.handle4339(&C.exported4339) +} + +// issue 4417 + +func testBoolAlign(t *testing.T) { + b := C.c_bool(true, true, 10, true, false) + if b != 10 { + t.Fatalf("found %d expected 10\n", b) + } + b = C.c_bool(true, true, 5, true, true) + if b != 5 { + t.Fatalf("found %d expected 5\n", b) + } + b = C.c_bool(true, true, 3, true, false) + if b != 3 { + t.Fatalf("found %d expected 3\n", b) + } + b = C.c_bool(false, false, 1, true, false) + if b != 1 { + t.Fatalf("found %d expected 1\n", b) + } + b = C.c_bool(false, true, 200, true, false) + if b != 200 { + t.Fatalf("found %d expected 200\n", b) + } +} + +// issue 4857 + +func test4857() { + _ = C.issue4857() +} + +// issue 5224 + +func testCflags(t *testing.T) { + is_windows := C.is_windows == 1 + if is_windows != (runtime.GOOS == "windows") { + t.Errorf("is_windows: %v, runtime.GOOS: %s", is_windows, runtime.GOOS) + } + if C.common != 123 { + t.Errorf("common: %v (expected 123)", C.common) + } +} + +// issue 5227 + +func test5227(t *testing.T) { + C.init() +} + +func selectfont() C.Fontinfo { + return C.SansTypeface +} + +// issue 5242 + +func test5242(t *testing.T) { + if got := C.issue5242(C.foo{}, C.bar{}); got != 5242 { + t.Errorf("got %v", got) + } +} + +func test5603(t *testing.T) { + var x [5]int64 + exp := int64(C.issue5603exp) + x[0] = int64(C.issue5603foo0()) + x[1] = int64(C.issue5603foo1(nil)) + x[2] = int64(C.issue5603foo2(nil, nil)) + x[3] = int64(C.issue5603foo3(nil, nil, nil)) + x[4] = int64(C.issue5603foo4(nil, nil, nil, nil)) + for i, v := range x { + if v != exp { + t.Errorf("issue5603foo%d() returns %v, expected %v", i, v, exp) + } + } +} + +// issue 5337 + +func test5337(t *testing.T) { + C.test5337() +} + +// issue 5740 + +func test5740(t *testing.T) { + if v := C.test5740a() + C.test5740b(); v != 5 { + t.Errorf("expected 5, got %v", v) + } +} + +// issue 5986 + +func test5986(t *testing.T) { + C.output5986() +} + +// issue 6128 + +func test6128() { + // nothing to run, just make sure this compiles. + _ = C.X +} + +// issue 6390 + +func test6390(t *testing.T) { + p1 := C.malloc(1024) + if p1 == nil { + t.Fatalf("C.malloc(1024) returned nil") + } + p2 := C.malloc(0) + if p2 == nil { + t.Fatalf("C.malloc(0) returned nil") + } + C.free(p1) + C.free(p2) +} + +func test6472() { + // nothing to run, just make sure this compiles + s := new(C.z) + println(s.y[0].x) +} + +// issue 6506 + +func test6506() { + // nothing to run, just make sure this compiles + var x C.size_t + + C.calloc(x, x) + C.malloc(x) + C.realloc(nil, x) + C.memcpy(nil, nil, x) + C.memcmp(nil, nil, x) + C.memmove(nil, nil, x) + C.strncpy(nil, nil, x) + C.strncmp(nil, nil, x) + C.strncat(nil, nil, x) + x = C.strxfrm(nil, nil, x) + C.memchr(nil, 0, x) + x = C.strcspn(nil, nil) + x = C.strspn(nil, nil) + C.memset(nil, 0, x) + x = C.strlen(nil) + _ = x +} + +// issue 6612 + +func testNaming(t *testing.T) { + C.myfunc() + C.myfunc_def() + if v := C.myvar; v != 5 { + t.Errorf("C.myvar = %d, want 5", v) + } + if v := C.myvar_def; v != 5 { + t.Errorf("C.myvar_def = %d, want 5", v) + } + if s := C.GoString(C.mytext); s != "abcdef" { + t.Errorf("C.mytext = %q, want %q", s, "abcdef") + } + if s := C.GoString(C.mytext_def); s != "abcdef" { + t.Errorf("C.mytext_def = %q, want %q", s, "abcdef") + } + if c := C.myenum; c != 1234 { + t.Errorf("C.myenum = %v, want 1234", c) + } + if c := C.myenum_def; c != 1234 { + t.Errorf("C.myenum_def = %v, want 1234", c) + } + { + const c = C.myenum + if c != 1234 { + t.Errorf("C.myenum as const = %v, want 1234", c) + } + } + { + const c = C.myenum_def + if c != 1234 { + t.Errorf("C.myenum as const = %v, want 1234", c) + } + } + if c := C.myint_def; c != 12345 { + t.Errorf("C.myint_def = %v, want 12345", c) + } + { + const c = C.myint_def + if c != 12345 { + t.Errorf("C.myint as const = %v, want 12345", c) + } + } + + if c := C.myfloat_def; c != 1.5 { + t.Errorf("C.myint_def = %v, want 1.5", c) + } + { + const c = C.myfloat_def + if c != 1.5 { + t.Errorf("C.myint as const = %v, want 1.5", c) + } + } + + if s := C.mystring_def; s != "hello" { + t.Errorf("C.mystring_def = %q, want %q", s, "hello") + } +} + +// issue 6907 + +func test6907(t *testing.T) { + want := "yarn" + if got := C.GoString(C.Issue6907CopyString(want)); got != want { + t.Errorf("C.GoString(C.Issue6907CopyString(%q)) == %q, want %q", want, got, want) + } +} + +// issue 7560 + +func test7560(t *testing.T) { + // some mingw don't implement __packed__ correctly. + if C.offset7560() != 1 { + t.Skip("C compiler did not pack struct") + } + + // C.misaligned should have x but then a padding field to get to the end of the struct. + // There should not be a field named 'y'. + var v C.misaligned + rt := reflect.TypeOf(&v).Elem() + if rt.NumField() != 2 || rt.Field(0).Name != "x" || rt.Field(1).Name != "_" { + t.Errorf("unexpected fields in C.misaligned:\n") + for i := 0; i < rt.NumField(); i++ { + t.Logf("%+v\n", rt.Field(i)) + } + } +} + +// issue 7786 + +func f() { + var x1 *C.typedef_test7786 + var x2 *C.struct_test7786 + x1 = x2 + x2 = x1 + C.f7786(x1) + C.f7786(x2) + C.g7786(x1) + C.g7786(x2) + + var b1 *C.typedef_body7786 + var b2 *C.struct_body7786 + b1 = b2 + b2 = b1 + C.b7786(b1) + C.b7786(b2) + C.c7786(b1) + C.c7786(b2) + + var u1 *C.typedef_union7786 + var u2 *C.union_union7786 + u1 = u2 + u2 = u1 + C.u7786(u1) + C.u7786(u2) + C.v7786(u1) + C.v7786(u2) +} + +// issue 8092 + +func test8092(t *testing.T) { + tests := []struct { + s string + a, b *C.char + }{ + {"text", &C.text[0], C.ctext()}, + {"data", &C.data[0], C.cdata()}, + } + for _, test := range tests { + if test.a != test.b { + t.Errorf("%s: pointer mismatch: %v != %v", test.s, test.a, test.b) + } + if got := C.GoString(test.a); got != test.s { + t.Errorf("%s: points at %#v, want %#v", test.s, got, test.s) + } + } +} + +// issues 8368 and 8441 + +func issue8368(one *C.struct_one, two *C.struct_two) { +} + +func issue8441(one *C.one, two *C.two) { + issue8441(two.x, one.x) +} + +// issue 8428 + +var _ = C.struct_issue8428one{ + b: C.char(0), + // The trailing rest field is not available in cgo. + // See issue 11925. + // rest: [0]C.char{}, +} + +var _ = C.struct_issue8428two{ + p: unsafe.Pointer(nil), + b: C.char(0), + rest: [0]C.char{}, +} + +var _ = C.struct_issue8428three{ + w: [1][2][3][0]C.char{}, + x: [2][3][0][1]C.char{}, + y: [3][0][1][2]C.char{}, + z: [0][1][2][3]C.char{}, +} + +// issue 8811 + +func test8811(t *testing.T) { + C.issue8811Execute() +} + +// issue 9557 + +func test9557(t *testing.T) { + // implicitly dereference a Go variable + foo := C.issue9557foo + if v := foo.a; v != 42 { + t.Fatalf("foo.a expected 42, but got %d", v) + } + + // explicitly dereference a C variable + if v := (*C.issue9557foo).a; v != 42 { + t.Fatalf("(*C.issue9557foo).a expected 42, but is %d", v) + } + + // implicitly dereference a C variable + if v := C.issue9557foo.a; v != 42 { + t.Fatalf("C.issue9557foo.a expected 42, but is %d", v) + } +} + +// issue 8331 part 1 + +func issue8331a() C.issue8331 { + return issue8331Var +} + +// issue 10303 + +func test10303(t *testing.T, n int) { + if runtime.Compiler == "gccgo" { + t.Skip("gccgo permits C pointers on the stack") + } + + // Run at a few different stack depths just to avoid an unlucky pass + // due to variables ending up on different pages. + if n > 0 { + test10303(t, n-1) + } + if t.Failed() { + return + } + var x, y, z, v, si C.int + var s C.Struct + C.setintstar(&x) + C.setintptr(&y) + C.setvoidptr(unsafe.Pointer(&v)) + s.P = &si + C.setstruct(s) + + if uintptr(unsafe.Pointer(&x))&^0xfff == uintptr(unsafe.Pointer(&z))&^0xfff { + t.Error("C int* argument on stack") + } + if uintptr(unsafe.Pointer(&y))&^0xfff == uintptr(unsafe.Pointer(&z))&^0xfff { + t.Error("C intptr argument on stack") + } + if uintptr(unsafe.Pointer(&v))&^0xfff == uintptr(unsafe.Pointer(&z))&^0xfff { + t.Error("C void* argument on stack") + } + if uintptr(unsafe.Pointer(&si))&^0xfff == uintptr(unsafe.Pointer(&z))&^0xfff { + t.Error("C struct field pointer on stack") + } +} + +// issue 11925 + +func test11925(t *testing.T) { + if C.sizeof_struct_a11925 != unsafe.Sizeof(C.struct_a11925{}) { + t.Errorf("size of a changed: C %d, Go %d", C.sizeof_struct_a11925, unsafe.Sizeof(C.struct_a11925{})) + } + if C.sizeof_struct_b11925 != unsafe.Sizeof(C.struct_b11925{}) { + t.Errorf("size of b changed: C %d, Go %d", C.sizeof_struct_b11925, unsafe.Sizeof(C.struct_b11925{})) + } +} + +// issue 12030 + +func test12030(t *testing.T) { + buf := (*C.char)(C.malloc(256)) + defer C.free(unsafe.Pointer(buf)) + for _, f := range []float64{1.0, 2.0, 3.14} { + C.issue12030conv(buf, C.double(f)) + got := C.GoString(buf) + if want := fmt.Sprintf("d=%g", f); got != want { + t.Fatalf("C.sprintf failed for %g: %q != %q", f, got, want) + } + } +} + +// issue 13402 + +var _ C.complexfloat +var _ C.complexdouble + +// issue 13930 +// Test that cgo's multiple-value special form for +// C function calls works in variable declaration statements. + +var _, _ = C.abs(0) + +// issue 14838 + +func test14838(t *testing.T) { + data := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} + cData := C.CBytes(data) + defer C.free(cData) + + if C.check_cbytes((*C.char)(cData), C.size_t(len(data))) == 0 { + t.Fatalf("mismatched data: expected %v, got %v", data, (*(*[10]byte)(unsafe.Pointer(cData)))[:]) + } +} + +// issue 17065 + +var sink C.int + +func test17065(t *testing.T) { + if runtime.GOOS == "darwin" { + t.Skip("broken on darwin; issue 17065") + } + for i := range C.ii { + sink = C.ii[i] + } +} + +// issue 17537 + +func test17537(t *testing.T) { + v := C.S17537{i: 17537} + if got, want := C.I17537(&v), C.int(17537); got != want { + t.Errorf("got %d, want %d", got, want) + } + + p := (*C.char)(C.malloc(1)) + *p = 17 + if got, want := C.F17537(&p), C.int(17); got != want { + t.Errorf("got %d, want %d", got, want) + } + + C.F18298(nil) + var v18298 C.T18298_2 + C.G18298(C.T18298_1(v18298)) +} + +// issue 17723 + +func testAPI() { + var cs *C.char + cs = C.CString("hello") + defer C.free(unsafe.Pointer(cs)) + var s string + s = C.GoString((*C.char)(C.api_hello)) + s = C.GoStringN((*C.char)(C.api_hello), C.int(6)) + var b []byte + b = C.GoBytes(unsafe.Pointer(C.api_hello), C.int(6)) + _, _ = s, b + C.cstring_pointer_fun(nil) +} + +// issue 18126 + +func test18126(t *testing.T) { + p := C.malloc(1) + _, err := C.Issue18126C(&p) + C.free(p) + _ = err +} + +// issue 18720 + +func test18720(t *testing.T) { + if got, want := C.HELLO_WORLD, "hello\000world"; got != want { + t.Errorf("C.HELLO_WORLD == %q, expected %q", got, want) + } + + if got, want := C.VAR1, C.int(5); got != want { + t.Errorf("C.VAR1 == %v, expected %v", got, want) + } + + if got, want := *C.ADDR, C.int(5); got != want { + t.Errorf("*C.ADDR == %v, expected %v", got, want) + } + + if got, want := C.CALL, C.int(6); got != want { + t.Errorf("C.CALL == %v, expected %v", got, want) + } + + if got, want := C.CALL, C.int(7); got != want { + t.Errorf("C.CALL == %v, expected %v", got, want) + } + + // Issue 20125. + if got, want := C.SIZE_OF_FOO, 1; got != want { + t.Errorf("C.SIZE_OF_FOO == %v, expected %v", got, want) + } +} + +// issue 20129 + +func test20129(t *testing.T) { + if C.issue20129 != 0 { + t.Fatal("test is broken") + } + C.issue20129Foo() + if C.issue20129 != 1 { + t.Errorf("got %v but expected %v", C.issue20129, 1) + } + C.issue20129Bar() + if C.issue20129 != 2 { + t.Errorf("got %v but expected %v", C.issue20129, 2) + } +} + +// issue 20369 + +func test20369(t *testing.T) { + if C.XUINT64_MAX != math.MaxUint64 { + t.Fatalf("got %v, want %v", uint64(C.XUINT64_MAX), uint64(math.MaxUint64)) + } +} + +// issue 21668 + +var issue21668_X = C.x21668 + +// issue 21708 + +func test21708(t *testing.T) { + if got, want := C.CAST_TO_INT64, -1; got != want { + t.Errorf("C.CAST_TO_INT64 == %v, expected %v", got, want) + } +} + +// issue 21809 + +func test21809(t *testing.T) { + longVar := C.long(3) + typedefVar := C.MySigned_t(4) + typedefTypedefVar := C.MySigned2_t(5) + + // all three should be considered identical to `long` + if ret := C.takes_long(longVar); ret != 9 { + t.Errorf("got %v but expected %v", ret, 9) + } + if ret := C.takes_long(typedefVar); ret != 16 { + t.Errorf("got %v but expected %v", ret, 16) + } + if ret := C.takes_long(typedefTypedefVar); ret != 25 { + t.Errorf("got %v but expected %v", ret, 25) + } + + // They should also be identical to the typedef'd type + if ret := C.takes_typedef(longVar); ret != 9 { + t.Errorf("got %v but expected %v", ret, 9) + } + if ret := C.takes_typedef(typedefVar); ret != 16 { + t.Errorf("got %v but expected %v", ret, 16) + } + if ret := C.takes_typedef(typedefTypedefVar); ret != 25 { + t.Errorf("got %v but expected %v", ret, 25) + } +} + +// issue 22906 + +func test22906(t *testing.T) { + var x1 C.jobject = 0 // Note: 0, not nil. That makes sure we use uintptr for these types. + _ = x1 + var x2 C.jclass = 0 + _ = x2 + var x3 C.jthrowable = 0 + _ = x3 + var x4 C.jstring = 0 + _ = x4 + var x5 C.jarray = 0 + _ = x5 + var x6 C.jbooleanArray = 0 + _ = x6 + var x7 C.jbyteArray = 0 + _ = x7 + var x8 C.jcharArray = 0 + _ = x8 + var x9 C.jshortArray = 0 + _ = x9 + var x10 C.jintArray = 0 + _ = x10 + var x11 C.jlongArray = 0 + _ = x11 + var x12 C.jfloatArray = 0 + _ = x12 + var x13 C.jdoubleArray = 0 + _ = x13 + var x14 C.jobjectArray = 0 + _ = x14 + var x15 C.jweak = 0 + _ = x15 +} + +// issue 22958 +// Nothing to run, just make sure this compiles. +var Vissue22958 C.issue22958Type + +func test23356(t *testing.T) { + if got, want := C.a(), C.int(5); got != want { + t.Errorf("C.a() == %v, expected %v", got, want) + } + if got, want := C.r(), C.int(3); got != want { + t.Errorf("C.r() == %v, expected %v", got, want) + } +} + +// issue 23720 + +func Issue23720F() { + var x C.issue23720A + C.issue23720F(x) +} + +// issue 24206 + +func test24206(t *testing.T) { + if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" { + t.Skipf("skipping on %s/%s", runtime.GOOS, runtime.GOARCH) + } + + if l := len(C.GoString(C.dangerousString1())); l != 123 { + t.Errorf("Incorrect string length - got %d, want 123", l) + } + if l := len(C.GoString(C.dangerousString2())); l != 4096+123 { + t.Errorf("Incorrect string length - got %d, want %d", l, 4096+123) + } +} + +// issue 25143 + +func issue25143sum(ns ...C.int) C.int { + total := C.int(0) + for _, n := range ns { + total += n + } + return total +} + +func test25143(t *testing.T) { + if got, want := issue25143sum(1, 2, 3), C.int(6); got != want { + t.Errorf("issue25143sum(1, 2, 3) == %v, expected %v", got, want) + } +} + +// issue 26066 +// Wrong type of constant with GCC 8 and newer. + +func test26066(t *testing.T) { + var i = int64(C.issue26066) + if i != -1 { + t.Errorf("got %d, want -1", i) + } +} + +// issue 26517 +var a C.TypeOne +var b C.TypeTwo + +// issue 27660 +// Stress the interaction between the race detector and cgo in an +// attempt to reproduce the memory corruption described in #27660. +// The bug was very timing sensitive; at the time of writing this +// test would only trigger the bug about once out of every five runs. + +func test27660(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + ints := make([]int, 100) + locks := make([]sync.Mutex, 100) + // Slowly create threads so that ThreadSanitizer is forced to + // frequently resize its SyncClocks. + for i := 0; i < 100; i++ { + go func() { + for ctx.Err() == nil { + // Sleep in C for long enough that it is likely that the runtime + // will retake this goroutine's currently wired P. + C.usleep(1000 /* 1ms */) + runtime.Gosched() // avoid starvation (see #28701) + } + }() + go func() { + // Trigger lots of synchronization and memory reads/writes to + // increase the likelihood that the race described in #27660 + // results in corruption of ThreadSanitizer's internal state + // and thus an assertion failure or segfault. + for ctx.Err() == nil { + j := rand.Intn(100) + locks[j].Lock() + ints[j]++ + locks[j].Unlock() + } + }() + time.Sleep(time.Millisecond) + } +} + +// issue 28540 + +func twoargsF() { + v := []string{} + C.twoargs1(C.twoargs2(), C.twoargs3(unsafe.Pointer(&v))) +} + +// issue 28545 + +func issue28545G(p **C.char) { + C.issue28545F(p, -1, (0)) + C.issue28545F(p, 2+3, complex(1, 1)) + C.issue28545F(p, issue28772Constant, issue28772Constant2) +} + +// issue 28772 part 1 - part 2 in testx.go + +const issue28772Constant = C.issue28772Constant + +// issue 28896 + +func offset(i int) uintptr { + var pi C.innerPacked + var po C.outerPacked + var ui C.innerUnpacked + var uo C.outerUnpacked + switch i { + case 0: + return unsafe.Offsetof(pi.f2) + case 1: + return unsafe.Offsetof(po.g2) + case 2: + return unsafe.Offsetof(ui.f2) + case 3: + return unsafe.Offsetof(uo.g2) + default: + panic("can't happen") + } +} + +func test28896(t *testing.T) { + for i := 0; i < 4; i++ { + c := uintptr(C.offset(C.int(i))) + g := offset(i) + if c != g { + t.Errorf("%d: C: %d != Go %d", i, c, g) + } + } +} + +// issue 29383 +// cgo's /*line*/ comments failed when inserted after '/', +// because the result looked like a "//" comment. +// No runtime test; just make sure it compiles. + +func Issue29383(n, size uint) int { + if ^C.size_t(0)/C.size_t(n) < C.size_t(size) { + return 0 + } + return 0 +} + +// issue 29748 +// Error handling a struct initializer that requires pointer checking. +// Compilation test only, nothing to run. + +var Vissue29748 = C.f29748(&C.S29748{ + nil, +}) + +func Fissue299748() { + C.f29748(&C.S29748{ + nil, + }) +} + +// issue 29781 + +var issue29781X struct{ X int } + +func issue29781F(...int) int { return 0 } + +func issue29781G() { + var p *C.char + C.issue29781F(&p, C.ISSUE29781C+1) + C.issue29781F(nil, (C.int)( + 0)) + C.issue29781F(&p, (C.int)(0)) + C.issue29781F(&p, (C.int)( + 0)) + C.issue29781F(&p, (C.int)(issue29781X. + X)) +} + +func test29878(t *testing.T) { + const arg uint32 = 123 // fits into all integer types + var ret int16 = C.issue29878function(arg) // no conversions needed + if int64(ret) != int64(arg) { + t.Errorf("return value unexpected: got %d, want %d", ret, arg) + } +} + +// issue 30065 + +func test30065(t *testing.T) { + var a [256]byte + b := []byte("a") + C.memcpy(unsafe.Pointer(&a), unsafe.Pointer(&b[0]), 1) + if a[0] != 'a' { + t.Errorf("&a failed: got %c, want %c", a[0], 'a') + } + + b = []byte("b") + C.memcpy(unsafe.Pointer(&a[0]), unsafe.Pointer(&b[0]), 1) + if a[0] != 'b' { + t.Errorf("&a[0] failed: got %c, want %c", a[0], 'b') + } + + d := make([]byte, 256) + b = []byte("c") + C.memcpy(unsafe.Pointer(&d[0]), unsafe.Pointer(&b[0]), 1) + if d[0] != 'c' { + t.Errorf("&d[0] failed: got %c, want %c", d[0], 'c') + } +} diff --git a/misc/cgo/test/test22906.go b/misc/cgo/test/test22906.go deleted file mode 100644 index 02bae9cfa7..0000000000 --- a/misc/cgo/test/test22906.go +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2017 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. - -// +build cgo - -package cgotest - -/* - -// It's going to be hard to include a whole real JVM to test this. -// So we'll simulate a really easy JVM using just the parts we need. - -// This is the relevant part of jni.h. - -struct _jobject; - -typedef struct _jobject *jobject; -typedef jobject jclass; -typedef jobject jthrowable; -typedef jobject jstring; -typedef jobject jarray; -typedef jarray jbooleanArray; -typedef jarray jbyteArray; -typedef jarray jcharArray; -typedef jarray jshortArray; -typedef jarray jintArray; -typedef jarray jlongArray; -typedef jarray jfloatArray; -typedef jarray jdoubleArray; -typedef jarray jobjectArray; - -typedef jobject jweak; - -// Note: jvalue is already a non-pointer type due to it being a C union. - -*/ -import "C" -import ( - "testing" -) - -func test22906(t *testing.T) { - var x1 C.jobject = 0 // Note: 0, not nil. That makes sure we use uintptr for these types. - _ = x1 - var x2 C.jclass = 0 - _ = x2 - var x3 C.jthrowable = 0 - _ = x3 - var x4 C.jstring = 0 - _ = x4 - var x5 C.jarray = 0 - _ = x5 - var x6 C.jbooleanArray = 0 - _ = x6 - var x7 C.jbyteArray = 0 - _ = x7 - var x8 C.jcharArray = 0 - _ = x8 - var x9 C.jshortArray = 0 - _ = x9 - var x10 C.jintArray = 0 - _ = x10 - var x11 C.jlongArray = 0 - _ = x11 - var x12 C.jfloatArray = 0 - _ = x12 - var x13 C.jdoubleArray = 0 - _ = x13 - var x14 C.jobjectArray = 0 - _ = x14 - var x15 C.jweak = 0 - _ = x15 -} diff --git a/misc/cgo/test/test27660.go b/misc/cgo/test/test27660.go deleted file mode 100644 index 8c23b7dc58..0000000000 --- a/misc/cgo/test/test27660.go +++ /dev/null @@ -1,54 +0,0 @@ -// 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. - -// Stress the interaction between the race detector and cgo in an -// attempt to reproduce the memory corruption described in #27660. -// The bug was very timing sensitive; at the time of writing this -// test would only trigger the bug about once out of every five runs. - -package cgotest - -// #include -import "C" - -import ( - "context" - "math/rand" - "runtime" - "sync" - "testing" - "time" -) - -func test27660(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - ints := make([]int, 100) - locks := make([]sync.Mutex, 100) - // Slowly create threads so that ThreadSanitizer is forced to - // frequently resize its SyncClocks. - for i := 0; i < 100; i++ { - go func() { - for ctx.Err() == nil { - // Sleep in C for long enough that it is likely that the runtime - // will retake this goroutine's currently wired P. - C.usleep(1000 /* 1ms */) - runtime.Gosched() // avoid starvation (see #28701) - } - }() - go func() { - // Trigger lots of synchronization and memory reads/writes to - // increase the likelihood that the race described in #27660 - // results in corruption of ThreadSanitizer's internal state - // and thus an assertion failure or segfault. - for ctx.Err() == nil { - j := rand.Intn(100) - locks[j].Lock() - ints[j]++ - locks[j].Unlock() - } - }() - time.Sleep(time.Millisecond) - } -} diff --git a/misc/cgo/test/issue29878export.go b/misc/cgo/test/test_unix.go similarity index 63% rename from misc/cgo/test/issue29878export.go rename to misc/cgo/test/test_unix.go index 59727c72fc..4a234469db 100644 --- a/misc/cgo/test/issue29878export.go +++ b/misc/cgo/test/test_unix.go @@ -2,11 +2,10 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build !windows + package cgotest -import "C" +import "syscall" -//export issue29878exported -func issue29878exported(arg int8) uint64 { - return uint64(arg) -} +var syscall_dot_SIGCHLD = syscall.SIGCHLD diff --git a/misc/cgo/test/issue13402.go b/misc/cgo/test/test_windows.go similarity index 52% rename from misc/cgo/test/issue13402.go rename to misc/cgo/test/test_windows.go index 3af24c2d3c..7bfb33a83c 100644 --- a/misc/cgo/test/issue13402.go +++ b/misc/cgo/test/test_windows.go @@ -1,10 +1,9 @@ -// Copyright 2015 The Go Authors. All rights reserved. +// Copyright 2019 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 cgotest -import "C" +import "syscall" -var _ C.complexfloat -var _ C.complexdouble +var syscall_dot_SIGCHLD syscall.Signal diff --git a/misc/cgo/test/testx.go b/misc/cgo/test/testx.go new file mode 100644 index 0000000000..b0b23e3011 --- /dev/null +++ b/misc/cgo/test/testx.go @@ -0,0 +1,542 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test cases for cgo. +// Both the import "C" prologue and the main file are sorted by issue number. +// This file contains //export directives on Go functions +// and so it must NOT contain C definitions (only declarations). +// See test.go for C definitions. + +package cgotest + +import ( + "runtime" + "runtime/debug" + "strings" + "sync" + "sync/atomic" + "testing" + "time" + "unsafe" +) + +/* +// threads +extern void doAdd(int, int); + +// issue 1328 +extern void BackIntoGo(void); +void IntoC(void); + +// issue 1560 +// mysleep returns the absolute start time in ms. +long long mysleep(int seconds); + +// twoSleep returns the absolute start time of the first sleep +// in ms. +long long twoSleep(int); + +// issue 3775 +void lockOSThreadCallback(void); +inline static void lockOSThreadC(void) +{ + lockOSThreadCallback(); +} +int usleep(unsigned usec); + +// issue 4054 part 2 - part 1 in test.go +typedef enum { + A = 0, + B, + C, + D, + E, + F, + G, + H, + II, + J, +} issue4054b; + +// issue 5548 + +extern int issue5548_in_c(void); + +// issue 6833 + +extern unsigned long long issue6833Func(unsigned int, unsigned long long); + +// issue 6907 + +extern int CheckIssue6907C(_GoString_); + +// issue 7665 + +extern void f7665(void); + +// issue 7978 +// Stack tracing didn't work during cgo code after calling a Go +// callback. Make sure GC works and the stack trace is correct. + +#include + +void issue7978cb(void); + +#if defined(__APPLE__) && defined(__arm__) +// on Darwin/ARM, libSystem doesn't provide implementation of the __sync_fetch_and_add +// primitive, and although gcc supports it, it doesn't inline its definition. +// Clang could inline its definition, so we require clang on Darwin/ARM. +#if defined(__clang__) +#define HAS_SYNC_FETCH_AND_ADD 1 +#else +#define HAS_SYNC_FETCH_AND_ADD 0 +#endif +#else +#define HAS_SYNC_FETCH_AND_ADD 1 +#endif + +// use ugly atomic variable sync since that doesn't require calling back into +// Go code or OS dependencies +static void issue7978c(uint32_t *sync) { +#if HAS_SYNC_FETCH_AND_ADD + while(__sync_fetch_and_add(sync, 0) != 0) + ; + __sync_fetch_and_add(sync, 1); + while(__sync_fetch_and_add(sync, 0) != 2) + ; + issue7978cb(); + __sync_fetch_and_add(sync, 1); + while(__sync_fetch_and_add(sync, 0) != 6) + ; +#endif +} + +// issue 8331 part 2 - part 1 in test.go +// A typedef of an unnamed struct is the same struct when +// #include'd twice. No runtime test; just make sure it compiles. +#include "issue8331.h" + +// issue 20910 +void callMulti(void); + +// issue 28772 part 2 - part 1 in issuex.go +#define issue28772Constant2 2 + +*/ +import "C" + +// exports + +//export ReturnIntLong +func ReturnIntLong() (int, C.long) { + return 1, 2 +} + +//export gc +func gc() { + runtime.GC() +} + +// threads + +var sum struct { + sync.Mutex + i int +} + +//export Add +func Add(x int) { + defer func() { + recover() + }() + sum.Lock() + sum.i += x + sum.Unlock() + var p *int + *p = 2 +} + +func testCthread(t *testing.T) { + if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") { + t.Skip("the iOS exec wrapper is unable to properly handle the panic from Add") + } + sum.i = 0 + C.doAdd(10, 6) + + want := 10 * (10 - 1) / 2 * 6 + if sum.i != want { + t.Fatalf("sum=%d, want %d", sum.i, want) + } +} + +// issue 1328 + +//export BackIntoGo +func BackIntoGo() { + x := 1 + + for i := 0; i < 10000; i++ { + xvariadic(x) + if x != 1 { + panic("x is not 1?") + } + } +} + +func xvariadic(x ...interface{}) { +} + +func test1328(t *testing.T) { + C.IntoC() +} + +// issue 1560 + +var sleepDone = make(chan int64) + +// parallelSleep returns the absolute difference between the start time +// of the two sleeps. +func parallelSleep(n int) int64 { + t := int64(C.twoSleep(C.int(n))) - <-sleepDone + if t < 0 { + return -t + } + return t +} + +//export BackgroundSleep +func BackgroundSleep(n int32) { + go func() { + sleepDone <- int64(C.mysleep(C.int(n))) + }() +} + +func testParallelSleep(t *testing.T) { + sleepSec := 1 + dt := time.Duration(parallelSleep(sleepSec)) * time.Millisecond + t.Logf("difference in start time for two sleep(%d) is %v", sleepSec, dt) + // bug used to run sleeps in serial, producing a 2*sleepSec-second delay. + // we detect if the start times of those sleeps are > 0.5*sleepSec-second. + if dt >= time.Duration(sleepSec)*time.Second/2 { + t.Fatalf("parallel %d-second sleeps slept for %f seconds", sleepSec, dt.Seconds()) + } +} + +// issue 2462 + +//export exportbyte +func exportbyte() byte { + return 0 +} + +//export exportbool +func exportbool() bool { + return false +} + +//export exportrune +func exportrune() rune { + return 0 +} + +//export exporterror +func exporterror() error { + return nil +} + +//export exportint +func exportint() int { + return 0 +} + +//export exportuint +func exportuint() uint { + return 0 +} + +//export exportuintptr +func exportuintptr() uintptr { + return (uintptr)(0) +} + +//export exportint8 +func exportint8() int8 { + return 0 +} + +//export exportuint8 +func exportuint8() uint8 { + return 0 +} + +//export exportint16 +func exportint16() int16 { + return 0 +} + +//export exportuint16 +func exportuint16() uint16 { + return 0 +} + +//export exportint32 +func exportint32() int32 { + return 0 +} + +//export exportuint32 +func exportuint32() uint32 { + return 0 +} + +//export exportint64 +func exportint64() int64 { + return 0 +} + +//export exportuint64 +func exportuint64() uint64 { + return 0 +} + +//export exportfloat32 +func exportfloat32() float32 { + return 0 +} + +//export exportfloat64 +func exportfloat64() float64 { + return 0 +} + +//export exportcomplex64 +func exportcomplex64() complex64 { + return 0 +} + +//export exportcomplex128 +func exportcomplex128() complex128 { + return 0 +} + +// issue 3741 + +//export exportSliceIn +func exportSliceIn(s []byte) bool { + return len(s) == cap(s) +} + +//export exportSliceOut +func exportSliceOut() []byte { + return []byte{1} +} + +//export exportSliceInOut +func exportSliceInOut(s []byte) []byte { + return s +} + +// issue 3775 + +func init() { + if runtime.GOOS == "android" { + return + } + // Same as test3775 but run during init so that + // there are two levels of internal runtime lock + // (1 for init, 1 for cgo). + // This would have been broken by CL 11663043. + C.lockOSThreadC() +} + +func test3775(t *testing.T) { + if runtime.GOOS == "android" { + return + } + // Used to panic because of the UnlockOSThread below. + C.lockOSThreadC() +} + +//export lockOSThreadCallback +func lockOSThreadCallback() { + runtime.LockOSThread() + runtime.UnlockOSThread() + go C.usleep(10000) + runtime.Gosched() +} + +// issue 4054 part 2 - part 1 in test.go + +var issue4054b = []int{C.A, C.B, C.C, C.D, C.E, C.F, C.G, C.H, C.II, C.J} + +//export issue5548FromC +func issue5548FromC(s string, i int) int { + if len(s) == 4 && s == "test" && i == 42 { + return 12345 + } + println("got", len(s), i) + return 9876 +} + +func test5548(t *testing.T) { + if x := C.issue5548_in_c(); x != 12345 { + t.Errorf("issue5548_in_c = %d, want %d", x, 12345) + } +} + +// issue 6833 + +//export GoIssue6833Func +func GoIssue6833Func(aui uint, aui64 uint64) uint64 { + return aui64 + uint64(aui) +} + +func test6833(t *testing.T) { + ui := 7 + ull := uint64(0x4000300020001000) + v := uint64(C.issue6833Func(C.uint(ui), C.ulonglong(ull))) + exp := uint64(ui) + ull + if v != exp { + t.Errorf("issue6833Func() returns %x, expected %x", v, exp) + } +} + +// issue 6907 + +const CString = "C string" + +//export CheckIssue6907Go +func CheckIssue6907Go(s string) C.int { + if s == CString { + return 1 + } + return 0 +} + +func test6907Go(t *testing.T) { + if got := C.CheckIssue6907C(CString); got != 1 { + t.Errorf("C.CheckIssue6907C() == %d, want %d", got, 1) + } +} + +// issue 7665 + +//export f7665 +func f7665() {} + +var bad7665 unsafe.Pointer = C.f7665 +var good7665 uintptr = uintptr(C.f7665) + +func test7665(t *testing.T) { + if bad7665 == nil || uintptr(bad7665) != good7665 { + t.Errorf("ptrs = %p, %#x, want same non-nil pointer", bad7665, good7665) + } +} + +// issue 7978 + +var issue7978sync uint32 + +func issue7978check(t *testing.T, wantFunc string, badFunc string, depth int) { + runtime.GC() + buf := make([]byte, 65536) + trace := string(buf[:runtime.Stack(buf, true)]) + for _, goroutine := range strings.Split(trace, "\n\n") { + if strings.Contains(goroutine, "test.issue7978go") { + trace := strings.Split(goroutine, "\n") + // look for the expected function in the stack + for i := 0; i < depth; i++ { + if badFunc != "" && strings.Contains(trace[1+2*i], badFunc) { + t.Errorf("bad stack: found %s in the stack:\n%s", badFunc, goroutine) + return + } + if strings.Contains(trace[1+2*i], wantFunc) { + return + } + } + t.Errorf("bad stack: didn't find %s in the stack:\n%s", wantFunc, goroutine) + return + } + } + t.Errorf("bad stack: goroutine not found. Full stack dump:\n%s", trace) +} + +func issue7978wait(store uint32, wait uint32) { + if store != 0 { + atomic.StoreUint32(&issue7978sync, store) + } + for atomic.LoadUint32(&issue7978sync) != wait { + runtime.Gosched() + } +} + +//export issue7978cb +func issue7978cb() { + // Force a stack growth from the callback to put extra + // pressure on the runtime. See issue #17785. + growStack(64) + issue7978wait(3, 4) +} + +func growStack(n int) int { + var buf [128]int + if n == 0 { + return 0 + } + return buf[growStack(n-1)] +} + +func issue7978go() { + C.issue7978c((*C.uint32_t)(&issue7978sync)) + issue7978wait(7, 8) +} + +func test7978(t *testing.T) { + if runtime.Compiler == "gccgo" { + t.Skip("gccgo can not do stack traces of C code") + } + if C.HAS_SYNC_FETCH_AND_ADD == 0 { + t.Skip("clang required for __sync_fetch_and_add support on darwin/arm") + } + debug.SetTraceback("2") + issue7978sync = 0 + go issue7978go() + // test in c code, before callback + issue7978wait(0, 1) + issue7978check(t, "_Cfunc_issue7978c(", "", 1) + // test in go code, during callback + issue7978wait(2, 3) + issue7978check(t, "test.issue7978cb(", "test.issue7978go", 3) + // test in c code, after callback + issue7978wait(4, 5) + issue7978check(t, "_Cfunc_issue7978c(", "_cgoexpwrap", 1) + // test in go code, after return from cgo + issue7978wait(6, 7) + issue7978check(t, "test.issue7978go(", "", 3) + atomic.StoreUint32(&issue7978sync, 8) +} + +// issue 8331 part 2 + +var issue8331Var C.issue8331 + +// issue 20910 + +//export multi +func multi() (*C.char, C.int) { + return C.CString("multi"), 0 +} + +func test20910(t *testing.T) { + C.callMulti() +} + +// issue 28772 part 2 + +const issue28772Constant2 = C.issue28772Constant2 + +//export issue29878exported +func issue29878exported(arg int8) uint64 { + return uint64(arg) +} diff --git a/misc/cgo/test/twoargs.go b/misc/cgo/test/twoargs.go deleted file mode 100644 index ca0534ca31..0000000000 --- a/misc/cgo/test/twoargs.go +++ /dev/null @@ -1,22 +0,0 @@ -// 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. - -// Crash from call with two arguments that need pointer checking. -// No runtime test; just make sure it compiles. - -package cgotest - -/* -static void twoargs1(void *p, int n) {} -static void *twoargs2() { return 0; } -static int twoargs3(void * p) { return 0; } -*/ -import "C" - -import "unsafe" - -func twoargsF() { - v := []string{} - C.twoargs1(C.twoargs2(), C.twoargs3(unsafe.Pointer(&v))) -} From 06b0babf3138d189f6e741561f77ac6146696377 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Wed, 15 May 2019 20:49:39 -0400 Subject: [PATCH 32/50] all: shorten some tests Shorten some of the longest tests that run during all.bash. Removes 7r 50u 21s from all.bash. After this change, all.bash is under 5 minutes again on my laptop. For #26473. Change-Id: Ie0460aa935808d65460408feaed210fbaa1d5d79 Reviewed-on: https://go-review.googlesource.com/c/go/+/177559 Run-TryBot: Russ Cox TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- src/archive/zip/zip_test.go | 5 +-- src/cmd/dist/test.go | 17 ++++++-- src/cmd/go/internal/cache/cache_test.go | 2 +- src/cmd/internal/obj/x86/pcrelative_test.go | 3 ++ src/cmd/link/dwarf_test.go | 6 ++- src/cmd/link/link_test.go | 5 ++- src/cmd/pack/pack_test.go | 3 ++ src/compress/flate/deflate_test.go | 6 +++ src/container/ring/ring_test.go | 2 +- src/crypto/cipher/xor_test.go | 3 ++ src/crypto/elliptic/fuzz_test.go | 2 +- src/crypto/rand/util_test.go | 3 ++ src/crypto/tls/handshake_client_test.go | 6 +++ src/crypto/x509/x509_test.go | 3 ++ src/debug/gosym/pclntab_test.go | 3 ++ src/encoding/json/encode_test.go | 6 +++ .../internal/srcimporter/srcimporter_test.go | 4 +- src/internal/trace/gc_test.go | 4 ++ src/internal/trace/parser_test.go | 13 +++++- src/math/big/floatmarsh_test.go | 3 ++ src/math/big/natconv_test.go | 3 ++ src/math/big/prime_test.go | 14 +++++-- src/math/big/sqrt_test.go | 3 ++ src/math/rand/rand_test.go | 2 +- src/mime/multipart/formdata_test.go | 9 +++- src/mime/multipart/multipart_test.go | 5 ++- src/mime/quotedprintable/reader_test.go | 13 +++++- src/net/http/serve_test.go | 8 +++- src/os/exec/exec_test.go | 3 ++ src/runtime/internal/atomic/atomic_test.go | 10 +++-- src/runtime/pprof/pprof_test.go | 29 +++++++++---- src/runtime/pprof/proto_test.go | 8 ++-- .../pprof/testdata/mappingtest/main.go | 2 +- src/runtime/semasleep_test.go | 42 ++++--------------- src/runtime/testdata/testprog/deadlock.go | 4 ++ src/runtime/testdata/testprog/sleep.go | 17 ++++++++ src/runtime/trace/trace_test.go | 4 ++ src/sync/pool_test.go | 3 ++ src/syscall/getdirentries_test.go | 3 ++ src/testing/quick/quick_test.go | 2 +- src/text/template/exec_test.go | 3 ++ 41 files changed, 208 insertions(+), 78 deletions(-) create mode 100644 src/runtime/testdata/testprog/sleep.go diff --git a/src/archive/zip/zip_test.go b/src/archive/zip/zip_test.go index efdb5bd044..b3a7caac7f 100644 --- a/src/archive/zip/zip_test.go +++ b/src/archive/zip/zip_test.go @@ -11,7 +11,6 @@ import ( "errors" "fmt" "hash" - "internal/race" "internal/testenv" "io" "io/ioutil" @@ -309,7 +308,7 @@ func TestZip64EdgeCase(t *testing.T) { // Tests that we generate a zip64 file if the directory at offset // 0xFFFFFFFF, but not before. func TestZip64DirectoryOffset(t *testing.T) { - if testing.Short() && race.Enabled { + if testing.Short() { t.Skip("skipping in short mode") } t.Parallel() @@ -354,7 +353,7 @@ func TestZip64DirectoryOffset(t *testing.T) { // At 16k records, we need to generate a zip64 file. func TestZip64ManyRecords(t *testing.T) { - if testing.Short() && race.Enabled { + if testing.Short() { t.Skip("skipping in short mode") } t.Parallel() diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go index 56ab64b8cf..833baf8f91 100644 --- a/src/cmd/dist/test.go +++ b/src/cmd/dist/test.go @@ -551,7 +551,9 @@ func (t *tester) registerTests() { name: "nolibgcc:" + pkg, heading: "Testing without libgcc.", fn: func(dt *distTest) error { - t.addCmd(dt, "src", t.goTest(), "-ldflags=-linkmode=internal -libgcc=none", pkg, t.runFlag(run)) + // What matters is that the tests build and start up. + // Skip expensive tests, especially x509 TestSystemRoots. + t.addCmd(dt, "src", t.goTest(), "-ldflags=-linkmode=internal -libgcc=none", "-run=^Test[^CS]", pkg, t.runFlag(run)) return nil }, }) @@ -693,7 +695,10 @@ func (t *tester) registerTests() { } if goos != "android" && !t.iOS() { - t.registerTest("bench_go1", "../test/bench/go1", t.goTest(), t.timeout(600)) + // There are no tests in this directory, only benchmarks. + // Check that the test binary builds but don't bother running it. + // (It has init-time work to set up for the benchmarks that is not worth doing unnecessarily.) + t.registerTest("bench_go1", "../test/bench/go1", t.goTest(), "-c", "-o="+os.DevNull) } if goos != "android" && !t.iOS() { // Only start multiple test dir shards on builders, @@ -1292,8 +1297,12 @@ func (t *tester) raceTest(dt *distTest) error { // TODO(iant): Figure out how to catch this. // t.addCmd(dt, "src", t.goTest(), "-race", "-run=TestParallelTest", "cmd/go") if t.cgoEnabled { - cmd := t.addCmd(dt, "misc/cgo/test", t.goTest(), "-race") - cmd.Env = append(os.Environ(), "GOTRACEBACK=2") + // Building misc/cgo/test takes a long time. + // There are already cgo-enabled packages being tested with the race detector. + // We shouldn't need to redo all of misc/cgo/test too. + // The race buildler will take care of this. + // cmd := t.addCmd(dt, "misc/cgo/test", t.goTest(), "-race") + // cmd.Env = append(os.Environ(), "GOTRACEBACK=2") } if t.extLink() { // Test with external linking; see issue 9133. diff --git a/src/cmd/go/internal/cache/cache_test.go b/src/cmd/go/internal/cache/cache_test.go index 7229bc4cec..1988c34502 100644 --- a/src/cmd/go/internal/cache/cache_test.go +++ b/src/cmd/go/internal/cache/cache_test.go @@ -78,7 +78,7 @@ func TestGrowth(t *testing.T) { n := 10000 if testing.Short() { - n = 1000 + n = 10 } for i := 0; i < n; i++ { diff --git a/src/cmd/internal/obj/x86/pcrelative_test.go b/src/cmd/internal/obj/x86/pcrelative_test.go index 51b60cf93e..487a65d8dc 100644 --- a/src/cmd/internal/obj/x86/pcrelative_test.go +++ b/src/cmd/internal/obj/x86/pcrelative_test.go @@ -96,6 +96,9 @@ LOOP: for idx := len(data) - 1; idx >= 0; idx-- { // check that RET wasn't overwritten. if bytes.Index(data[idx], []byte("RET")) != -1 { + if testing.Short() { + break LOOP + } continue LOOP } } diff --git a/src/cmd/link/dwarf_test.go b/src/cmd/link/dwarf_test.go index 235db39dda..e52e26af49 100644 --- a/src/cmd/link/dwarf_test.go +++ b/src/cmd/link/dwarf_test.go @@ -165,8 +165,10 @@ func testDWARF(t *testing.T, buildmode string, expectDWARF bool, env ...string) func TestDWARF(t *testing.T) { testDWARF(t, "", true) - if runtime.GOOS == "darwin" { - testDWARF(t, "c-archive", true) + if runtime.GOOS == "darwin" && !testing.Short() { + t.Run("c-archive", func(t *testing.T) { + testDWARF(t, "c-archive", true) + }) } } diff --git a/src/cmd/link/link_test.go b/src/cmd/link/link_test.go index a783bddc50..29b98e9c32 100644 --- a/src/cmd/link/link_test.go +++ b/src/cmd/link/link_test.go @@ -170,7 +170,7 @@ main.x: relocation target main.zero not defined } } -func TestBuildFortvOS(t *testing.T) { +func TestBuildForTvOS(t *testing.T) { testenv.MustHaveCGO(t) testenv.MustHaveGoBuild(t) @@ -178,6 +178,9 @@ func TestBuildFortvOS(t *testing.T) { if runtime.GOARCH != "amd64" || runtime.GOOS != "darwin" { t.Skip("skipping on non-darwin/amd64 platform") } + if testing.Short() && os.Getenv("GO_BUILDER_NAME") == "" { + t.Skip("skipping in -short mode with $GO_BUILDER_NAME empty") + } if err := exec.Command("xcrun", "--help").Run(); err != nil { t.Skipf("error running xcrun, required for iOS cross build: %v", err) } diff --git a/src/cmd/pack/pack_test.go b/src/cmd/pack/pack_test.go index b2217c090f..6121bf08c0 100644 --- a/src/cmd/pack/pack_test.go +++ b/src/cmd/pack/pack_test.go @@ -231,6 +231,9 @@ func TestHello(t *testing.T) { // Test that pack works with very long lines in PKGDEF. func TestLargeDefs(t *testing.T) { + if testing.Short() { + t.Skip("skipping in -short mode") + } testenv.MustHaveGoBuild(t) dir := tmpDir(t) diff --git a/src/compress/flate/deflate_test.go b/src/compress/flate/deflate_test.go index 079c03c283..4b1ed549a4 100644 --- a/src/compress/flate/deflate_test.go +++ b/src/compress/flate/deflate_test.go @@ -345,6 +345,9 @@ func testToFromWithLimit(t *testing.T, input []byte, name string, limit [11]int) func TestDeflateInflate(t *testing.T) { t.Parallel() for i, h := range deflateInflateTests { + if testing.Short() && len(h.in) > 10000 { + continue + } testToFromWithLimit(t, h.in, fmt.Sprintf("#%d", i), [11]int{}) } } @@ -591,6 +594,9 @@ func TestBestSpeed(t *testing.T) { } for i, tc := range testCases { + if i >= 3 && testing.Short() { + break + } for _, firstN := range []int{1, 65534, 65535, 65536, 65537, 131072} { tc[0] = firstN outer: diff --git a/src/container/ring/ring_test.go b/src/container/ring/ring_test.go index 552f0e24b5..41d18abf8b 100644 --- a/src/container/ring/ring_test.go +++ b/src/container/ring/ring_test.go @@ -179,7 +179,7 @@ func TestLink2(t *testing.T) { func TestLink3(t *testing.T) { var r Ring n := 1 - for i := 1; i < 100; i++ { + for i := 1; i < 10; i++ { n += i verify(t, r.Link(New(i)), n, -1) } diff --git a/src/crypto/cipher/xor_test.go b/src/crypto/cipher/xor_test.go index d49f1da77c..40d4e5afa3 100644 --- a/src/crypto/cipher/xor_test.go +++ b/src/crypto/cipher/xor_test.go @@ -20,6 +20,9 @@ func TestXOR(t *testing.T) { testenv.SkipFlaky(t, 31812) } for j := 1; j <= 1024; j++ { + if testing.Short() && j > 16 { + break + } for alignP := 0; alignP < 2; alignP++ { for alignQ := 0; alignQ < 2; alignQ++ { for alignD := 0; alignD < 2; alignD++ { diff --git a/src/crypto/elliptic/fuzz_test.go b/src/crypto/elliptic/fuzz_test.go index 10196cf0bc..eaeed0dacc 100644 --- a/src/crypto/elliptic/fuzz_test.go +++ b/src/crypto/elliptic/fuzz_test.go @@ -22,7 +22,7 @@ func TestFuzz(t *testing.T) { var timeout *time.Timer if testing.Short() { - timeout = time.NewTimer(500 * time.Millisecond) + timeout = time.NewTimer(10 * time.Millisecond) } else { timeout = time.NewTimer(2 * time.Second) } diff --git a/src/crypto/rand/util_test.go b/src/crypto/rand/util_test.go index 685624e1b3..e76ce2018a 100644 --- a/src/crypto/rand/util_test.go +++ b/src/crypto/rand/util_test.go @@ -84,6 +84,9 @@ func TestIntMask(t *testing.T) { for max := 1; max <= 256; max++ { t.Run(fmt.Sprintf("max=%d", max), func(t *testing.T) { for i := 0; i < max; i++ { + if testing.Short() && i == 0 { + i = max - 1 + } var b bytes.Buffer b.WriteByte(byte(i)) n, err := rand.Int(&b, big.NewInt(int64(max))) diff --git a/src/crypto/tls/handshake_client_test.go b/src/crypto/tls/handshake_client_test.go index 40311b0a66..a27f107ba7 100644 --- a/src/crypto/tls/handshake_client_test.go +++ b/src/crypto/tls/handshake_client_test.go @@ -880,6 +880,9 @@ func TestResumption(t *testing.T) { } func testResumption(t *testing.T, version uint16) { + if testing.Short() { + t.Skip("skipping in -short mode") + } serverConfig := &Config{ MaxVersion: version, CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA}, @@ -1727,6 +1730,9 @@ func TestAlertFlushing(t *testing.T) { } func TestHandshakeRace(t *testing.T) { + if testing.Short() { + t.Skip("skipping in -short mode") + } t.Parallel() // This test races a Read and Write to try and complete a handshake in // order to provide some evidence that there are no races or deadlocks diff --git a/src/crypto/x509/x509_test.go b/src/crypto/x509/x509_test.go index 833497d275..171509f7c4 100644 --- a/src/crypto/x509/x509_test.go +++ b/src/crypto/x509/x509_test.go @@ -1243,6 +1243,9 @@ func TestParsePEMCRL(t *testing.T) { } func TestImports(t *testing.T) { + if testing.Short() { + t.Skip("skipping in -short mode") + } testenv.MustHaveGoRun(t) if out, err := exec.Command(testenv.GoToolPath(t), "run", "x509_test_import.go").CombinedOutput(); err != nil { diff --git a/src/debug/gosym/pclntab_test.go b/src/debug/gosym/pclntab_test.go index ef644f8454..6baa53defd 100644 --- a/src/debug/gosym/pclntab_test.go +++ b/src/debug/gosym/pclntab_test.go @@ -196,6 +196,9 @@ func TestLineAline(t *testing.T) { } func TestPCLine(t *testing.T) { + if testing.Short() { + t.Skip("skipping in -short mode") + } dotest(t) defer endtest() diff --git a/src/encoding/json/encode_test.go b/src/encoding/json/encode_test.go index cd5eadf3c1..bdf2a9f079 100644 --- a/src/encoding/json/encode_test.go +++ b/src/encoding/json/encode_test.go @@ -580,6 +580,9 @@ func TestStringBytes(t *testing.T) { // Test that encodeState.stringBytes and encodeState.string use the same encoding. var r []rune for i := '\u0000'; i <= unicode.MaxRune; i++ { + if testing.Short() && i > 1000 { + i = unicode.MaxRune + } r = append(r, i) } s := string(r) + "\xff\xff\xffhello" // some invalid UTF-8 too @@ -864,6 +867,9 @@ func TestMarshalFloat(t *testing.T) { var digits = "1.2345678901234567890123" for i := len(digits); i >= 2; i-- { + if testing.Short() && i < len(digits)-4 { + break + } for exp := -30; exp <= 30; exp++ { for _, sign := range "+-" { for bits := 32; bits <= 64; bits += 32 { diff --git a/src/go/internal/srcimporter/srcimporter_test.go b/src/go/internal/srcimporter/srcimporter_test.go index 087f97461e..56549434d1 100644 --- a/src/go/internal/srcimporter/srcimporter_test.go +++ b/src/go/internal/srcimporter/srcimporter_test.go @@ -81,10 +81,10 @@ func TestImportStdLib(t *testing.T) { t.Skip("no source code available") } - dt := maxTime if testing.Short() && testenv.Builder() == "" { - dt = 500 * time.Millisecond + t.Skip("skipping in -short mode") } + dt := maxTime nimports, _ := walkDir(t, "", time.Now().Add(dt)) // installed packages t.Logf("tested %d imports", nimports) } diff --git a/src/internal/trace/gc_test.go b/src/internal/trace/gc_test.go index da1cb90f5c..4f9c77041a 100644 --- a/src/internal/trace/gc_test.go +++ b/src/internal/trace/gc_test.go @@ -79,6 +79,10 @@ func TestMMU(t *testing.T) { func TestMMUTrace(t *testing.T) { // Can't be t.Parallel() because it modifies the // testingOneBand package variable. + if testing.Short() { + // test input too big for all.bash + t.Skip("skipping in -short mode") + } data, err := ioutil.ReadFile("testdata/stress_1_10_good") if err != nil { diff --git a/src/internal/trace/parser_test.go b/src/internal/trace/parser_test.go index c9afa68c3c..6d87970157 100644 --- a/src/internal/trace/parser_test.go +++ b/src/internal/trace/parser_test.go @@ -7,6 +7,7 @@ package trace import ( "bytes" "io/ioutil" + "os" "path/filepath" "strings" "testing" @@ -38,9 +39,17 @@ func TestParseCanned(t *testing.T) { t.Fatalf("failed to read ./testdata: %v", err) } for _, f := range files { - data, err := ioutil.ReadFile(filepath.Join("./testdata", f.Name())) + name := filepath.Join("./testdata", f.Name()) + info, err := os.Stat(name) if err != nil { - t.Fatalf("failed to read input file: %v", err) + t.Fatal(err) + } + if testing.Short() && info.Size() > 10000 { + continue + } + data, err := ioutil.ReadFile(name) + if err != nil { + t.Fatal(err) } // Instead of Parse that requires a proper binary name for old traces, // we use 'parse' that omits symbol lookup if an empty string is given. diff --git a/src/math/big/floatmarsh_test.go b/src/math/big/floatmarsh_test.go index 5bd906ddae..c056d78b80 100644 --- a/src/math/big/floatmarsh_test.go +++ b/src/math/big/floatmarsh_test.go @@ -109,6 +109,9 @@ func TestFloatJSONEncoding(t *testing.T) { for _, test := range floatVals { for _, sign := range []string{"", "+", "-"} { for _, prec := range []uint{0, 1, 2, 10, 53, 64, 100, 1000} { + if prec > 53 && testing.Short() { + continue + } x := sign + test var tx Float _, _, err := tx.SetPrec(prec).Parse(x, 0) diff --git a/src/math/big/natconv_test.go b/src/math/big/natconv_test.go index 9c2acca07e..d390272108 100644 --- a/src/math/big/natconv_test.go +++ b/src/math/big/natconv_test.go @@ -446,6 +446,9 @@ func TestStringPowers(t *testing.T) { var p Word for b := 2; b <= 16; b++ { for p = 0; p <= 512; p++ { + if testing.Short() && p > 10 { + break + } x := nat(nil).expWW(Word(b), p) xs := x.utoa(b) xs2 := itoa(x, b) diff --git a/src/math/big/prime_test.go b/src/math/big/prime_test.go index bf50f34419..8596e33a13 100644 --- a/src/math/big/prime_test.go +++ b/src/math/big/prime_test.go @@ -125,11 +125,11 @@ func cutSpace(r rune) rune { func TestProbablyPrime(t *testing.T) { nreps := 20 if testing.Short() { - nreps = 3 + nreps = 1 } for i, s := range primes { p, _ := new(Int).SetString(s, 10) - if !p.ProbablyPrime(nreps) || !p.ProbablyPrime(1) || !p.ProbablyPrime(0) { + if !p.ProbablyPrime(nreps) || nreps != 1 && !p.ProbablyPrime(1) || !p.ProbablyPrime(0) { t.Errorf("#%d prime found to be non-prime (%s)", i, s) } } @@ -137,7 +137,7 @@ func TestProbablyPrime(t *testing.T) { for i, s := range composites { s = strings.Map(cutSpace, s) c, _ := new(Int).SetString(s, 10) - if c.ProbablyPrime(nreps) || c.ProbablyPrime(1) || c.ProbablyPrime(0) { + if c.ProbablyPrime(nreps) || nreps != 1 && c.ProbablyPrime(1) || c.ProbablyPrime(0) { t.Errorf("#%d composite found to be prime (%s)", i, s) } } @@ -197,6 +197,14 @@ func TestLucasPseudoprimes(t *testing.T) { func testPseudoprimes(t *testing.T, name string, cond func(nat) bool, want []int) { n := nat{1} for i := 3; i < 100000; i += 2 { + if testing.Short() { + if len(want) == 0 { + break + } + if i < want[0]-2 { + i = want[0] - 2 + } + } n[0] = Word(i) pseudo := cond(n) if pseudo && (len(want) == 0 || i != want[0]) { diff --git a/src/math/big/sqrt_test.go b/src/math/big/sqrt_test.go index 6a412d61fb..d314711d74 100644 --- a/src/math/big/sqrt_test.go +++ b/src/math/big/sqrt_test.go @@ -15,6 +15,9 @@ import ( // behaves like float math.Sqrt. func TestFloatSqrt64(t *testing.T) { for i := 0; i < 1e5; i++ { + if i == 1e2 && testing.Short() { + break + } r := rand.Float64() got := new(Float).SetPrec(53) diff --git a/src/math/rand/rand_test.go b/src/math/rand/rand_test.go index e663b84f9f..ee9c8f8e84 100644 --- a/src/math/rand/rand_test.go +++ b/src/math/rand/rand_test.go @@ -486,7 +486,7 @@ func TestUniformFactorial(t *testing.T) { r := New(NewSource(testSeeds[0])) top := 6 if testing.Short() { - top = 4 + top = 3 } for n := 3; n <= top; n++ { t.Run(fmt.Sprintf("n=%d", n), func(t *testing.T) { diff --git a/src/mime/multipart/formdata_test.go b/src/mime/multipart/formdata_test.go index 105a82c417..7d756c8c24 100644 --- a/src/mime/multipart/formdata_test.go +++ b/src/mime/multipart/formdata_test.go @@ -176,7 +176,11 @@ func (r *failOnReadAfterErrorReader) Read(p []byte) (n int, err error) { // TestReadForm_NonFileMaxMemory asserts that the ReadForm maxMemory limit is applied // while processing non-file form data as well as file form data. func TestReadForm_NonFileMaxMemory(t *testing.T) { - largeTextValue := strings.Repeat("1", (10<<20)+25) + n := 10<<20 + 25 + if testing.Short() { + n = 10<<10 + 25 + } + largeTextValue := strings.Repeat("1", n) message := `--MyBoundary Content-Disposition: form-data; name="largetext" @@ -196,6 +200,9 @@ Content-Disposition: form-data; name="largetext" } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + if tc.maxMemory == 0 && testing.Short() { + t.Skip("skipping in -short mode") + } b := strings.NewReader(testBody) r := NewReader(b, boundary) f, err := r.ReadForm(tc.maxMemory) diff --git a/src/mime/multipart/multipart_test.go b/src/mime/multipart/multipart_test.go index 5a8102b822..5dc74b5ffe 100644 --- a/src/mime/multipart/multipart_test.go +++ b/src/mime/multipart/multipart_test.go @@ -832,7 +832,10 @@ func partsFromReader(r *Reader) ([]headerBody, error) { func TestParseAllSizes(t *testing.T) { t.Parallel() - const maxSize = 5 << 10 + maxSize := 5 << 10 + if testing.Short() { + maxSize = 512 + } var buf bytes.Buffer body := strings.Repeat("a", maxSize) bodyb := []byte(body) diff --git a/src/mime/quotedprintable/reader_test.go b/src/mime/quotedprintable/reader_test.go index f870bdaa8d..48a7ff6495 100644 --- a/src/mime/quotedprintable/reader_test.go +++ b/src/mime/quotedprintable/reader_test.go @@ -116,7 +116,11 @@ func TestExhaustive(t *testing.T) { var buf bytes.Buffer res := make(map[string]int) - everySequence("", "0A \r\n=", 6, func(s string) { + n := 6 + if testing.Short() { + n = 4 + } + everySequence("", "0A \r\n=", n, func(s string) { if strings.HasSuffix(s, "=") || strings.Contains(s, "==") { return } @@ -200,6 +204,13 @@ func TestExhaustive(t *testing.T) { invalid bytes after =: 3949 quotedprintable: invalid hex byte 0x0d: 2048 unexpected EOF: 194` + if testing.Short() { + want = `OK: 896 +invalid bytes after =: 100 +quotedprintable: invalid hex byte 0x0d: 26 +unexpected EOF: 3` + } + if got != want { t.Errorf("Got:\n%s\nWant:\n%s", got, want) } diff --git a/src/net/http/serve_test.go b/src/net/http/serve_test.go index 32ddd3dde9..d774915719 100644 --- a/src/net/http/serve_test.go +++ b/src/net/http/serve_test.go @@ -5758,8 +5758,12 @@ func TestServerDuplicateBackgroundRead(t *testing.T) { setParallel(t) defer afterTest(t) - const goroutines = 5 - const requests = 2000 + goroutines := 5 + requests := 2000 + if testing.Short() { + goroutines = 3 + requests = 100 + } hts := httptest.NewServer(HandlerFunc(NotFound)) defer hts.Close() diff --git a/src/os/exec/exec_test.go b/src/os/exec/exec_test.go index f9d73060a3..c9322f6b0f 100644 --- a/src/os/exec/exec_test.go +++ b/src/os/exec/exec_test.go @@ -691,6 +691,9 @@ func TestExtraFilesRace(t *testing.T) { } for i := 0; i < 10; i++ { + if testing.Short() && i >= 3 { + break + } la := listen() ca := helperCommand(t, "describefiles") ca.ExtraFiles = []*os.File{listenerFile(la)} diff --git a/src/runtime/internal/atomic/atomic_test.go b/src/runtime/internal/atomic/atomic_test.go index 25ece4354e..0ba75447e8 100644 --- a/src/runtime/internal/atomic/atomic_test.go +++ b/src/runtime/internal/atomic/atomic_test.go @@ -29,14 +29,18 @@ func runParallel(N, iter int, f func()) { } func TestXadduintptr(t *testing.T) { - const N = 20 - const iter = 100000 + N := 20 + iter := 100000 + if testing.Short() { + N = 10 + iter = 10000 + } inc := uintptr(100) total := uintptr(0) runParallel(N, iter, func() { atomic.Xadduintptr(&total, inc) }) - if want := uintptr(N * iter * inc); want != total { + if want := uintptr(N*iter) * inc; want != total { t.Fatalf("xadduintpr error, want %d, got %d", want, total) } total = 0 diff --git a/src/runtime/pprof/pprof_test.go b/src/runtime/pprof/pprof_test.go index 59dee26867..53496371a0 100644 --- a/src/runtime/pprof/pprof_test.go +++ b/src/runtime/pprof/pprof_test.go @@ -159,12 +159,27 @@ func testCPUProfile(t *testing.T, matches matchFunc, need []string, avoid []stri t.Skip("skipping on plan9") } - const maxDuration = 5 * time.Second + broken := false + switch runtime.GOOS { + case "darwin", "dragonfly", "netbsd", "illumos", "solaris": + broken = true + case "openbsd": + if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" { + broken = true + } + } + + maxDuration := 5 * time.Second + if testing.Short() && broken { + // If it's expected to be broken, no point waiting around. + maxDuration /= 10 + } + // If we're running a long test, start with a long duration // for tests that try to make sure something *doesn't* happen. duration := 5 * time.Second if testing.Short() { - duration = 200 * time.Millisecond + duration = 100 * time.Millisecond } // Profiling tests are inherently flaky, especially on a @@ -190,14 +205,10 @@ func testCPUProfile(t *testing.T, matches matchFunc, need []string, avoid []stri } } - switch runtime.GOOS { - case "darwin", "dragonfly", "netbsd", "illumos", "solaris": - t.Skipf("ignoring failure on %s; see golang.org/issue/13841", runtime.GOOS) - case "openbsd": - if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" { - t.Skipf("ignoring failure on %s/%s; see golang.org/issue/13841", runtime.GOOS, runtime.GOARCH) - } + if broken { + t.Skipf("ignoring failure on %s/%s; see golang.org/issue/13841", runtime.GOOS, runtime.GOARCH) } + // Ignore the failure if the tests are running in a QEMU-based emulator, // QEMU is not perfect at emulating everything. // IN_QEMU environmental variable is set by some of the Go builders. diff --git a/src/runtime/pprof/proto_test.go b/src/runtime/pprof/proto_test.go index 4452d51231..bcb4d3386d 100644 --- a/src/runtime/pprof/proto_test.go +++ b/src/runtime/pprof/proto_test.go @@ -207,11 +207,11 @@ ffffffffff600000-ffffffffff601000 r-xp 00000090 00:00 0 [vsysca 7ffc34343000 7ffc34345000 00000000 [vdso] ffffffffff600000 ffffffffff601000 00000090 [vsyscall] -00400000-07000000 r-xp 00000000 00:00 0 +00400000-07000000 r-xp 00000000 00:00 0 07000000-07093000 r-xp 06c00000 00:2e 536754 /path/to/gobench_server_main 07093000-0722d000 rw-p 06c92000 00:2e 536754 /path/to/gobench_server_main -0722d000-07b21000 rw-p 00000000 00:00 0 -c000000000-c000036000 rw-p 00000000 00:00 0 +0722d000-07b21000 rw-p 00000000 00:00 0 +c000000000-c000036000 rw-p 00000000 00:00 0 -> 07000000 07093000 06c00000 /path/to/gobench_server_main ` @@ -301,7 +301,7 @@ func TestProcSelfMaps(t *testing.T) { }) } -// TestMapping checkes the mapping section of CPU profiles +// TestMapping checks the mapping section of CPU profiles // has the HasFunctions field set correctly. If all PCs included // in the samples are successfully symbolized, the corresponding // mapping entry (in this test case, only one entry) should have diff --git a/src/runtime/pprof/testdata/mappingtest/main.go b/src/runtime/pprof/testdata/mappingtest/main.go index 7850faab0d..476b9e88a3 100644 --- a/src/runtime/pprof/testdata/mappingtest/main.go +++ b/src/runtime/pprof/testdata/mappingtest/main.go @@ -69,7 +69,7 @@ func main() { if err := pprof.StartCPUProfile(os.Stdout); err != nil { log.Fatal("can't start CPU profile: ", err) } - time.Sleep(1 * time.Second) + time.Sleep(200 * time.Millisecond) pprof.StopCPUProfile() if err := os.Stdout.Close(); err != nil { diff --git a/src/runtime/semasleep_test.go b/src/runtime/semasleep_test.go index b931095619..f5b4a50697 100644 --- a/src/runtime/semasleep_test.go +++ b/src/runtime/semasleep_test.go @@ -7,11 +7,7 @@ package runtime_test import ( - "internal/testenv" - "io/ioutil" - "os" "os/exec" - "path/filepath" "syscall" "testing" "time" @@ -24,39 +20,14 @@ func TestSpuriousWakeupsNeverHangSemasleep(t *testing.T) { if *flagQuick { t.Skip("-quick") } - testenv.MustHaveGoBuild(t) - tempDir, err := ioutil.TempDir("", "issue-27250") + + exe, err := buildTestProg(t, "testprog") if err != nil { - t.Fatalf("Failed to create the temp directory: %v", err) - } - defer os.RemoveAll(tempDir) - - repro := ` - package main - - import "time" - - func main() { - <-time.After(1 * time.Second) - } - ` - mainPath := filepath.Join(tempDir, "main.go") - if err := ioutil.WriteFile(mainPath, []byte(repro), 0644); err != nil { - t.Fatalf("Failed to create temp file for repro.go: %v", err) - } - binaryPath := filepath.Join(tempDir, "binary") - - // Build the binary so that we can send the signal to its PID. - out, err := exec.Command(testenv.GoToolPath(t), "build", "-o", binaryPath, mainPath).CombinedOutput() - if err != nil { - t.Fatalf("Failed to compile the binary: err: %v\nOutput: %s\n", err, out) - } - if err := os.Chmod(binaryPath, 0755); err != nil { - t.Fatalf("Failed to chmod binary: %v", err) + t.Fatal(err) } - // Now run the binary. - cmd := exec.Command(binaryPath) + start := time.Now() + cmd := exec.Command(exe, "After1") if err := cmd.Start(); err != nil { t.Fatalf("Failed to start command: %v", err) } @@ -85,6 +56,9 @@ func TestSpuriousWakeupsNeverHangSemasleep(t *testing.T) { if err != nil { t.Fatalf("The program returned but unfortunately with an error: %v", err) } + if time.Since(start) < 100*time.Millisecond { + t.Fatalf("The program stopped too quickly.") + } return } } diff --git a/src/runtime/testdata/testprog/deadlock.go b/src/runtime/testdata/testprog/deadlock.go index ca2be57911..5f0d120004 100644 --- a/src/runtime/testdata/testprog/deadlock.go +++ b/src/runtime/testdata/testprog/deadlock.go @@ -112,12 +112,16 @@ func RecursivePanic() { } func GoexitExit() { + println("t1") go func() { time.Sleep(time.Millisecond) }() i := 0 + println("t2") runtime.SetFinalizer(&i, func(p *int) {}) + println("t3") runtime.GC() + println("t4") runtime.Goexit() } diff --git a/src/runtime/testdata/testprog/sleep.go b/src/runtime/testdata/testprog/sleep.go new file mode 100644 index 0000000000..86e2f6cfe6 --- /dev/null +++ b/src/runtime/testdata/testprog/sleep.go @@ -0,0 +1,17 @@ +// Copyright 2019 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 "time" + +// for golang.org/issue/27250 + +func init() { + register("After1", After1) +} + +func After1() { + <-time.After(1 * time.Second) +} diff --git a/src/runtime/trace/trace_test.go b/src/runtime/trace/trace_test.go index e289fa5e12..235845df4e 100644 --- a/src/runtime/trace/trace_test.go +++ b/src/runtime/trace/trace_test.go @@ -186,6 +186,10 @@ func TestTraceStress(t *testing.T) { if IsEnabled() { t.Skip("skipping because -test.trace is set") } + if testing.Short() { + t.Skip("skipping in -short mode") + } + var wg sync.WaitGroup done := make(chan bool) diff --git a/src/sync/pool_test.go b/src/sync/pool_test.go index 796a5a0a73..ff1174cc15 100644 --- a/src/sync/pool_test.go +++ b/src/sync/pool_test.go @@ -105,6 +105,9 @@ func testPool(t *testing.T, drain bool) { const N = 100 loop: for try := 0; try < 3; try++ { + if try == 1 && testing.Short() { + break + } var fin, fin1 uint32 for i := 0; i < N; i++ { v := new(string) diff --git a/src/syscall/getdirentries_test.go b/src/syscall/getdirentries_test.go index b20ae1d1e3..8505a0bb89 100644 --- a/src/syscall/getdirentries_test.go +++ b/src/syscall/getdirentries_test.go @@ -26,6 +26,9 @@ func TestGetdirentries(t *testing.T) { } } func testGetdirentries(t *testing.T, count int) { + if count > 100 && testing.Short() && os.Getenv("GO_BUILDER_NAME") == "" { + t.Skip("skipping in -short mode") + } d, err := ioutil.TempDir("", "getdirentries-test") if err != nil { t.Fatalf("Tempdir: %v", err) diff --git a/src/testing/quick/quick_test.go b/src/testing/quick/quick_test.go index 4246cd1d3b..9df6dd4679 100644 --- a/src/testing/quick/quick_test.go +++ b/src/testing/quick/quick_test.go @@ -319,7 +319,7 @@ func TestInt64(t *testing.T) { } return true } - cfg := &Config{MaxCount: 100000} + cfg := &Config{MaxCount: 10000} Check(f, cfg) if uint64(lo)>>62 == 0 || uint64(hi)>>62 == 0 { t.Errorf("int64 returned range %#016x,%#016x; does not look like full range", lo, hi) diff --git a/src/text/template/exec_test.go b/src/text/template/exec_test.go index c45df89d59..63ccd5c3c0 100644 --- a/src/text/template/exec_test.go +++ b/src/text/template/exec_test.go @@ -1417,6 +1417,9 @@ func TestEvalFieldErrors(t *testing.T) { } func TestMaxExecDepth(t *testing.T) { + if testing.Short() { + t.Skip("skipping in -short mode") + } tmpl := Must(New("tmpl").Parse(`{{template "tmpl" .}}`)) err := tmpl.Execute(ioutil.Discard, nil) got := "" From a3d4655c2435e3777c45f09650539b943bab1c66 Mon Sep 17 00:00:00 2001 From: Filippo Valsorda Date: Tue, 21 May 2019 14:54:54 -0400 Subject: [PATCH 33/50] crypto/x509: fix value ownership in isSSLPolicy on macOS CFDictionaryGetValueIfPresent does not take ownership of the value, so releasing the properties dictionary before passing the value to CFEqual can crash. Not really clear why this works most of the time. See https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html Fixes #28092 Hopefully fixes #30763 Change-Id: I5ee7ca276b753a48abc3aedfb78b8af68b448dd4 Reviewed-on: https://go-review.googlesource.com/c/go/+/178537 Reviewed-by: Adam Langley --- src/crypto/x509/root_cgo_darwin.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/crypto/x509/root_cgo_darwin.go b/src/crypto/x509/root_cgo_darwin.go index e6332072d6..1c20f26acb 100644 --- a/src/crypto/x509/root_cgo_darwin.go +++ b/src/crypto/x509/root_cgo_darwin.go @@ -16,7 +16,7 @@ package x509 #include #include -static bool isSSLPolicy(SecPolicyRef policyRef) { +static Boolean isSSLPolicy(SecPolicyRef policyRef) { if (!policyRef) { return false; } @@ -24,13 +24,13 @@ static bool isSSLPolicy(SecPolicyRef policyRef) { if (properties == NULL) { return false; } + Boolean isSSL = false; CFTypeRef value = NULL; if (CFDictionaryGetValueIfPresent(properties, kSecPolicyOid, (const void **)&value)) { - CFRelease(properties); - return CFEqual(value, kSecPolicyAppleSSL); + isSSL = CFEqual(value, kSecPolicyAppleSSL); } CFRelease(properties); - return false; + return isSSL; } // sslTrustSettingsResult obtains the final kSecTrustSettingsResult value From 2326a668781a664707f5775d896879668ab378e8 Mon Sep 17 00:00:00 2001 From: Filippo Valsorda Date: Tue, 21 May 2019 15:00:50 -0400 Subject: [PATCH 34/50] crypto/x509: fix and cleanup loadSystemRoots on macOS Note how untrustedData is never NULL, so loadSystemRoots was checking the wrong thing. Also, renamed the C function to CopyPEMRoots to follow the CoreFoundation naming convention on ownership. Finally, redirect all debug output to standard error. Change-Id: Ie80abefadf8974a75c0646aa02fcfcebcbe3bde8 Reviewed-on: https://go-review.googlesource.com/c/go/+/178538 Reviewed-by: Adam Langley --- src/crypto/x509/root_cgo_darwin.go | 39 ++++++++++++++--------------- src/crypto/x509/root_darwin_test.go | 6 ++--- 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/src/crypto/x509/root_cgo_darwin.go b/src/crypto/x509/root_cgo_darwin.go index 1c20f26acb..e8fc1665f6 100644 --- a/src/crypto/x509/root_cgo_darwin.go +++ b/src/crypto/x509/root_cgo_darwin.go @@ -143,7 +143,7 @@ static Boolean isRootCertificate(SecCertificateRef cert, CFErrorRef *errRef) { return equal; } -// FetchPEMRoots fetches the system's list of trusted X.509 root certificates +// CopyPEMRoots fetches the system's list of trusted X.509 root certificates // for the kSecTrustSettingsPolicy SSL. // // On success it returns 0 and fills pemRoots with a CFDataRef that contains the extracted root @@ -152,15 +152,15 @@ static Boolean isRootCertificate(SecCertificateRef cert, CFErrorRef *errRef) { // // Note: The CFDataRef returned in pemRoots and untrustedPemRoots must // be released (using CFRelease) after we've consumed its content. -int FetchPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots, bool debugDarwinRoots) { +int CopyPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots, bool debugDarwinRoots) { int i; if (debugDarwinRoots) { - printf("crypto/x509: kSecTrustSettingsResultInvalid = %d\n", kSecTrustSettingsResultInvalid); - printf("crypto/x509: kSecTrustSettingsResultTrustRoot = %d\n", kSecTrustSettingsResultTrustRoot); - printf("crypto/x509: kSecTrustSettingsResultTrustAsRoot = %d\n", kSecTrustSettingsResultTrustAsRoot); - printf("crypto/x509: kSecTrustSettingsResultDeny = %d\n", kSecTrustSettingsResultDeny); - printf("crypto/x509: kSecTrustSettingsResultUnspecified = %d\n", kSecTrustSettingsResultUnspecified); + fprintf(stderr, "crypto/x509: kSecTrustSettingsResultInvalid = %d\n", kSecTrustSettingsResultInvalid); + fprintf(stderr, "crypto/x509: kSecTrustSettingsResultTrustRoot = %d\n", kSecTrustSettingsResultTrustRoot); + fprintf(stderr, "crypto/x509: kSecTrustSettingsResultTrustAsRoot = %d\n", kSecTrustSettingsResultTrustAsRoot); + fprintf(stderr, "crypto/x509: kSecTrustSettingsResultDeny = %d\n", kSecTrustSettingsResultDeny); + fprintf(stderr, "crypto/x509: kSecTrustSettingsResultUnspecified = %d\n", kSecTrustSettingsResultUnspecified); } // Get certificates from all domains, not just System, this lets @@ -170,7 +170,7 @@ int FetchPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots, bool debugD kSecTrustSettingsDomainAdmin, kSecTrustSettingsDomainUser }; int numDomains = sizeof(domains)/sizeof(SecTrustSettingsDomain); - if (pemRoots == NULL) { + if (pemRoots == NULL || untrustedPemRoots == NULL) { return -1; } @@ -186,8 +186,6 @@ int FetchPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots, bool debugD CFIndex numCerts = CFArrayGetCount(certs); for (j = 0; j < numCerts; j++) { - CFDataRef data = NULL; - CFArrayRef trustSettings = NULL; SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(certs, j); if (cert == NULL) { continue; @@ -206,7 +204,7 @@ int FetchPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots, bool debugD CFErrorRef errRef = NULL; CFStringRef summary = SecCertificateCopyShortDescription(NULL, cert, &errRef); if (errRef != NULL) { - printf("crypto/x509: SecCertificateCopyShortDescription failed\n"); + fprintf(stderr, "crypto/x509: SecCertificateCopyShortDescription failed\n"); CFRelease(errRef); continue; } @@ -215,7 +213,7 @@ int FetchPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots, bool debugD CFIndex maxSize = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1; char *buffer = malloc(maxSize); if (CFStringGetCString(summary, buffer, maxSize, kCFStringEncodingUTF8)) { - printf("crypto/x509: %s returned %d\n", buffer, (int)result); + fprintf(stderr, "crypto/x509: %s returned %d\n", buffer, (int)result); } free(buffer); CFRelease(summary); @@ -251,6 +249,7 @@ int FetchPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots, bool debugD continue; } + CFDataRef data = NULL; err = SecItemExport(cert, kSecFormatX509Cert, kSecItemPemArmour, NULL, &data); if (err != noErr) { continue; @@ -274,22 +273,22 @@ import ( ) func loadSystemRoots() (*CertPool, error) { - roots := NewCertPool() - - var data C.CFDataRef = 0 - var untrustedData C.CFDataRef = 0 - err := C.FetchPEMRoots(&data, &untrustedData, C.bool(debugDarwinRoots)) + var data, untrustedData C.CFDataRef + err := C.CopyPEMRoots(&data, &untrustedData, C.bool(debugDarwinRoots)) if err == -1 { return nil, errors.New("crypto/x509: failed to load darwin system roots with cgo") } - defer C.CFRelease(C.CFTypeRef(data)) + defer C.CFRelease(C.CFTypeRef(untrustedData)) + buf := C.GoBytes(unsafe.Pointer(C.CFDataGetBytePtr(data)), C.int(C.CFDataGetLength(data))) + roots := NewCertPool() roots.AppendCertsFromPEM(buf) - if untrustedData == 0 { + + if C.CFDataGetLength(untrustedData) == 0 { return roots, nil } - defer C.CFRelease(C.CFTypeRef(untrustedData)) + buf = C.GoBytes(unsafe.Pointer(C.CFDataGetBytePtr(untrustedData)), C.int(C.CFDataGetLength(untrustedData))) untrustedRoots := NewCertPool() untrustedRoots.AppendCertsFromPEM(buf) diff --git a/src/crypto/x509/root_darwin_test.go b/src/crypto/x509/root_darwin_test.go index 1165a97e20..0a1529e833 100644 --- a/src/crypto/x509/root_darwin_test.go +++ b/src/crypto/x509/root_darwin_test.go @@ -120,12 +120,10 @@ func TestSystemRoots(t *testing.T) { if t.Failed() && debugDarwinRoots { cmd := exec.Command("security", "dump-trust-settings") - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr + cmd.Stdout, cmd.Stderr = os.Stderr, os.Stderr cmd.Run() cmd = exec.Command("security", "dump-trust-settings", "-d") - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr + cmd.Stdout, cmd.Stderr = os.Stderr, os.Stderr cmd.Run() } } From 42bb47689310ebe2fedd165db98402a7874dc6be Mon Sep 17 00:00:00 2001 From: Filippo Valsorda Date: Wed, 22 May 2019 11:10:06 -0400 Subject: [PATCH 35/50] crypto/x509: include roots with empty or multiple policies on macOS To a fifth reading of the relevant docs, it looks like 1) a constraint dictionary with no policy applies to all of them; 2) multiple applying constraint dictionaries should have their results OR'd; 3) untrusted certificates in the keychain should be used for chain building. This fixes 1), approximates 2) and punts on 3). Fixes #30672 Fixes #30471 Change-Id: Ibbaabf0b77d267377c0b5de07abca3445c2c2302 Reviewed-on: https://go-review.googlesource.com/c/go/+/178539 Reviewed-by: Adam Langley --- src/crypto/x509/root_cgo_darwin.go | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/crypto/x509/root_cgo_darwin.go b/src/crypto/x509/root_cgo_darwin.go index e8fc1665f6..255a8d3525 100644 --- a/src/crypto/x509/root_cgo_darwin.go +++ b/src/crypto/x509/root_cgo_darwin.go @@ -51,6 +51,7 @@ static SInt32 sslTrustSettingsResult(SecCertificateRef cert) { } // > no trust settings [...] means "this certificate must be verified to a known trusted certificate” + // (Should this cause a fallback from user to admin domain? It's unclear.) if (err != errSecSuccess || trustSettings == NULL) { if (trustSettings != NULL) CFRelease(trustSettings); return kSecTrustSettingsResultUnspecified; @@ -77,16 +78,12 @@ static SInt32 sslTrustSettingsResult(SecCertificateRef cert) { for (m = 0; m < CFArrayGetCount(trustSettings); m++) { CFDictionaryRef tSetting = (CFDictionaryRef)CFArrayGetValueAtIndex(trustSettings, m); - // First, check if this trust setting applies to our policy. We assume - // only one will. The docs suggest that there might be multiple applying - // but don't explain how to combine them. + // First, check if this trust setting is constrained to a non-SSL policy. SecPolicyRef policyRef; if (CFDictionaryGetValueIfPresent(tSetting, _kSecTrustSettingsPolicy, (const void**)&policyRef)) { if (!isSSLPolicy(policyRef)) { continue; } - } else { - continue; } if (CFDictionaryContainsKey(tSetting, _kSecTrustSettingsPolicyString)) { @@ -98,13 +95,23 @@ static SInt32 sslTrustSettingsResult(SecCertificateRef cert) { if (CFDictionaryGetValueIfPresent(tSetting, _kSecTrustSettingsResult, (const void**)&cfNum)) { CFNumberGetValue(cfNum, kCFNumberSInt32Type, &result); } else { - // > If the value of the kSecTrustSettingsResult component is not - // > kSecTrustSettingsResultUnspecified for a usage constraints dictionary that has - // > no constraints, the default value kSecTrustSettingsResultTrustRoot is assumed. + // > If this key is not present, a default value of + // > kSecTrustSettingsResultTrustRoot is assumed. result = kSecTrustSettingsResultTrustRoot; } - break; + // If multiple dictionaries match, we are supposed to "OR" them, + // the semantics of which are not clear. Since TrustRoot and TrustAsRoot + // are mutually exclusive, Deny should probably override, and Invalid and + // Unspecified be overridden, approximate this by stopping at the first + // TrustRoot, TrustAsRoot or Deny. + if (result == kSecTrustSettingsResultTrustRoot) { + break; + } else if (result == kSecTrustSettingsResultTrustAsRoot) { + break; + } else if (result == kSecTrustSettingsResultDeny) { + break; + } } // If trust settings are present, but none of them match the policy... @@ -244,6 +251,10 @@ int CopyPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots, bool debugDa } else if (result == kSecTrustSettingsResultDeny) { appendTo = combinedUntrustedData; } else if (result == kSecTrustSettingsResultUnspecified) { + // Certificates with unspecified trust should probably be added to a pool of + // intermediates for chain building, or checked for transitive trust and + // added to the root pool (which is an imprecise approximation because it + // cuts chains short) but we don't support either at the moment. TODO. continue; } else { continue; From a326bc6df27309815e4a2ae005adef233cfb9ea9 Mon Sep 17 00:00:00 2001 From: Agniva De Sarker Date: Wed, 22 May 2019 00:10:32 +0200 Subject: [PATCH 36/50] net/url: clarify that RawPath is optionally set Fixes #29662 Change-Id: I38b52b96712e44a323333da17dbbc883516773b6 Reviewed-on: https://go-review.googlesource.com/c/go/+/177900 Reviewed-by: Brad Fitzpatrick --- src/net/url/url.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/net/url/url.go b/src/net/url/url.go index 9ff707b24e..7f6ff93ce4 100644 --- a/src/net/url/url.go +++ b/src/net/url/url.go @@ -337,10 +337,11 @@ func escape(s string, mode encoding) string { // Note that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/. // A consequence is that it is impossible to tell which slashes in the Path were // slashes in the raw URL and which were %2f. This distinction is rarely important, -// but when it is, code must not use Path directly. -// The Parse function sets both Path and RawPath in the URL it returns, -// and URL's String method uses RawPath if it is a valid encoding of Path, -// by calling the EscapedPath method. +// but when it is, the code should use RawPath, an optional field which only gets +// set if the default encoding is different from Path. +// +// URL's String method uses the EscapedPath method to obtain the path. See the +// EscapedPath method for more details. type URL struct { Scheme string Opaque string // encoded opaque data From 94a9dad8fdcd7adf2036482391f715ea3ab35cd9 Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Wed, 22 May 2019 11:06:09 -0700 Subject: [PATCH 37/50] cmd/compile: fix capture-by-reference of return parameters As an optimization, function literals capture variables by value when they're not assigned and their address has not been taken. Because result parameters are implicitly assigned through return statements (which do not otherwise set the "assigned" flag), result parameters are explicitly handled to always capture by reference. However, the logic was slightly mistaken because it was only checking if the variable in the immediately enclosing context was a return parameter, whereas in a multiply-nested function literal it would itself be another closure variable (PAUTOHEAP) rather than a return parameter (PPARAMOUT). The fix is to simply test the outermost variable, like the rest of the if statement's tests were already doing. Fixes #32175. Change-Id: Ibadde033ff89a1b47584b3f56c0014d8e5a74512 Reviewed-on: https://go-review.googlesource.com/c/go/+/178541 Run-TryBot: Matthew Dempsky Reviewed-by: Brad Fitzpatrick TryBot-Result: Gobot Gobot --- src/cmd/compile/internal/gc/closure.go | 2 +- test/fixedbugs/issue32175.go | 22 ++++++++++++++++++++++ test/fixedbugs/issue32175.out | 1 + 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 test/fixedbugs/issue32175.go create mode 100644 test/fixedbugs/issue32175.out diff --git a/src/cmd/compile/internal/gc/closure.go b/src/cmd/compile/internal/gc/closure.go index 89e2a4ef00..397162dac8 100644 --- a/src/cmd/compile/internal/gc/closure.go +++ b/src/cmd/compile/internal/gc/closure.go @@ -186,7 +186,7 @@ func capturevars(xfunc *Node) { outermost := v.Name.Defn // out parameters will be assigned to implicitly upon return. - if outer.Class() != PPARAMOUT && !outermost.Addrtaken() && !outermost.Assigned() && v.Type.Width <= 128 { + if outermost.Class() != PPARAMOUT && !outermost.Addrtaken() && !outermost.Assigned() && v.Type.Width <= 128 { v.Name.SetByval(true) } else { outermost.SetAddrtaken(true) diff --git a/test/fixedbugs/issue32175.go b/test/fixedbugs/issue32175.go new file mode 100644 index 0000000000..a67735148e --- /dev/null +++ b/test/fixedbugs/issue32175.go @@ -0,0 +1,22 @@ +// run + +// Copyright 2019 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 + +// This used to print 0, because x was incorrectly captured by value. + +func f() (x int) { + defer func() func() { + return func() { + println(x) + } + }()() + return 42 +} + +func main() { + f() +} diff --git a/test/fixedbugs/issue32175.out b/test/fixedbugs/issue32175.out new file mode 100644 index 0000000000..d81cc0710e --- /dev/null +++ b/test/fixedbugs/issue32175.out @@ -0,0 +1 @@ +42 From 983986f23d81eae6ee202bd31383d04e73187536 Mon Sep 17 00:00:00 2001 From: kawakami Date: Thu, 16 May 2019 03:11:44 +0900 Subject: [PATCH 38/50] image/gif: fix transparency loss when encoding a wrapped *image.Paletted This keeps transparency of a wrapped image.Image even after it is encoded. Fixes #30995 Change-Id: I1f7ac98b1741f83ed740f6eda6c36b7e9b16e5af Reviewed-on: https://go-review.googlesource.com/c/go/+/177377 Reviewed-by: Hayato Kawakami Reviewed-by: Benny Siegert Run-TryBot: Benny Siegert TryBot-Result: Gobot Gobot --- src/image/gif/writer.go | 14 ++++- src/image/gif/writer_test.go | 81 ++++++++++++++++++++++++++-- src/image/testdata/triangle-001.gif | Bin 0 -> 1476 bytes 3 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 src/image/testdata/triangle-001.gif diff --git a/src/image/gif/writer.go b/src/image/gif/writer.go index 5819df0dd0..7220446de5 100644 --- a/src/image/gif/writer.go +++ b/src/image/gif/writer.go @@ -433,8 +433,18 @@ func Encode(w io.Writer, m image.Image, o *Options) error { opts.Drawer = draw.FloydSteinberg } - pm, ok := m.(*image.Paletted) - if !ok || len(pm.Palette) > opts.NumColors { + pm, _ := m.(*image.Paletted) + if pm == nil { + if cp, ok := m.ColorModel().(color.Palette); ok { + pm = image.NewPaletted(b, cp) + for y := b.Min.Y; y < b.Max.Y; y++ { + for x := b.Min.X; x < b.Max.X; x++ { + pm.Set(x, y, cp.Convert(m.At(x, y))) + } + } + } + } + if pm == nil || len(pm.Palette) > opts.NumColors { // Set pm to be a palettedized copy of m, including its bounds, which // might not start at (0, 0). // diff --git a/src/image/gif/writer_test.go b/src/image/gif/writer_test.go index 91275bb907..0bc24d1bee 100644 --- a/src/image/gif/writer_test.go +++ b/src/image/gif/writer_test.go @@ -48,11 +48,17 @@ func delta(u0, u1 uint32) int64 { // have the same bounds. func averageDelta(m0, m1 image.Image) int64 { b := m0.Bounds() + return averageDeltaBound(m0, m1, b, b) +} + +// averageDeltaBounds returns the average delta in RGB space. The average delta is +// calulated in the specified bounds. +func averageDeltaBound(m0, m1 image.Image, b0, b1 image.Rectangle) int64 { var sum, n int64 - for y := b.Min.Y; y < b.Max.Y; y++ { - for x := b.Min.X; x < b.Max.X; x++ { + for y := b0.Min.Y; y < b0.Max.Y; y++ { + for x := b0.Min.X; x < b0.Max.X; x++ { c0 := m0.At(x, y) - c1 := m1.At(x, y) + c1 := m1.At(x-b0.Min.X+b1.Min.X, y-b0.Min.Y+b1.Min.Y) r0, g0, b0, _ := c0.RGBA() r1, g1, b1, _ := c1.RGBA() sum += delta(r0, r1) @@ -581,6 +587,75 @@ func TestEncodeCroppedSubImages(t *testing.T) { } } +type offsetImage struct { + image.Image + Rect image.Rectangle +} + +func (i offsetImage) Bounds() image.Rectangle { + return i.Rect +} + +func TestEncodeWrappedImage(t *testing.T) { + m0, err := readImg("../testdata/video-001.gif") + if err != nil { + t.Fatalf("readImg: %v", err) + } + + // Case 1: Enocde a wrapped image.Image + buf := new(bytes.Buffer) + w0 := offsetImage{m0, m0.Bounds()} + err = Encode(buf, w0, nil) + if err != nil { + t.Fatalf("Encode: %v", err) + } + w1, err := Decode(buf) + if err != nil { + t.Fatalf("Dencode: %v", err) + } + avgDelta := averageDelta(m0, w1) + if avgDelta > 0 { + t.Fatalf("Wrapped: average delta is too high. expected: 0, got %d", avgDelta) + } + + // Case 2: Enocde a wrapped image.Image with offset + b0 := image.Rectangle{ + Min: image.Point{ + X: 128, + Y: 64, + }, + Max: image.Point{ + X: 256, + Y: 128, + }, + } + w0 = offsetImage{m0, b0} + buf = new(bytes.Buffer) + err = Encode(buf, w0, nil) + if err != nil { + t.Fatalf("Encode: %v", err) + } + w1, err = Decode(buf) + if err != nil { + t.Fatalf("Dencode: %v", err) + } + + b1 := image.Rectangle{ + Min: image.Point{ + X: 0, + Y: 0, + }, + Max: image.Point{ + X: 128, + Y: 64, + }, + } + avgDelta = averageDeltaBound(m0, w1, b0, b1) + if avgDelta > 0 { + t.Fatalf("Wrapped and offset: average delta is too high. expected: 0, got %d", avgDelta) + } +} + func BenchmarkEncode(b *testing.B) { bo := image.Rect(0, 0, 640, 480) rnd := rand.New(rand.NewSource(123)) diff --git a/src/image/testdata/triangle-001.gif b/src/image/testdata/triangle-001.gif new file mode 100644 index 0000000000000000000000000000000000000000..f3d45bbfa431634a26a59bc838fd638e2400e0cb GIT binary patch literal 1476 zcmZ8g2~d+)5MC5IRMH?4bQGx(Mec;dP|!h1NjNMZM-sU#Fd;A*%MnP7T4zGU3ezgk z3RK&%9)QP`LyFQ?2Y-cNt%h(6M=I(lf~BoRgwz;?(tSZ@+V0Go-Tn64@9n>D{_x1K zz@QAUD1s7rV?u}qKE!|k5+D^~Arj(&iy0r75C%~ghXV^wBxb~N%hR?2=5nSDIN4Ck zkCh(^oX6e>n%!HIBG5h)!LqGJYB3^4u92#!oS{rz^WNGZg2l)oR*yVlI$k2Asb5ng z_C_k(0-$r5kpig*e1!QuH`%8D;HP8&*4X0~hx(xyqaLw)7E-g zN}cCloSNrpj=ZE`5x{<&f!REzN<=?;AzLkQ2r=JBa{6f_wV?%PfDp4L`Hn=aGtm>? zb<`SWOsN*?q-O0frJ_BYQIS}NG4V^}2D2w3miS%Gg$5OwgJGPXh3IV#Fj87eve$X@ zdoF@C7<$@;Ks@qha2~Q7OGdMr%uO&-Bb=?!toA`ZsgaoIT4OB=PaxvlUZc5>-~v1} z#6$koNAyU(Fb@xV2$qiiq?-Z14`2_*WIsfgya&nuzaKIS(H?tZ% zuz&%sz|152A^csq58@Z@XJQ>6EP5}KmnT-_NOI+csrk}^47r4v^-)GPD_fcc4AeY~ zynFOm;GutWA9x{t$qwfYlB$`ApQ^$4OHWrH!<^v6XqXdht%Iq(+Vir}$Vzu%W2W@t=$&d` ziLN$jdaTQXqnH@|#ok%>^_EZQF5B$Kd(T8xvD)@9+!D^m)x9fER{Sok5B)Z`>+ZlV zZ9@iC=3?XbH0h{hpixo!!Ykzm*@Y_#&!LIrEAnR(vtJFd)2_$Q(se8KK5^~Ew(N=H zdSCIabSKxc)S$6UZ8b-wxwm&Z`?C}L;tjJ2hTq!jgjadN`~Lbv-5}`@c@GEV^t37- z57rMWlOG&Xy{2E=^YZz~{_=I(bCss)C;2D0Z+B{AE5-+##OE5FJe3m<&K;O@Wq;$o z*YM=%ne3(yJwJXqaKHPot?HWYmFd|Bx-`|??Y|ez*w%qfWnM@b&1)%F#}HK9IJszX^%j>)+>)~5jx;1?*&W!O>~OA5#M~wIb`P*^8SpR4 zY3{6ApZ7iEOR6B!Qkh!Qmy>tDU%#{a{@}y0farZEzFU!USafIkgZ92JhHmd1YI~1g zWb@8Y(n0=4x=Mf6s>8}S!Ydh8ip%~KM2Xd*Wi Date: Sat, 2 Mar 2019 19:58:13 +0000 Subject: [PATCH 39/50] encoding/gob: properly ignore errors Change-Id: I8827cef0f57459384329c50c51795350da0ede4b GitHub-Last-Rev: c9ad9e12b5a0fff47c21a8c299b762b64b8c9c7c GitHub-Pull-Request: golang/go#30010 Reviewed-on: https://go-review.googlesource.com/c/go/+/160434 Run-TryBot: Bryan C. Mills TryBot-Result: Gobot Gobot Reviewed-by: Bryan C. Mills --- src/encoding/gob/decgen.go | 4 +++- src/encoding/gob/encgen.go | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/encoding/gob/decgen.go b/src/encoding/gob/decgen.go index bad4fe5d92..1c31e66625 100644 --- a/src/encoding/gob/decgen.go +++ b/src/encoding/gob/decgen.go @@ -185,10 +185,12 @@ func main() { log.Fatal("source format error:", err) } fd, err := os.Create(*output) - _, err = fd.Write(source) if err != nil { log.Fatal(err) } + if _, err := fd.Write(source); err != nil { + log.Fatal(err) + } } func printMaps(b *bytes.Buffer, upperClass string) { diff --git a/src/encoding/gob/encgen.go b/src/encoding/gob/encgen.go index 0c051d2e84..409b8c9d95 100644 --- a/src/encoding/gob/encgen.go +++ b/src/encoding/gob/encgen.go @@ -164,10 +164,12 @@ func main() { log.Fatal("source format error:", err) } fd, err := os.Create(*output) - _, err = fd.Write(source) if err != nil { log.Fatal(err) } + if _, err := fd.Write(source); err != nil { + log.Fatal(err) + } } func printMaps(b *bytes.Buffer, upperClass string) { From 7a567a631f48f19817a4c9a221e9951ffebfa8cb Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Tue, 21 May 2019 19:02:00 +0000 Subject: [PATCH 40/50] cmd/dist: support using cross-compiled std test binaries for slow builders We want the builders to be able to cross-compile test binaries for a few of the super slow builders that require either slow hardware or slow full CPU emulation. Updates golang/go#31217 Change-Id: I8d33b18efaf788f6f131354b2917ac9738ca975e Reviewed-on: https://go-review.googlesource.com/c/go/+/178399 Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- src/cmd/dist/test.go | 71 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go index 833baf8f91..f63c94697c 100644 --- a/src/cmd/dist/test.go +++ b/src/cmd/dist/test.go @@ -12,6 +12,7 @@ import ( "log" "os" "os/exec" + "path" "path/filepath" "reflect" "regexp" @@ -277,8 +278,17 @@ func (t *tester) tags() string { return "-tags=" } +// timeoutDuration converts the provided number of seconds into a +// time.Duration, scaled by the t.timeoutScale factor. +func (t *tester) timeoutDuration(sec int) time.Duration { + return time.Duration(sec) * time.Second * time.Duration(t.timeoutScale) +} + +// timeout returns the "-timeout=" string argument to "go test" given +// the number of seconds of timeout. It scales it by the +// t.timeoutScale factor. func (t *tester) timeout(sec int) string { - return "-timeout=" + fmt.Sprint(time.Duration(sec)*time.Second*time.Duration(t.timeoutScale)) + return "-timeout=" + t.timeoutDuration(sec).String() } // ranGoTest and stdMatches are state closed over by the stdlib @@ -319,6 +329,11 @@ func (t *tester) registerStdTest(pkg string) { break } } + // Special case for our slow cross-compiled + // qemu builders: + if t.shouldUsePrecompiledStdTest() { + return t.runPrecompiledStdTest(t.timeoutDuration(timeoutSec)) + } args := []string{ "test", short(), @@ -1416,6 +1431,60 @@ func (t *tester) makeGOROOTUnwritable() { } } +// shouldUsePrecompiledStdTest reports whether "dist test" should use +// a pre-compiled go test binary on disk rather than running "go test" +// and compiling it again. This is used by our slow qemu-based builder +// that do full processor emulation where we cross-compile the +// make.bash step as well as pre-compile each std test binary. +// +// This only reports true if dist is run with an single go_test:foo +// argument (as the build coordinator does with our slow qemu-based +// builders), we're in a builder environment ("GO_BUILDER_NAME" is set), +// and the pre-built test binary exists. +func (t *tester) shouldUsePrecompiledStdTest() bool { + bin := t.prebuiltGoPackageTestBinary() + if bin == "" { + return false + } + _, err := os.Stat(bin) + return err == nil +} + +// prebuiltGoPackageTestBinary returns the path where we'd expect +// the pre-built go test binary to be on disk when dist test is run with +// a single argument. +// It returns an empty string if a pre-built binary should not be used. +func (t *tester) prebuiltGoPackageTestBinary() string { + if len(stdMatches) != 1 || t.race || t.compileOnly || os.Getenv("GO_BUILDER_NAME") == "" { + return "" + } + pkg := stdMatches[0] + return filepath.Join(os.Getenv("GOROOT"), "src", pkg, path.Base(pkg)+".test") +} + +// runPrecompiledStdTest runs the pre-compiled standard library package test binary. +// See shouldUsePrecompiledStdTest above; it must return true for this to be called. +func (t *tester) runPrecompiledStdTest(timeout time.Duration) error { + bin := t.prebuiltGoPackageTestBinary() + fmt.Fprintf(os.Stderr, "# %s: using pre-built %s...\n", stdMatches[0], bin) + cmd := exec.Command(bin, "-test.short", "-test.timeout="+timeout.String()) + cmd.Dir = filepath.Dir(bin) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Start(); err != nil { + return err + } + // And start a timer to kill the process if it doesn't kill + // itself in the prescribed timeout. + const backupKillFactor = 1.05 // add 5% + timer := time.AfterFunc(time.Duration(float64(timeout)*backupKillFactor), func() { + fmt.Fprintf(os.Stderr, "# %s: timeout running %s; killing...\n", stdMatches[0], bin) + cmd.Process.Kill() + }) + defer timer.Stop() + return cmd.Wait() +} + // raceDetectorSupported is a copy of the function // cmd/internal/sys.RaceDetectorSupported, which can't be used here // because cmd/dist has to be buildable by Go 1.4. From 3e9d8e2e1bb94c3e302da8121f9cc018d86d1e71 Mon Sep 17 00:00:00 2001 From: LE Manh Cuong Date: Fri, 17 May 2019 17:25:07 +0700 Subject: [PATCH 41/50] test/fixedbugs: fix some tests will not be run Currently, some tests under test/fixedbugs never run: $ for d in test/fixedbugs/*.dir; do ! test -f "${d%.dir}.go" && echo "$d" done test/fixedbugs/issue15071.dir test/fixedbugs/issue15609.dir test/fixedbugs/issue29612.dir Because they missed the corresponding ".go" file, so "go run run.go" will skip them. Add missing ".go" files for those tests to make sure they will be collected and run. While at it, add another action "runindir", which does "go run ." inside the t.goDirName then check the output. Change-Id: I88000b3663a6a615d90c1cf11844ea0377403e3d Reviewed-on: https://go-review.googlesource.com/c/go/+/177798 Run-TryBot: Ian Lance Taylor TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- .../fixedbugs/issue15071.dir/{exp => }/exp.go | 0 test/fixedbugs/issue15071.go | 7 +++++ test/fixedbugs/issue15609.go | 7 +++++ test/fixedbugs/issue29612.go | 7 +++++ test/run.go | 31 +++++++++++++++++-- 5 files changed, 49 insertions(+), 3 deletions(-) rename test/fixedbugs/issue15071.dir/{exp => }/exp.go (100%) create mode 100644 test/fixedbugs/issue15071.go create mode 100644 test/fixedbugs/issue15609.go create mode 100644 test/fixedbugs/issue29612.go diff --git a/test/fixedbugs/issue15071.dir/exp/exp.go b/test/fixedbugs/issue15071.dir/exp.go similarity index 100% rename from test/fixedbugs/issue15071.dir/exp/exp.go rename to test/fixedbugs/issue15071.dir/exp.go diff --git a/test/fixedbugs/issue15071.go b/test/fixedbugs/issue15071.go new file mode 100644 index 0000000000..af6f134172 --- /dev/null +++ b/test/fixedbugs/issue15071.go @@ -0,0 +1,7 @@ +// rundir + +// Copyright 2019 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 ignored diff --git a/test/fixedbugs/issue15609.go b/test/fixedbugs/issue15609.go new file mode 100644 index 0000000000..87c96b480f --- /dev/null +++ b/test/fixedbugs/issue15609.go @@ -0,0 +1,7 @@ +// runindir + +// Copyright 2019 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 ignored diff --git a/test/fixedbugs/issue29612.go b/test/fixedbugs/issue29612.go new file mode 100644 index 0000000000..87c96b480f --- /dev/null +++ b/test/fixedbugs/issue29612.go @@ -0,0 +1,7 @@ +// runindir + +// Copyright 2019 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 ignored diff --git a/test/run.go b/test/run.go index 84f5cd991c..28ed865c50 100644 --- a/test/run.go +++ b/test/run.go @@ -522,7 +522,7 @@ func (t *test) run() { // TODO: Clean up/simplify this switch statement. switch action { - case "compile", "compiledir", "build", "builddir", "buildrundir", "run", "buildrun", "runoutput", "rundir", "asmcheck": + case "compile", "compiledir", "build", "builddir", "buildrundir", "run", "buildrun", "runoutput", "rundir", "runindir", "asmcheck": // nothing to do case "errorcheckandrundir": wantError = false // should be no error if also will run @@ -603,16 +603,19 @@ func (t *test) run() { } useTmp := true + runInDir := false runcmd := func(args ...string) ([]byte, error) { cmd := exec.Command(args[0], args[1:]...) var buf bytes.Buffer cmd.Stdout = &buf cmd.Stderr = &buf + cmd.Env = os.Environ() if useTmp { cmd.Dir = t.tempDir cmd.Env = envForDir(cmd.Dir) - } else { - cmd.Env = os.Environ() + } + if runInDir { + cmd.Dir = t.goDirName() } var err error @@ -834,6 +837,28 @@ func (t *test) run() { } } + case "runindir": + // run "go run ." in t.goDirName() + // It's used when test requires go build and run the binary success. + // Example when long import path require (see issue29612.dir) or test + // contains assembly file (see issue15609.dir). + // Verify the expected output. + useTmp = false + runInDir = true + cmd := []string{goTool(), "run", goGcflags()} + if *linkshared { + cmd = append(cmd, "-linkshared") + } + cmd = append(cmd, ".") + out, err := runcmd(cmd...) + if err != nil { + t.err = err + return + } + if strings.Replace(string(out), "\r\n", "\n", -1) != t.expectedOutput() { + t.err = fmt.Errorf("incorrect output\n%s", out) + } + case "build": // Build Go file. _, err := runcmd(goTool(), "build", goGcflags(), "-o", "a.exe", long) From 6f51082da77a1d4cafd5b7af0db69293943f4066 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20M=C3=B6hrmann?= Date: Wed, 22 May 2019 14:27:47 +0200 Subject: [PATCH 42/50] fmt: always clear wrapErrs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Like panicking and erroring - wrapErrs should always be reset to the default false. wrapErrs should only be true when set by Errorf. Change-Id: I4d51cc2f0905109e232b0983dc5331bd34f138bc Reviewed-on: https://go-review.googlesource.com/c/go/+/178517 Run-TryBot: Martin Möhrmann TryBot-Result: Gobot Gobot Reviewed-by: Damien Neil --- src/fmt/print.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fmt/print.go b/src/fmt/print.go index 3253e8042e..595869140a 100644 --- a/src/fmt/print.go +++ b/src/fmt/print.go @@ -122,7 +122,7 @@ type pp struct { panicking bool // erroring is set when printing an error string to guard against calling handleMethods. erroring bool - // wrapErrors is set when the format string may contain a %w verb. + // wrapErrs is set when the format string may contain a %w verb. wrapErrs bool // wrappedErr records the target of the %w verb. wrappedErr error @@ -137,6 +137,7 @@ func newPrinter() *pp { p := ppFree.Get().(*pp) p.panicking = false p.erroring = false + p.wrapErrs = false p.fmt.init(&p.buf) return p } From e2970a4591084d25c8bbd3e0648f8228f9defa2e Mon Sep 17 00:00:00 2001 From: Ariel Mashraki Date: Sun, 10 Feb 2019 22:44:03 +0200 Subject: [PATCH 43/50] text/template: add a slice function to the predefined global functions The new slice function returns the result of slicing its first argument by the following arguments. Thus {{slice x 1 3}} is, in Go syntax, x[1:3]. Each sliced item must be a string, slice, or array. Closed #30153 RELNOTE=yes Change-Id: I63188c422848cee3d383a64dc4d046e3a1767c63 Reviewed-on: https://go-review.googlesource.com/c/go/+/161762 Reviewed-by: Rob Pike --- src/text/template/doc.go | 5 ++ src/text/template/exec_test.go | 33 +++++++++++- src/text/template/funcs.go | 93 ++++++++++++++++++++++++++++------ 3 files changed, 114 insertions(+), 17 deletions(-) diff --git a/src/text/template/doc.go b/src/text/template/doc.go index 0179dec5c3..dbffaa4958 100644 --- a/src/text/template/doc.go +++ b/src/text/template/doc.go @@ -328,6 +328,11 @@ Predefined global functions are named as follows. Returns the result of indexing its first argument by the following arguments. Thus "index x 1 2 3" is, in Go syntax, x[1][2][3]. Each indexed item must be a map, slice, or array. + slice + slice returns the result of slicing its first argument by the + remaining arguments. Thus "slice x 1 2" is, in Go syntax, x[1:2], + while "slice x" is x[:], "slice x 1" is x[1:], and "slice x 1 2 3" + is x[1:2:3]. The first argument must be a string, slice, or array. js Returns the escaped JavaScript equivalent of the textual representation of its arguments. diff --git a/src/text/template/exec_test.go b/src/text/template/exec_test.go index 63ccd5c3c0..81f9e04476 100644 --- a/src/text/template/exec_test.go +++ b/src/text/template/exec_test.go @@ -23,7 +23,7 @@ type T struct { True bool I int U16 uint16 - X string + X, S string FloatZero float64 ComplexZero complex128 // Nested structs. @@ -36,8 +36,11 @@ type T struct { W1, W2 *W // Slices SI []int + SICap []int SIEmpty []int SB []bool + // Arrays + AI [3]int // Maps MSI map[string]int MSIone map[string]int // one element, for deterministic output @@ -122,12 +125,15 @@ var tVal = &T{ I: 17, U16: 16, X: "x", + S: "xyz", U: &U{"v"}, V0: V{6666}, V1: &V{7777}, // leave V2 as nil W0: W{888}, W1: &W{999}, // leave W2 as nil SI: []int{3, 4, 5}, + SICap: make([]int, 5, 10), + AI: [3]int{3, 4, 5}, SB: []bool{true, false}, MSI: map[string]int{"one": 1, "two": 2, "three": 3}, MSIone: map[string]int{"one": 1}, @@ -491,6 +497,31 @@ var execTests = []execTest{ {"map MI8S", "{{index .MI8S 3}}", "i83", tVal, true}, {"map MUI8S", "{{index .MUI8S 2}}", "u82", tVal, true}, + // Slicing. + {"slice[:]", "{{slice .SI}}", "[3 4 5]", tVal, true}, + {"slice[1:]", "{{slice .SI 1}}", "[4 5]", tVal, true}, + {"slice[1:2]", "{{slice .SI 1 2}}", "[4]", tVal, true}, + {"slice[-1:]", "{{slice .SI -1}}", "", tVal, false}, + {"slice[1:-2]", "{{slice .SI 1 -2}}", "", tVal, false}, + {"slice[1:2:-1]", "{{slice .SI 1 2 -1}}", "", tVal, false}, + {"slice[2:1]", "{{slice .SI 2 1}}", "", tVal, false}, + {"slice[2:2:1]", "{{slice .SI 2 2 1}}", "", tVal, false}, + {"out of range", "{{slice .SI 4 5}}", "", tVal, false}, + {"out of range", "{{slice .SI 2 2 5}}", "", tVal, false}, + {"len(s) < indexes < cap(s)", "{{slice .SICap 6 10}}", "[0 0 0 0]", tVal, true}, + {"len(s) < indexes < cap(s)", "{{slice .SICap 6 10 10}}", "[0 0 0 0]", tVal, true}, + {"indexes > cap(s)", "{{slice .SICap 10 11}}", "", tVal, false}, + {"indexes > cap(s)", "{{slice .SICap 6 10 11}}", "", tVal, false}, + {"array[:]", "{{slice .AI}}", "[3 4 5]", tVal, true}, + {"array[1:]", "{{slice .AI 1}}", "[4 5]", tVal, true}, + {"array[1:2]", "{{slice .AI 1 2}}", "[4]", tVal, true}, + {"string[:]", "{{slice .S}}", "xyz", tVal, true}, + {"string[0:1]", "{{slice .S 0 1}}", "x", tVal, true}, + {"string[1:]", "{{slice .S 1}}", "yz", tVal, true}, + {"string[1:2]", "{{slice .S 1 2}}", "y", tVal, true}, + {"out of range", "{{slice .S 1 5}}", "", tVal, false}, + {"3-index slice of string", "{{slice .S 1 2 2}}", "", tVal, false}, + // Len. {"slice", "{{len .SI}}", "3", tVal, true}, {"map", "{{len .MSI }}", "3", tVal, true}, diff --git a/src/text/template/funcs.go b/src/text/template/funcs.go index a626247c2c..248dbcf22e 100644 --- a/src/text/template/funcs.go +++ b/src/text/template/funcs.go @@ -34,6 +34,7 @@ var builtins = FuncMap{ "call": call, "html": HTMLEscaper, "index": index, + "slice": slice, "js": JSEscaper, "len": length, "not": not, @@ -159,17 +160,36 @@ func intLike(typ reflect.Kind) bool { return false } +// indexArg checks if a reflect.Value can be used as an index, and converts it to int if possible. +func indexArg(index reflect.Value, cap int) (int, error) { + var x int64 + switch index.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + x = index.Int() + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + x = int64(index.Uint()) + case reflect.Invalid: + return 0, fmt.Errorf("cannot index slice/array with nil") + default: + return 0, fmt.Errorf("cannot index slice/array with type %s", index.Type()) + } + if x < 0 || int(x) < 0 || int(x) > cap { + return 0, fmt.Errorf("index out of range: %d", x) + } + return int(x), nil +} + // Indexing. // index returns the result of indexing its first argument by the following // arguments. Thus "index x 1 2 3" is, in Go syntax, x[1][2][3]. Each // indexed item must be a map, slice, or array. -func index(item reflect.Value, indices ...reflect.Value) (reflect.Value, error) { +func index(item reflect.Value, indexes ...reflect.Value) (reflect.Value, error) { v := indirectInterface(item) if !v.IsValid() { return reflect.Value{}, fmt.Errorf("index of untyped nil") } - for _, i := range indices { + for _, i := range indexes { index := indirectInterface(i) var isNil bool if v, isNil = indirect(v); isNil { @@ -177,21 +197,11 @@ func index(item reflect.Value, indices ...reflect.Value) (reflect.Value, error) } switch v.Kind() { case reflect.Array, reflect.Slice, reflect.String: - var x int64 - switch index.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - x = index.Int() - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - x = int64(index.Uint()) - case reflect.Invalid: - return reflect.Value{}, fmt.Errorf("cannot index slice/array with nil") - default: - return reflect.Value{}, fmt.Errorf("cannot index slice/array with type %s", index.Type()) + x, err := indexArg(index, v.Len()) + if err != nil { + return reflect.Value{}, err } - if x < 0 || x >= int64(v.Len()) { - return reflect.Value{}, fmt.Errorf("index out of range: %d", x) - } - v = v.Index(int(x)) + v = v.Index(x) case reflect.Map: index, err := prepareArg(index, v.Type().Key()) if err != nil { @@ -212,6 +222,57 @@ func index(item reflect.Value, indices ...reflect.Value) (reflect.Value, error) return v, nil } +// Slicing. + +// slice returns the result of slicing its first argument by the remaining +// arguments. Thus "slice x 1 2" is, in Go syntax, x[1:2], while "slice x" +// is x[:], "slice x 1" is x[1:], and "slice x 1 2 3" is x[1:2:3]. The first +// argument must be a string, slice, or array. +func slice(item reflect.Value, indexes ...reflect.Value) (reflect.Value, error) { + var ( + cap int + v = indirectInterface(item) + ) + if !v.IsValid() { + return reflect.Value{}, fmt.Errorf("slice of untyped nil") + } + if len(indexes) > 3 { + return reflect.Value{}, fmt.Errorf("too many slice indexes: %d", len(indexes)) + } + switch v.Kind() { + case reflect.String: + if len(indexes) == 3 { + return reflect.Value{}, fmt.Errorf("cannot 3-index slice a string") + } + cap = v.Len() + case reflect.Array, reflect.Slice: + cap = v.Cap() + default: + return reflect.Value{}, fmt.Errorf("can't slice item of type %s", v.Type()) + } + // set default values for cases item[:], item[i:]. + idx := [3]int{0, v.Len()} + for i, index := range indexes { + x, err := indexArg(index, cap) + if err != nil { + return reflect.Value{}, err + } + idx[i] = x + } + // given item[i:j], make sure i <= j. + if idx[0] > idx[1] { + return reflect.Value{}, fmt.Errorf("invalid slice index: %d > %d", idx[0], idx[1]) + } + if len(indexes) < 3 { + return item.Slice(idx[0], idx[1]), nil + } + // given item[i:j:k], make sure i <= j <= k. + if idx[1] > idx[2] { + return reflect.Value{}, fmt.Errorf("invalid slice index: %d > %d", idx[1], idx[2]) + } + return item.Slice3(idx[0], idx[1], idx[2]), nil +} + // Length // length returns the length of the item, with an error if it has no defined length. From 65ef999d52ebce2534e8006d7a6d5bb6871f3c24 Mon Sep 17 00:00:00 2001 From: Agniva De Sarker Date: Wed, 22 May 2019 10:05:04 +0200 Subject: [PATCH 44/50] cmd/doc: stop showing interface methods while matching symbols Fixes #31961 Change-Id: I9db9ecfd2f8ca7cf51df4413a6e0d66de5da7043 Reviewed-on: https://go-review.googlesource.com/c/go/+/178457 Run-TryBot: Agniva De Sarker TryBot-Result: Gobot Gobot Reviewed-by: Rob Pike --- src/cmd/doc/doc_test.go | 13 +++++++++++++ src/cmd/doc/pkg.go | 7 +++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/cmd/doc/doc_test.go b/src/cmd/doc/doc_test.go index 22468db1ff..bc870aca58 100644 --- a/src/cmd/doc/doc_test.go +++ b/src/cmd/doc/doc_test.go @@ -602,6 +602,19 @@ var tests = []test{ `Comment about exported interface`, }, }, + // Interface method at package level. + { + "interface method at package level", + []string{p, `ExportedMethod`}, + []string{ + `func \(ExportedType\) ExportedMethod\(a int\) bool`, + `Comment about exported method`, + }, + []string{ + `Comment before exported method.*\n.*ExportedMethod\(\)` + + `.*Comment on line with exported method`, + }, + }, // Method. { diff --git a/src/cmd/doc/pkg.go b/src/cmd/doc/pkg.go index 12b76c2ad0..32810bd581 100644 --- a/src/cmd/doc/pkg.go +++ b/src/cmd/doc/pkg.go @@ -914,8 +914,8 @@ func trimUnexportedFields(fields *ast.FieldList, isInterface bool) *ast.FieldLis } // printMethodDoc prints the docs for matches of symbol.method. -// If symbol is empty, it prints all methods that match the name. -// It reports whether it found any methods. +// If symbol is empty, it prints all methods for any concrete type +// that match the name. It reports whether it found any methods. func (pkg *Package) printMethodDoc(symbol, method string) bool { defer pkg.flush() types := pkg.findTypes(symbol) @@ -937,6 +937,9 @@ func (pkg *Package) printMethodDoc(symbol, method string) bool { } continue } + if symbol == "" { + continue + } // Type may be an interface. The go/doc package does not attach // an interface's methods to the doc.Type. We need to dig around. spec := pkg.findTypeSpec(typ.Decl, typ.Name) From 4fbb4e74aa3b9e83d812e494766cff41e57dd5a8 Mon Sep 17 00:00:00 2001 From: Mickey Reiss Date: Thu, 23 May 2019 05:15:49 +0000 Subject: [PATCH 45/50] bufio: Fix typo in scan.go documentation Apologies for the the nitpicky PR. I believe there is a minor typo in the documentation of `MaxScanTokenSize`, which confused me for a moment when I went to search for the referenced method, `Scan.Buffer`. Thanks! Change-Id: I5d21e77276285206497fe75291001032c255cace GitHub-Last-Rev: 635e35c0191c11f2b6966b5e58cf91a1064099da GitHub-Pull-Request: golang/go#32193 Reviewed-on: https://go-review.googlesource.com/c/go/+/178637 Reviewed-by: Brad Fitzpatrick --- src/bufio/scan.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bufio/scan.go b/src/bufio/scan.go index cefd261464..4e787c4b0a 100644 --- a/src/bufio/scan.go +++ b/src/bufio/scan.go @@ -73,7 +73,7 @@ var ( const ( // MaxScanTokenSize is the maximum size used to buffer a token - // unless the user provides an explicit buffer with Scan.Buffer. + // unless the user provides an explicit buffer with Scanner.Buffer. // The actual maximum token size may be smaller as the buffer // may need to include, for instance, a newline. MaxScanTokenSize = 64 * 1024 From f8a5ba2a3880f4782d8250fd26dde2baa3990afa Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 21 May 2019 09:03:26 -0400 Subject: [PATCH 46/50] cmd/go: default to GOPROXY=https://proxy.golang.org and GOSUMDB=sum.golang.org This CL changes the default module download and module verification mechanisms to use the Go module mirror and Go checksum database run by Google. See https://proxy.golang.org/privacy for the services' privacy policy. (Today, that URL is a redirect to Google's standard privacy policy, which covers these services as well. If we publish a more specific privacy policy just for these services, that URL will be updated to display or redirect to it.) See 'go help modules' and 'go help modules-auth' for details (added in this CL). To disable the mirror and checksum database for non-public modules: go env -w GONOPROXY=*.private.net,your.com/* go env -w GONOSUMDB=*.private.net,your.com/* (If you are using a private module proxy then you'd only do the second.) If you run into problems with the behavior of the go command when using the Go module mirror or the Go checksum database, please file issues at https://golang.org/issue/new, so that we can address them for the Go 1.13 release. For #25530. This CL also documents GONOPROXY. Fixes #32056. Change-Id: I2fde82e071742272b0842efd9580df1a56947fec Reviewed-on: https://go-review.googlesource.com/c/go/+/178179 Run-TryBot: Russ Cox TryBot-Result: Gobot Gobot Reviewed-by: Bryan C. Mills --- src/cmd/go/alldocs.go | 76 +++++++++++-------- src/cmd/go/internal/cfg/cfg.go | 14 ---- src/cmd/go/internal/modfetch/fetch.go | 18 +++-- src/cmd/go/internal/modfetch/proxy.go | 15 ---- src/cmd/go/internal/modload/help.go | 43 +++++++++-- .../go/testdata/script/mod_sumdb_golang.txt | 8 +- 6 files changed, 94 insertions(+), 80 deletions(-) diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go index 1a7eff29a2..26fb337f86 100644 --- a/src/cmd/go/alldocs.go +++ b/src/cmd/go/alldocs.go @@ -2020,21 +2020,6 @@ // // Module proxy protocol // -// The go command by default downloads modules from version control systems -// directly, just as 'go get' always has. The GOPROXY environment variable allows -// further control over the download source. If GOPROXY is unset, is the empty string, -// or is the string "direct", downloads use the default direct connection to version -// control systems. Setting GOPROXY to "off" disallows downloading modules from -// any source. Otherwise, GOPROXY is expected to be a comma-separated list of -// the URLs of module proxies, in which case the go command will fetch modules -// from those proxies. For each request, the go command tries each proxy in sequence, -// only moving to the next if the current proxy returns a 404 or 410 HTTP response. -// The string "direct" may appear in the proxy list, to cause a direct connection to -// be attempted at that point in the search. -// -// No matter the source of the modules, downloaded modules must match existing -// entries in go.sum (see 'go help modules' for discussion of verification). -// // A Go module proxy is any web server that can respond to GET requests for // URLs of a specified form. The requests have no query parameters, so even // a site serving from a fixed file system (including a file:/// URL) @@ -2591,16 +2576,43 @@ // // Module downloading and verification // -// The go command checks downloads against known checksums, -// to detect unexpected changes in the content of any specific module -// version from one day to the next. See 'go help module-auth' for details. +// The go command can fetch modules from a proxy or connect to source control +// servers directly, according to the setting of the GOPROXY environment +// variable (see 'go help env'). The default setting for GOPROXY is +// "https://proxy.golang.org", the Go module mirror run by Google. +// See https://proxy.golang.org/privacy for the service's privacy policy. +// If GOPROXY is set to the string "direct", downloads use a direct connection +// to source control servers. Setting GOPROXY to "off" disallows downloading +// modules from any source. Otherwise, GOPROXY is expected to be a comma-separated +// list of the URLs of module proxies, in which case the go command will fetch +// modules from those proxies. For each request, the go command tries each proxy +// in sequence, only moving to the next if the current proxy returns a 404 or 410 +// HTTP response. The string "direct" may appear in the proxy list, +// to cause a direct connection to be attempted at that point in the search. +// Any proxies listed after "direct" are never consulted. // -// The go command can fetch modules from a proxy instead of connecting -// to source control systems directly, according to the setting of the GOPROXY -// environment variable. +// The GONOPROXY environment variable is a comma-separated list of +// glob patterns (in the syntax of Go's path.Match) of module path prefixes +// that should always be fetched directly, ignoring the GOPROXY setting. +// For example, // -// See 'go help goproxy' for details about the proxy and also the format of -// the cached downloaded packages. +// GONOPROXY=*.corp.example.com,rsc.io/private +// +// forces a direct connection to download modules with path prefixes matching +// either pattern, including "git.corp.example.com/xyzzy", "rsc.io/private", +// and "rsc.io/private/quux". +// +// The 'go env -w' command (see 'go help env') can be used to set these variables +// for future go command invocations. +// +// No matter the source of the modules, the go command checks downloads against +// known checksums, to detect unexpected changes in the content of any specific +// module version from one day to the next. This check first consults the current +// module's go.sum file but falls back to the Go checksum database. +// See 'go help module-auth' for details. +// +// See 'go help goproxy' for details about the proxy protocol and also +// the format of the cached downloaded packages. // // Modules and vendoring // @@ -2778,18 +2790,17 @@ // database requires giving the public key explicitly. The URL defaults to // "https://" followed by the database name. // -// GOSUMDB defaults to "sum.golang.org" when GOPROXY="https://proxy.golang.org" -// and otherwise defaults to "off". NOTE: The GOSUMDB will later default to -// "sum.golang.org" unconditionally. +// GOSUMDB defaults to "sum.golang.org", the Go checksum database run by Google. +// See https://sum.golang.org/privacy for the service's privacy policy. // // If GOSUMDB is set to "off", or if "go get" is invoked with the -insecure flag, -// the checksum database is never consulted, but at the cost of giving up the -// security guarantee of verified repeatable downloads for all modules. -// A better way to bypass the checksum database for specific modules is -// to use the GONOSUMDB environment variable. +// the checksum database is not consulted, and all unrecognized modules are +// accepted, at the cost of giving up the security guarantee of verified repeatable +// downloads for all modules. A better way to bypass the checksum database +// for specific modules is to use the GONOSUMDB environment variable. // // The GONOSUMDB environment variable is a comma-separated list of -// patterns (in the syntax of Go's path.Match) of module path prefixes +// glob patterns (in the syntax of Go's path.Match) of module path prefixes // that should not be compared against the checksum database. // For example, // @@ -2799,6 +2810,9 @@ // either pattern, including "git.corp.example.com/xyzzy", "rsc.io/private", // and "rsc.io/private/quux". // +// The 'go env -w' command (see 'go help env') can be used to set these variables +// for future go command invocations. +// // // Testing flags // diff --git a/src/cmd/go/internal/cfg/cfg.go b/src/cmd/go/internal/cfg/cfg.go index 2d17d104a6..77d8bab14f 100644 --- a/src/cmd/go/internal/cfg/cfg.go +++ b/src/cmd/go/internal/cfg/cfg.go @@ -303,13 +303,6 @@ func goproxy() string { return v } - // Proxy is off by default for now. - // TODO(rsc): Remove this condition, turning it on always. - // (But do NOT do this without approval from rsc.) - if true { - return "direct" - } - return "https://proxy.golang.org" } @@ -319,13 +312,6 @@ func gosumdb() string { return v } - // Checksum database is off by default except when GOPROXY is proxy.golang.org. - // TODO(rsc): Remove this condition, turning it on always. - // (But do NOT do this without approval from rsc.) - if !strings.HasPrefix(GOPROXY, "https://proxy.golang.org") { - return "off" - } - return "sum.golang.org" } diff --git a/src/cmd/go/internal/modfetch/fetch.go b/src/cmd/go/internal/modfetch/fetch.go index 817f7657e2..d40d2c6fac 100644 --- a/src/cmd/go/internal/modfetch/fetch.go +++ b/src/cmd/go/internal/modfetch/fetch.go @@ -702,18 +702,17 @@ The go command knows the public key of sum.golang.org; use of any other database requires giving the public key explicitly. The URL defaults to "https://" followed by the database name. -GOSUMDB defaults to "sum.golang.org" when GOPROXY="https://proxy.golang.org" -and otherwise defaults to "off". NOTE: The GOSUMDB will later default to -"sum.golang.org" unconditionally. +GOSUMDB defaults to "sum.golang.org", the Go checksum database run by Google. +See https://sum.golang.org/privacy for the service's privacy policy. If GOSUMDB is set to "off", or if "go get" is invoked with the -insecure flag, -the checksum database is never consulted, but at the cost of giving up the -security guarantee of verified repeatable downloads for all modules. -A better way to bypass the checksum database for specific modules is -to use the GONOSUMDB environment variable. +the checksum database is not consulted, and all unrecognized modules are +accepted, at the cost of giving up the security guarantee of verified repeatable +downloads for all modules. A better way to bypass the checksum database +for specific modules is to use the GONOSUMDB environment variable. The GONOSUMDB environment variable is a comma-separated list of -patterns (in the syntax of Go's path.Match) of module path prefixes +glob patterns (in the syntax of Go's path.Match) of module path prefixes that should not be compared against the checksum database. For example, @@ -722,5 +721,8 @@ For example, disables checksum database lookups for modules with path prefixes matching either pattern, including "git.corp.example.com/xyzzy", "rsc.io/private", and "rsc.io/private/quux". + +The 'go env -w' command (see 'go help env') can be used to set these variables +for future go command invocations. `, } diff --git a/src/cmd/go/internal/modfetch/proxy.go b/src/cmd/go/internal/modfetch/proxy.go index 605c72c0ab..5f0432ceed 100644 --- a/src/cmd/go/internal/modfetch/proxy.go +++ b/src/cmd/go/internal/modfetch/proxy.go @@ -32,21 +32,6 @@ var HelpGoproxy = &base.Command{ UsageLine: "goproxy", Short: "module proxy protocol", Long: ` -The go command by default downloads modules from version control systems -directly, just as 'go get' always has. The GOPROXY environment variable allows -further control over the download source. If GOPROXY is unset, is the empty string, -or is the string "direct", downloads use the default direct connection to version -control systems. Setting GOPROXY to "off" disallows downloading modules from -any source. Otherwise, GOPROXY is expected to be a comma-separated list of -the URLs of module proxies, in which case the go command will fetch modules -from those proxies. For each request, the go command tries each proxy in sequence, -only moving to the next if the current proxy returns a 404 or 410 HTTP response. -The string "direct" may appear in the proxy list, to cause a direct connection to -be attempted at that point in the search. - -No matter the source of the modules, downloaded modules must match existing -entries in go.sum (see 'go help modules' for discussion of verification). - A Go module proxy is any web server that can respond to GET requests for URLs of a specified form. The requests have no query parameters, so even a site serving from a fixed file system (including a file:/// URL) diff --git a/src/cmd/go/internal/modload/help.go b/src/cmd/go/internal/modload/help.go index c1685ff08e..96fec8451e 100644 --- a/src/cmd/go/internal/modload/help.go +++ b/src/cmd/go/internal/modload/help.go @@ -328,16 +328,43 @@ module file trees. Module downloading and verification -The go command checks downloads against known checksums, -to detect unexpected changes in the content of any specific module -version from one day to the next. See 'go help module-auth' for details. +The go command can fetch modules from a proxy or connect to source control +servers directly, according to the setting of the GOPROXY environment +variable (see 'go help env'). The default setting for GOPROXY is +"https://proxy.golang.org", the Go module mirror run by Google. +See https://proxy.golang.org/privacy for the service's privacy policy. +If GOPROXY is set to the string "direct", downloads use a direct connection +to source control servers. Setting GOPROXY to "off" disallows downloading +modules from any source. Otherwise, GOPROXY is expected to be a comma-separated +list of the URLs of module proxies, in which case the go command will fetch +modules from those proxies. For each request, the go command tries each proxy +in sequence, only moving to the next if the current proxy returns a 404 or 410 +HTTP response. The string "direct" may appear in the proxy list, +to cause a direct connection to be attempted at that point in the search. +Any proxies listed after "direct" are never consulted. -The go command can fetch modules from a proxy instead of connecting -to source control systems directly, according to the setting of the GOPROXY -environment variable. +The GONOPROXY environment variable is a comma-separated list of +glob patterns (in the syntax of Go's path.Match) of module path prefixes +that should always be fetched directly, ignoring the GOPROXY setting. +For example, -See 'go help goproxy' for details about the proxy and also the format of -the cached downloaded packages. + GONOPROXY=*.corp.example.com,rsc.io/private + +forces a direct connection to download modules with path prefixes matching +either pattern, including "git.corp.example.com/xyzzy", "rsc.io/private", +and "rsc.io/private/quux". + +The 'go env -w' command (see 'go help env') can be used to set these variables +for future go command invocations. + +No matter the source of the modules, the go command checks downloads against +known checksums, to detect unexpected changes in the content of any specific +module version from one day to the next. This check first consults the current +module's go.sum file but falls back to the Go checksum database. +See 'go help module-auth' for details. + +See 'go help goproxy' for details about the proxy protocol and also +the format of the cached downloaded packages. Modules and vendoring diff --git a/src/cmd/go/testdata/script/mod_sumdb_golang.txt b/src/cmd/go/testdata/script/mod_sumdb_golang.txt index ca040c5dcf..0eb0fc84a7 100644 --- a/src/cmd/go/testdata/script/mod_sumdb_golang.txt +++ b/src/cmd/go/testdata/script/mod_sumdb_golang.txt @@ -1,16 +1,16 @@ -[!net] skip - +# Test default GOPROXY and GOSUMDB env GOPROXY= env GOSUMDB= go env GOPROXY -stdout '^direct$' +stdout '^https://proxy.golang.org$' go env GOSUMDB -stdout '^off$' +stdout '^sum.golang.org$' env GOPROXY=https://proxy.golang.org go env GOSUMDB stdout '^sum.golang.org$' # download direct from github +[!net] skip env GOSUMDB=sum.golang.org env GOPROXY=direct go get -m rsc.io/quote From 05092163bb48004fbad847b04c1b0545e3f0189f Mon Sep 17 00:00:00 2001 From: Caleb Spare Date: Sat, 12 Jan 2019 14:29:08 -0800 Subject: [PATCH 47/50] strconv: fix rounding in FormatFloat fallback path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Float formatting uses a multiprecision fallback path where Grisu3 algorithm fails. This has a bug during the rounding phase: the difference between the decimal value and the upper bound is examined byte-by-byte and doesn't properly handle the case where the first divergence has a difference of 1. For instance (using an example from #29491), for the number 498484681984085570, roundShortest examines the three decimal values: lower: 498484681984085536 d: 498484681984085568 upper: 498484681984085600 After examining the 16th digit, we know that rounding d up will fall within the bounds unless all remaining digits of d are 9 and all remaining digits of upper are 0: d: ...855xx upper: ...856xx However, the loop forgets that d and upper have already diverged and then on the next iteration sees that the 17th digit of d is actually lower than the 17th digit of upper and decides that we still can't round up: d: ...8556x upper: ...8560x Thus the original value is incorrectly rounded down to 498484681984085560 instead of the closer (and equally short) 498484681984085570. Thanks to Brian Kessler for diagnosing this bug. Fix it by remembering when we've seen divergence in previous digits. This CL also fixes another bug in the same loop: for some inputs, the decimal value d or the lower bound may have fewer digits than the upper bound, yet the iteration through the digits starts at i=0 for each of them. For instance, given the float64 value 1e23, we have d: 99999999999999991611392 upper: 100000000000000000000000 but the loop starts by comparing '9' to '1' rather than '0' to '1'. I haven't found any cases where this second bug causes incorrect output because when the digit comparison fails on the first loop iteration the upper bound always has more nonzero digits (i.e., the expression 'i+1 < upper.nd' is always true). Fixes #29491 Change-Id: I58856a7a2e47935ec2f233d9f717ef15c78bb2d0 Reviewed-on: https://go-review.googlesource.com/c/go/+/157697 Run-TryBot: Caleb Spare TryBot-Result: Gobot Gobot Reviewed-by: Rémy Oudompheng Reviewed-by: Brad Fitzpatrick --- src/strconv/ftoa.go | 65 ++++++++++++++++++++++++++++++++-------- src/strconv/ftoa_test.go | 4 +++ 2 files changed, 57 insertions(+), 12 deletions(-) diff --git a/src/strconv/ftoa.go b/src/strconv/ftoa.go index 432521b24f..8ce6ef30b4 100644 --- a/src/strconv/ftoa.go +++ b/src/strconv/ftoa.go @@ -289,39 +289,80 @@ func roundShortest(d *decimal, mant uint64, exp int, flt *floatInfo) { // would round to the original mantissa and not the neighbors. inclusive := mant%2 == 0 + // As we walk the digits we want to know whether rounding up would fall + // within the upper bound. This is tracked by upperdelta: + // + // If upperdelta == 0, the digits of d and upper are the same so far. + // + // If upperdelta == 1, we saw a difference of 1 between d and upper on a + // previous digit and subsequently only 9s for d and 0s for upper. + // (Thus rounding up may fall outside the bound, if it is exclusive.) + // + // If upperdelta == 2, then the difference is greater than 1 + // and we know that rounding up falls within the bound. + var upperdelta uint8 + // Now we can figure out the minimum number of digits required. // Walk along until d has distinguished itself from upper and lower. - for i := 0; i < d.nd; i++ { - l := byte('0') // lower digit - if i < lower.nd { - l = lower.d[i] + for ui := 0; ; ui++ { + // lower, d, and upper may have the decimal points at different + // places. In this case upper is the longest, so we iterate from + // ui==0 and start li and mi at (possibly) -1. + mi := ui - upper.dp + d.dp + if mi >= d.nd { + break + } + li := ui - upper.dp + lower.dp + l := byte('0') // lower digit + if li >= 0 && li < lower.nd { + l = lower.d[li] + } + m := byte('0') // middle digit + if mi >= 0 { + m = d.d[mi] } - m := d.d[i] // middle digit u := byte('0') // upper digit - if i < upper.nd { - u = upper.d[i] + if ui < upper.nd { + u = upper.d[ui] } // Okay to round down (truncate) if lower has a different digit // or if lower is inclusive and is exactly the result of rounding // down (i.e., and we have reached the final digit of lower). - okdown := l != m || inclusive && i+1 == lower.nd + okdown := l != m || inclusive && li+1 == lower.nd + switch { + case upperdelta == 0 && m+1 < u: + // Example: + // m = 12345xxx + // u = 12347xxx + upperdelta = 2 + case upperdelta == 0 && m != u: + // Example: + // m = 12345xxx + // u = 12346xxx + upperdelta = 1 + case upperdelta == 1 && (m != '9' || u != '0'): + // Example: + // m = 1234598x + // u = 1234600x + upperdelta = 2 + } // Okay to round up if upper has a different digit and either upper // is inclusive or upper is bigger than the result of rounding up. - okup := m != u && (inclusive || m+1 < u || i+1 < upper.nd) + okup := upperdelta > 0 && (inclusive || upperdelta > 1 || ui+1 < upper.nd) // If it's okay to do either, then round to the nearest one. // If it's okay to do only one, do it. switch { case okdown && okup: - d.Round(i + 1) + d.Round(mi + 1) return case okdown: - d.RoundDown(i + 1) + d.RoundDown(mi + 1) return case okup: - d.RoundUp(i + 1) + d.RoundUp(mi + 1) return } } diff --git a/src/strconv/ftoa_test.go b/src/strconv/ftoa_test.go index 055fef99aa..755c986b86 100644 --- a/src/strconv/ftoa_test.go +++ b/src/strconv/ftoa_test.go @@ -137,6 +137,10 @@ var ftoatests = []ftoaTest{ {383260575764816448, 'f', 0, "383260575764816448"}, {383260575764816448, 'g', -1, "3.8326057576481645e+17"}, + // Issue 29491. + {498484681984085570, 'f', -1, "498484681984085570"}, + {-5.8339553793802237e+23, 'g', -1, "-5.8339553793802237e+23"}, + // rounding {2.275555555555555, 'x', -1, "0x1.23456789abcdep+01"}, {2.275555555555555, 'x', 0, "0x1p+01"}, From 0ac4ea79f725a0cc3797faa32ab698b8b3d77343 Mon Sep 17 00:00:00 2001 From: andrius4669 Date: Thu, 23 May 2019 15:43:51 +0000 Subject: [PATCH 48/50] mime: encode CTL and non-US-ASCII characters in FormatMediaType Encodes non-WSP CTL and non-US-ASCII UTF-8 characters using syntax specified in RFC 2231. Fixes #7668 Fixes #9624 Change-Id: I433f167c5bdd84a7f811ac0410b08b10790e0d9f GitHub-Last-Rev: 9c77146760341fdb3af35c1b94d4ee00ffb0daae GitHub-Pull-Request: golang/go#29328 Reviewed-on: https://go-review.googlesource.com/c/go/+/154760 Reviewed-by: Brad Fitzpatrick --- src/mime/mediatype.go | 36 ++++++++++++++++++++++++++++++++---- src/mime/mediatype_test.go | 25 ++++++++++++++++++++++--- 2 files changed, 54 insertions(+), 7 deletions(-) diff --git a/src/mime/mediatype.go b/src/mime/mediatype.go index 05390773a8..56ceb48853 100644 --- a/src/mime/mediatype.go +++ b/src/mime/mediatype.go @@ -19,7 +19,7 @@ import ( // FormatMediaType returns the empty string. func FormatMediaType(t string, param map[string]string) string { var b strings.Builder - if slash := strings.Index(t, "/"); slash == -1 { + if slash := strings.IndexByte(t, '/'); slash == -1 { if !isToken(t) { return "" } @@ -48,7 +48,38 @@ func FormatMediaType(t string, param map[string]string) string { return "" } b.WriteString(strings.ToLower(attribute)) + + needEnc := needsEncoding(value) + if needEnc { + // RFC 2231 section 4 + b.WriteByte('*') + } b.WriteByte('=') + + if needEnc { + b.WriteString("utf-8''") + + offset := 0 + for index := 0; index < len(value); index++ { + ch := value[index] + // {RFC 2231 section 7} + // attribute-char := + if ch <= ' ' || ch >= 0x7F || + ch == '*' || ch == '\'' || ch == '%' || + isTSpecial(rune(ch)) { + + b.WriteString(value[offset:index]) + offset = index + 1 + + b.WriteByte('%') + b.WriteByte(upperhex[ch>>4]) + b.WriteByte(upperhex[ch&0x0F]) + } + } + b.WriteString(value[offset:]) + continue + } + if isToken(value) { b.WriteString(value) continue @@ -63,9 +94,6 @@ func FormatMediaType(t string, param map[string]string) string { offset = index b.WriteByte('\\') } - if character&0x80 != 0 { - return "" - } } b.WriteString(value[offset:]) b.WriteByte('"') diff --git a/src/mime/mediatype_test.go b/src/mime/mediatype_test.go index 945a8189e1..e91ff38d68 100644 --- a/src/mime/mediatype_test.go +++ b/src/mime/mediatype_test.go @@ -6,6 +6,7 @@ package mime import ( "reflect" + "strings" "testing" ) @@ -481,8 +482,9 @@ var formatTests = []formatTest{ {"noslash", map[string]string{"X": "Y"}, "noslash; x=Y"}, // e.g. Content-Disposition values (RFC 2183); issue 11289 {"foo bar/baz", nil, ""}, {"foo/bar baz", nil, ""}, - {"attachment", map[string]string{"filename": "ĄĄŽŽČČŠŠ"}, ""}, - {"attachment", map[string]string{"filename": "ÁÁÊÊÇÇÎÎ"}, ""}, + {"attachment", map[string]string{"filename": "ĄĄŽŽČČŠŠ"}, "attachment; filename*=utf-8''%C4%84%C4%84%C5%BD%C5%BD%C4%8C%C4%8C%C5%A0%C5%A0"}, + {"attachment", map[string]string{"filename": "ÁÁÊÊÇÇÎÎ"}, "attachment; filename*=utf-8''%C3%81%C3%81%C3%8A%C3%8A%C3%87%C3%87%C3%8E%C3%8E"}, + {"attachment", map[string]string{"filename": "数据统计.png"}, "attachment; filename*=utf-8''%E6%95%B0%E6%8D%AE%E7%BB%9F%E8%AE%A1.png"}, {"foo/BAR", nil, "foo/bar"}, {"foo/BAR", map[string]string{"X": "Y"}, "foo/bar; x=Y"}, {"foo/BAR", map[string]string{"space": "With space"}, `foo/bar; space="With space"`}, @@ -491,7 +493,8 @@ var formatTests = []formatTest{ {"foo/BAR", map[string]string{"both": `With \backslash and "quote`}, `foo/bar; both="With \\backslash and \"quote"`}, {"foo/BAR", map[string]string{"": "empty attribute"}, ""}, {"foo/BAR", map[string]string{"bad attribute": "baz"}, ""}, - {"foo/BAR", map[string]string{"nonascii": "not an ascii character: ä"}, ""}, + {"foo/BAR", map[string]string{"nonascii": "not an ascii character: ä"}, "foo/bar; nonascii*=utf-8''not%20an%20ascii%20character%3A%20%C3%A4"}, + {"foo/BAR", map[string]string{"ctl": "newline: \n nil: \000"}, "foo/bar; ctl*=utf-8''newline%3A%20%0A%20nil%3A%20%00"}, {"foo/bar", map[string]string{"a": "av", "b": "bv", "c": "cv"}, "foo/bar; a=av; b=bv; c=cv"}, {"foo/bar", map[string]string{"0": "'", "9": "'"}, "foo/bar; 0='; 9='"}, {"foo", map[string]string{"bar": ""}, `foo; bar=""`}, @@ -503,5 +506,21 @@ func TestFormatMediaType(t *testing.T) { if got != tt.want { t.Errorf("%d. FormatMediaType(%q, %v) = %q; want %q", i, tt.typ, tt.params, got, tt.want) } + if got == "" { + continue + } + typ, params, err := ParseMediaType(got) + if err != nil { + t.Errorf("%d. ParseMediaType(%q) err: %v", i, got, err) + } + if typ != strings.ToLower(tt.typ) { + t.Errorf("%d. ParseMediaType(%q) typ = %q; want %q", i, got, typ, tt.typ) + } + for k, v := range tt.params { + k = strings.ToLower(k) + if params[k] != v { + t.Errorf("%d. ParseMediaType(%q) params[%s] = %q; want %q", i, got, k, params[k], v) + } + } } } From 2500ac20c0cfc38e84d9ac75771c881952ed8070 Mon Sep 17 00:00:00 2001 From: Leon Klingele Date: Wed, 30 Jan 2019 17:36:33 +0000 Subject: [PATCH 49/50] image: add missing error check in test Change-Id: Ia42a4a658e4207cc1f036f2faeac011e71edad77 GitHub-Last-Rev: b384f81799fcd404f53647d8a3015487ea240c6f GitHub-Pull-Request: golang/go#30012 Reviewed-on: https://go-review.googlesource.com/c/go/+/160436 Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- src/image/decode_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/image/decode_test.go b/src/image/decode_test.go index 85e235e729..2b3ff6ba58 100644 --- a/src/image/decode_test.go +++ b/src/image/decode_test.go @@ -123,6 +123,10 @@ loop: continue } c, _, err := decodeConfig(it.filename) + if err != nil { + t.Errorf("%s: %v", it.filename, err) + continue loop + } if m.ColorModel() != c.ColorModel { t.Errorf("%s: color models differ", it.filename) continue loop From 3ce865d7a0b88714cc433454ae2370a105210c01 Mon Sep 17 00:00:00 2001 From: Michael McLoughlin Date: Wed, 2 Jan 2019 18:47:33 -0800 Subject: [PATCH 50/50] crypto/sha*: replace putUint{32,64} helpers Replaces putUint{32,64} functions in crypto/sha* packages with the equivalent functions encoding/binary.BigEndian.PutUint{32,64}. Change-Id: I9208d2125202ea9c97777560e6917d21893aced0 Reviewed-on: https://go-review.googlesource.com/c/go/+/156117 Reviewed-by: Brad Fitzpatrick Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot --- src/crypto/sha1/sha1.go | 37 ++++++++----------------------- src/crypto/sha256/sha256.go | 43 +++++++++++-------------------------- src/crypto/sha512/sha512.go | 35 +++++++++++------------------- 3 files changed, 33 insertions(+), 82 deletions(-) diff --git a/src/crypto/sha1/sha1.go b/src/crypto/sha1/sha1.go index 8c48042b1c..286a59d33d 100644 --- a/src/crypto/sha1/sha1.go +++ b/src/crypto/sha1/sha1.go @@ -10,6 +10,7 @@ package sha1 import ( "crypto" + "encoding/binary" "errors" "hash" ) @@ -81,13 +82,13 @@ func (d *digest) UnmarshalBinary(b []byte) error { func appendUint64(b []byte, x uint64) []byte { var a [8]byte - putUint64(a[:], x) + binary.BigEndian.PutUint64(a[:], x) return append(b, a[:]...) } func appendUint32(b []byte, x uint32) []byte { var a [4]byte - putUint32(a[:], x) + binary.BigEndian.PutUint32(a[:], x) return append(b, a[:]...) } @@ -170,7 +171,7 @@ func (d *digest) checkSum() [Size]byte { // Length in bits. len <<= 3 - putUint64(tmp[:], len) + binary.BigEndian.PutUint64(tmp[:], len) d.Write(tmp[0:8]) if d.nx != 0 { @@ -179,11 +180,11 @@ func (d *digest) checkSum() [Size]byte { var digest [Size]byte - putUint32(digest[0:], d.h[0]) - putUint32(digest[4:], d.h[1]) - putUint32(digest[8:], d.h[2]) - putUint32(digest[12:], d.h[3]) - putUint32(digest[16:], d.h[4]) + binary.BigEndian.PutUint32(digest[0:], d.h[0]) + binary.BigEndian.PutUint32(digest[4:], d.h[1]) + binary.BigEndian.PutUint32(digest[8:], d.h[2]) + binary.BigEndian.PutUint32(digest[12:], d.h[3]) + binary.BigEndian.PutUint32(digest[16:], d.h[4]) return digest } @@ -263,23 +264,3 @@ func Sum(data []byte) [Size]byte { d.Write(data) return d.checkSum() } - -func putUint64(x []byte, s uint64) { - _ = x[7] - x[0] = byte(s >> 56) - x[1] = byte(s >> 48) - x[2] = byte(s >> 40) - x[3] = byte(s >> 32) - x[4] = byte(s >> 24) - x[5] = byte(s >> 16) - x[6] = byte(s >> 8) - x[7] = byte(s) -} - -func putUint32(x []byte, s uint32) { - _ = x[3] - x[0] = byte(s >> 24) - x[1] = byte(s >> 16) - x[2] = byte(s >> 8) - x[3] = byte(s) -} diff --git a/src/crypto/sha256/sha256.go b/src/crypto/sha256/sha256.go index 3fd446f94b..e1cccf65a6 100644 --- a/src/crypto/sha256/sha256.go +++ b/src/crypto/sha256/sha256.go @@ -8,6 +8,7 @@ package sha256 import ( "crypto" + "encoding/binary" "errors" "hash" ) @@ -104,35 +105,15 @@ func (d *digest) UnmarshalBinary(b []byte) error { return nil } -func putUint32(x []byte, s uint32) { - _ = x[3] - x[0] = byte(s >> 24) - x[1] = byte(s >> 16) - x[2] = byte(s >> 8) - x[3] = byte(s) -} - -func putUint64(x []byte, s uint64) { - _ = x[7] - x[0] = byte(s >> 56) - x[1] = byte(s >> 48) - x[2] = byte(s >> 40) - x[3] = byte(s >> 32) - x[4] = byte(s >> 24) - x[5] = byte(s >> 16) - x[6] = byte(s >> 8) - x[7] = byte(s) -} - func appendUint64(b []byte, x uint64) []byte { var a [8]byte - putUint64(a[:], x) + binary.BigEndian.PutUint64(a[:], x) return append(b, a[:]...) } func appendUint32(b []byte, x uint32) []byte { var a [4]byte - putUint32(a[:], x) + binary.BigEndian.PutUint32(a[:], x) return append(b, a[:]...) } @@ -246,7 +227,7 @@ func (d *digest) checkSum() [Size]byte { // Length in bits. len <<= 3 - putUint64(tmp[:], len) + binary.BigEndian.PutUint64(tmp[:], len) d.Write(tmp[0:8]) if d.nx != 0 { @@ -255,15 +236,15 @@ func (d *digest) checkSum() [Size]byte { var digest [Size]byte - putUint32(digest[0:], d.h[0]) - putUint32(digest[4:], d.h[1]) - putUint32(digest[8:], d.h[2]) - putUint32(digest[12:], d.h[3]) - putUint32(digest[16:], d.h[4]) - putUint32(digest[20:], d.h[5]) - putUint32(digest[24:], d.h[6]) + binary.BigEndian.PutUint32(digest[0:], d.h[0]) + binary.BigEndian.PutUint32(digest[4:], d.h[1]) + binary.BigEndian.PutUint32(digest[8:], d.h[2]) + binary.BigEndian.PutUint32(digest[12:], d.h[3]) + binary.BigEndian.PutUint32(digest[16:], d.h[4]) + binary.BigEndian.PutUint32(digest[20:], d.h[5]) + binary.BigEndian.PutUint32(digest[24:], d.h[6]) if !d.is224 { - putUint32(digest[28:], d.h[7]) + binary.BigEndian.PutUint32(digest[28:], d.h[7]) } return digest diff --git a/src/crypto/sha512/sha512.go b/src/crypto/sha512/sha512.go index c685319480..9c143a2a28 100644 --- a/src/crypto/sha512/sha512.go +++ b/src/crypto/sha512/sha512.go @@ -12,6 +12,7 @@ package sha512 import ( "crypto" + "encoding/binary" "errors" "hash" ) @@ -195,21 +196,9 @@ func (d *digest) UnmarshalBinary(b []byte) error { return nil } -func putUint64(x []byte, s uint64) { - _ = x[7] - x[0] = byte(s >> 56) - x[1] = byte(s >> 48) - x[2] = byte(s >> 40) - x[3] = byte(s >> 32) - x[4] = byte(s >> 24) - x[5] = byte(s >> 16) - x[6] = byte(s >> 8) - x[7] = byte(s) -} - func appendUint64(b []byte, x uint64) []byte { var a [8]byte - putUint64(a[:], x) + binary.BigEndian.PutUint64(a[:], x) return append(b, a[:]...) } @@ -316,8 +305,8 @@ func (d *digest) checkSum() [Size]byte { // Length in bits. len <<= 3 - putUint64(tmp[0:], 0) // upper 64 bits are always zero, because len variable has type uint64 - putUint64(tmp[8:], len) + binary.BigEndian.PutUint64(tmp[0:], 0) // upper 64 bits are always zero, because len variable has type uint64 + binary.BigEndian.PutUint64(tmp[8:], len) d.Write(tmp[0:16]) if d.nx != 0 { @@ -325,15 +314,15 @@ func (d *digest) checkSum() [Size]byte { } var digest [Size]byte - putUint64(digest[0:], d.h[0]) - putUint64(digest[8:], d.h[1]) - putUint64(digest[16:], d.h[2]) - putUint64(digest[24:], d.h[3]) - putUint64(digest[32:], d.h[4]) - putUint64(digest[40:], d.h[5]) + binary.BigEndian.PutUint64(digest[0:], d.h[0]) + binary.BigEndian.PutUint64(digest[8:], d.h[1]) + binary.BigEndian.PutUint64(digest[16:], d.h[2]) + binary.BigEndian.PutUint64(digest[24:], d.h[3]) + binary.BigEndian.PutUint64(digest[32:], d.h[4]) + binary.BigEndian.PutUint64(digest[40:], d.h[5]) if d.function != crypto.SHA384 { - putUint64(digest[48:], d.h[6]) - putUint64(digest[56:], d.h[7]) + binary.BigEndian.PutUint64(digest[48:], d.h[6]) + binary.BigEndian.PutUint64(digest[56:], d.h[7]) } return digest