Ensure that nogo is enabled.

A recent change stopped using the correct file (the export data, not the
archive) and checklocks started failing. Unfortunately, this was suppressed,
since the filter command was not failing with findings.

This change fixes that problem and adds a test to ensure that this cannot
happen again. If nogo starts failing to identify problems, the sanity_test in
nogo/sanity will also start to fail.

This change also requires updating the WORKSPACE to the latest rules_go and
Go version, in order to pick up the fixed go_tools. The latest rules_go in
turn required an updated bazel, which in turn required a minor change in the
coverdata implementation.

Fixing the fact propagation brought forward a number of problems with caching
for bazel workers. Its unclear whether this was a core worker issue or whether
some caching was broken, but the situation was basically undebugable. Instead,
the way facts are stored and loaded is optimized to be able to remove the use
of workers altogether and ideally make nogo debuggable.

PiperOrigin-RevId: 426327186
This commit is contained in:
Adin Scannell
2022-02-03 23:45:40 -08:00
committed by gVisor bot
parent dce4528a1a
commit a87bb4aae2
34 changed files with 753 additions and 997 deletions
+3
View File
@@ -41,6 +41,9 @@ steps:
- <<: *common
label: ":fire: Smoke tests"
command: make smoke-tests
- <<: *common
label: ":fire: Smoke race tests"
command: make smoke-race-tests
- wait
# Check that the Go branch builds.
+5 -2
View File
@@ -185,11 +185,14 @@ debian: ## Builds the debian packages.
@$(call build,-c opt //debian:debian)
.PHONY: debian
smoke-tests: ## Runs a simple smoke test after build runsc.
smoke-tests: ## Runs a simple smoke test after building runsc.
@$(call run,//runsc,--alsologtostderr --network none --debug --TESTONLY-unsafe-nonroot=true --rootless do true)
@$(call run,$(RACE_FLAGS) //runsc:runsc-race,--alsologtostderr --network none --debug --TESTONLY-unsafe-nonroot=true --rootless do true)
.PHONY: smoke-tests
smoke-race-tests: ## Runs a smoke test after build building runsc in race configuration.
@$(call run,$(RACE_FLAGS) //runsc:runsc-race,--alsologtostderr --network none --debug --TESTONLY-unsafe-nonroot=true --rootless do true)
.PHONY: smoke-race-tests
nogo-tests:
@$(call test,--build_tag_filters=nogo --test_tag_filters=nogo //:all pkg/... tools/...)
.PHONY: nogo-tests
+42 -33
View File
@@ -39,36 +39,52 @@ http_archive(
# Newer versions of the rules_go rules will automatically strip test
# binaries of symbols, which we don't want.
"//tools:rules_go_symbols.patch",
# Allow for patching of the go_sdk.
"//tools:rules_go_sdk.patch",
],
sha256 = "8e968b5fcea1d2d64071872b12737bbb5514524ee5f0a4f54f5920266c261acb",
sha256 = "d6b2513456fe2229811da7eb67a444be7785f5323c6708b38d851d2b51e54d83",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.28.0/rules_go-v0.28.0.zip",
"https://github.com/bazelbuild/rules_go/releases/download/v0.28.0/rules_go-v0.28.0.zip",
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.30.0/rules_go-v0.30.0.zip",
"https://github.com/bazelbuild/rules_go/releases/download/v0.30.0/rules_go-v0.30.0.zip",
],
)
http_archive(
name = "bazel_gazelle",
sha256 = "62ca106be173579c0a167deb23358fdfe71ffa1e4cfdddf5582af26520f1c66f",
sha256 = "de69a09dc70417580aabf20a28619bb3ef60d038470c7cf8442fafcf627c21cb",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.23.0/bazel-gazelle-v0.23.0.tar.gz",
"https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.23.0/bazel-gazelle-v0.23.0.tar.gz",
"https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.24.0/bazel-gazelle-v0.24.0.tar.gz",
"https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.24.0/bazel-gazelle-v0.24.0.tar.gz",
],
)
load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
load("@io_bazel_rules_go//go:deps.bzl", "go_download_sdk", "go_rules_dependencies")
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository")
go_rules_dependencies()
go_register_toolchains(go_version = "1.16.8")
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository")
go_download_sdk(
name = "go_sdk",
# This implements a fix in the types package which dramatically speeds up
# analysis. Without this fix, the nogo rules will often fail to run in
# time on our continuous integration.
patch = "//tools:go_types_memoize.patch",
patch_strip = 2,
version = "1.17.6",
)
gazelle_dependencies()
# Some repository below has a transitive dependency on these repositories.
# These declarations must precede any later declarations that transitively
# depend on older versions, since only the first declaration is considered.
# depend on older versions, since only the first declaration is considered. go_repository(
go_repository(
name = "org_golang_x_tools",
importpath = "golang.org/x/tools",
sum = "h1:j9KsMiaP1c3B0OTQGth0/k+miLGTgLsAFUCrF2vLcF8=",
version = "v0.1.9",
)
go_repository(
name = "org_golang_x_sys",
importpath = "golang.org/x/sys",
@@ -83,6 +99,20 @@ go_repository(
version = "v0.0.0-20210503060351-7fd8e65b6420",
)
go_repository(
name = "co_honnef_go_tools",
importpath = "honnef.co/go/tools",
sum = "h1:MNh1AVMyVX23VUHE2O27jm6lNj3vjO5DexS4A1xvnzk=",
version = "v0.2.2",
)
go_repository(
name = "org_golang_x_oauth2",
importpath = "golang.org/x/oauth2",
sum = "h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=",
version = "v0.0.0-20211104180415-d3ed0bb246c8",
)
# Load C++ rules.
http_archive(
name = "rules_cc",
@@ -585,11 +615,11 @@ rbe_autoconfig(name = "rbe_default")
http_archive(
name = "rules_pkg",
sha256 = "62eeb544ff1ef41d786e329e1536c1d541bb9bcad27ae984d57f18f314018e66",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/rules_pkg/releases/download/0.6.0/rules_pkg-0.6.0.tar.gz",
"https://github.com/bazelbuild/rules_pkg/releases/download/0.6.0/rules_pkg-0.6.0.tar.gz",
],
sha256 = "62eeb544ff1ef41d786e329e1536c1d541bb9bcad27ae984d57f18f314018e66",
)
load("@rules_pkg//:deps.bzl", "rules_pkg_dependencies")
@@ -820,13 +850,6 @@ go_repository(
version = "v0.0.0-20191024005414-555d28b269f0",
)
go_repository(
name = "org_golang_x_tools",
importpath = "golang.org/x/tools",
sum = "h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA=",
version = "v0.1.5",
)
go_repository(
name = "org_golang_x_xerrors",
importpath = "golang.org/x/xerrors",
@@ -848,13 +871,6 @@ go_repository(
version = "v1.5.2",
)
go_repository(
name = "org_golang_x_oauth2",
importpath = "golang.org/x/oauth2",
sum = "h1:B333XXssMuKQeBwiNODx4TupZy7bf4sxFZnN2ZOcvUE=",
version = "v0.0.0-20211005180243-6b3c2da341f1",
)
go_repository(
name = "com_github_docker_docker",
importpath = "github.com/docker/docker",
@@ -974,13 +990,6 @@ go_repository(
version = "v0.23.0",
)
go_repository(
name = "co_honnef_go_tools",
importpath = "honnef.co/go/tools",
sum = "h1:/EPr//+UMMXwMTkXvCCoaJDq8cpjMO80Ou+L4PDo2mY=",
version = "v0.2.1",
)
go_repository(
name = "com_github_burntsushi_toml",
importpath = "github.com/BurntSushi/toml",
+1 -1
View File
@@ -4,7 +4,7 @@ go 1.17
require (
github.com/BurntSushi/toml v0.3.1
github.com/bazelbuild/rules_go v0.27.0
github.com/bazelbuild/rules_go v0.30.0
github.com/cenkalti/backoff v1.1.1-0.20190506075156-2146c9339422
github.com/containerd/cgroups v1.0.1
github.com/containerd/console v1.0.1
+2
View File
@@ -57,6 +57,8 @@ github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kd
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/bazelbuild/rules_go v0.27.0 h1:KViqR7qKXwz+LrNdIauCDU21kneCk+4DnYjpvlJwH50=
github.com/bazelbuild/rules_go v0.27.0/go.mod h1:MC23Dc/wkXEyk3Wpq6lCqz0ZAYOZDw2DR5y3N1q2i7M=
github.com/bazelbuild/rules_go v0.30.0 h1:kX4jVcstqrsRqKPJSn2mq2o+TI21edRzEJSrEOMQtr0=
github.com/bazelbuild/rules_go v0.30.0/go.mod h1:MC23Dc/wkXEyk3Wpq6lCqz0ZAYOZDw2DR5y3N1q2i7M=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/cenkalti/backoff v1.1.1-0.20190506075156-2146c9339422 h1:8eZxmY1yvxGHzdzTEhI09npjMVGzNAdrqzruTX6jcK4=
+1 -1
View File
@@ -24,6 +24,6 @@ RUN curl https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud
ln -s /google-cloud-sdk/bin/gcloud /usr/bin/gcloud
# Download the official bazel binary. The APT repository isn't used because there is not packages for arm64.
RUN sh -c 'curl -o /usr/local/bin/bazel https://releases.bazel.build/4.0.0/release/bazel-4.0.0-linux-$(uname -m | sed s/aarch64/arm64/) && chmod ugo+x /usr/local/bin/bazel'
RUN sh -c 'curl -o /usr/local/bin/bazel https://releases.bazel.build/4.2.1/release/bazel-4.2.1-linux-$(uname -m | sed s/aarch64/arm64/) && chmod ugo+x /usr/local/bin/bazel'
WORKDIR /workspace
ENTRYPOINT ["/usr/local/bin/bazel"]
+24
View File
@@ -51,6 +51,20 @@ global:
- "may require checklocks annotation for"
# Generated proto code creates declarations like 'var start int = iNdEx'
- "should omit type .* from declaration; it will be inferred from the right-hand side"
external:
suppress:
# buildssa can't handle certain packages (cmd/...).
- "panic recovered: interface conversion: types.Type is nil"
- "panic recovered: runtime error: invalid memory address or nil"
- "panic recovered: no type for \\*ast.CallExpr"
- "panic recovered: interface conversion: types.Type is \\*types.Basic"
- "panic recovered: no type for \\*ast.BinaryExpr"
- "panic recovered: no type for \\*ast.SelectorExpr"
- "panic recovered: no types.Object for ast.Ident SetTypeErrors"
- "panic recovered: unexpected CompositeLit type: invalid type"
exclude:
- ".*/vet/testdata/.*"
- ".*/runtime/testdata/.*"
internal:
suppress:
# We use ALL_CAPS for system definitions,
@@ -100,6 +114,9 @@ analyzers:
exclude: [".*"]
errorsas:
external: # Enabled.
exclude:
# Specific broken case.
- ".*/cmd/go/internal/modload/list.go"
httpresponse:
external: # Enabled.
loopclosure:
@@ -111,6 +128,7 @@ analyzers:
exclude:
- pkg/sentry/platform/kvm/kvm_test.go # Intentional.
- tools/bigquery/bigquery.go # False positive.
- "-" # No filename.
printf:
external: # Enabled.
suppress:
@@ -157,6 +175,10 @@ analyzers:
external: # Enabled.
checkescape:
external: # Enabled.
suppress:
# External libraries may not have binaries (e.g. stdlib testdata, etc.),
# so these cases can be safely ignored.
- "no such file or directory"
checklinkname:
external: # Enabled.
suppress:
@@ -168,6 +190,8 @@ analyzers:
# targets in the standard library, so we still need to run
# checklinkname on stdlib generally.
- "linkname to unknown symbol"
exclude:
- ".*/containerd/sys/subprocess_unsafe_linux.go"
SA1019: # Use of deprecated identifier.
# disable for now due to misattribution from golang.org/issue/44195.
generated:
+10 -10
View File
@@ -39,7 +39,7 @@ import (
)
var (
// coverageMu must be held while accessing coverdata.Cover. This prevents
// coverageMu must be held while accessing coverdata.*. This prevents
// concurrent reads/writes from multiple threads collecting coverage data.
coverageMu sync.RWMutex
@@ -61,7 +61,7 @@ const blockBitLength = 16
// Available returns whether any coverage data is available.
func Available() bool {
return len(coverdata.Cover.Blocks) > 0
return len(coverdata.Blocks) > 0
}
// EnableReport sets up coverage reporting.
@@ -102,7 +102,7 @@ func ClearCoverageData() {
// We do not use atomic operations while reading/writing to the counters,
// which would drastically degrade performance. Slight discrepancies due to
// racing is okay for the purposes of kcov.
for _, counters := range coverdata.Cover.Counters {
for _, counters := range coverdata.Counters {
for index := 0; index < len(counters); index++ {
counters[index] = 0
}
@@ -155,7 +155,7 @@ func ConsumeCoverageData(w io.Writer) int {
total := 0
var pcBuffer [8]byte
for fileNum, file := range globalData.files {
counters := coverdata.Cover.Counters[file]
counters := coverdata.Counters[file]
for index := 0; index < len(counters); index++ {
// We do not use atomic operations while reading/writing to the counters,
// which would drastically degrade performance. Slight discrepancies due to
@@ -194,13 +194,13 @@ func InitCoverageData() {
globalData.once.Do(func() {
// First, order all files. Then calculate synthetic PCs for every block
// (using the well-defined ordering for files as well).
for file := range coverdata.Cover.Blocks {
for file := range coverdata.Blocks {
globalData.files = append(globalData.files, file)
}
sort.Strings(globalData.files)
for fileNum, file := range globalData.files {
blocks := coverdata.Cover.Blocks[file]
blocks := coverdata.Blocks[file]
pcs := make([]uint64, 0, len(blocks))
for blockNum := range blocks {
pcs = append(pcs, calculateSyntheticPC(fileNum, blockNum))
@@ -226,8 +226,8 @@ func Report() error {
var err error
reportOnce.Do(func() {
for file, counters := range coverdata.Cover.Counters {
blocks := coverdata.Cover.Blocks[file]
for file, counters := range coverdata.Counters {
blocks := coverdata.Blocks[file]
for i := 0; i < len(counters); i++ {
if atomic.LoadUint32(&counters[i]) > 0 {
err = writeBlock(reportOutput, file, blocks[i])
@@ -260,7 +260,7 @@ func Symbolize(out io.Writer, pc uint64) error {
// corresponding synthetic PCs.
func WriteAllBlocks(out io.Writer) error {
for fileNum, file := range globalData.files {
for blockNum, block := range coverdata.Cover.Blocks[file] {
for blockNum, block := range coverdata.Blocks[file] {
if err := writeBlockWithPC(out, calculateSyntheticPC(fileNum, blockNum), file, block); err != nil {
return err
}
@@ -300,7 +300,7 @@ func fileFromIndex(i int) (string, error) {
// blockFromIndex returns the i-th block in the given file.
func blockFromIndex(file string, i int) (testing.CoverBlock, error) {
blocks, ok := coverdata.Cover.Blocks[file]
blocks, ok := coverdata.Blocks[file]
if !ok {
return testing.CoverBlock{}, fmt.Errorf("instrumented file %s does not exist", file)
}
@@ -74,7 +74,9 @@ func TestConnectionAbort(t *testing.T) {
testObj := primitive.Uint32(rand.Uint32())
for i := 0; i < int(numRequests); i++ {
req := conn.NewRequest(creds, uint32(i), uint64(i), 0, &testObj)
conn.fd.mu.Lock()
fut, err := conn.callFutureLocked(task, req)
conn.fd.mu.Unlock()
if err != nil {
t.Fatalf("callFutureLocked failed: %v", err)
}
+3 -3
View File
@@ -303,12 +303,12 @@ func (fs *filesystem) MountOptions() string {
return fs.opts.mopts
}
// Fh data returned by newEntry
// NewFhData is returned by newEntry.
type NewFhData struct {
// file handler
// fh is the file handler.
fh uint64
// Flags of the file.
// flags is the flags of the file.
flags uint32
}
+1 -7
View File
@@ -1,4 +1,4 @@
load("//tools:defs.bzl", "bzl_library", "go_proto_library")
load("//tools:defs.bzl", "bzl_library")
package(
default_visibility = ["//:sandbox"],
@@ -53,9 +53,3 @@ genrule(
],
visibility = ["//:sandbox"],
)
go_proto_library(
name = "worker_protocol_go_proto",
importpath = "gvisor.dev/bazel/worker_protocol_go_proto",
proto = "@bazel_tools//src/main/protobuf:worker_protocol_proto",
)
-2
View File
@@ -11,8 +11,6 @@ go_embed_data = _go_embed_data
go_path = _go_path
bazel_worker_proto = "//tools/bazeldefs:worker_protocol_go_proto"
def _go_proto_or_grpc_library(go_library_func, name, **kwargs):
if "importpath" in kwargs:
# If importpath is explicit, pass straight through.
+1
View File
@@ -8,6 +8,7 @@ go_library(
nogo = False,
visibility = ["//tools/nogo:__subpackages__"],
deps = [
"//pkg/log",
"//tools/nogo/flags",
"@org_golang_x_tools//go/analysis:go_default_library",
"@org_golang_x_tools//go/analysis/passes/buildssa:go_default_library",
+47 -37
View File
@@ -67,15 +67,16 @@ import (
"go/types"
"io"
"io/ioutil"
"log"
"os"
"os/exec"
"path/filepath"
"strings"
"sync"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/buildssa"
"golang.org/x/tools/go/ssa"
"gvisor.dev/gvisor/pkg/log"
"gvisor.dev/gvisor/tools/nogo/flags"
)
@@ -165,21 +166,6 @@ var escapingBuiltins = []string{
"mallocgc",
}
// packageEscapeFacts is the set of all functions in a package, and whether or
// not they recursively pass escape analysis.
//
// All the type names for receivers are encoded in the full key. The key
// represents the fully qualified package and type name used at link time.
//
// Note that each Escapes object is a summary. Local findings may be reported
// using more detailed information.
type packageEscapeFacts struct {
Funcs map[string]Escapes
}
// AFact implements analysis.Fact.AFact.
func (*packageEscapeFacts) AFact() {}
// objdumpAnalyzer accepts the objdump parameter.
type objdumpAnalyzer struct {
analysis.Analyzer
@@ -202,7 +188,7 @@ var Analyzer = &objdumpAnalyzer{
Doc: "escape analysis checks based on +checkescape annotations",
Run: nil, // Must be invoked via Run above.
Requires: []*analysis.Analyzer{buildssa.Analyzer},
FactTypes: []analysis.Fact{(*packageEscapeFacts)(nil)},
FactTypes: []analysis.Fact{(*Escapes)(nil)},
},
}
@@ -252,6 +238,9 @@ type Escapes struct {
Omitted [reasonCount]int
}
// AFact implements analysis.Fact.AFact.
func (*Escapes) AFact() {}
// add is called by Add and Merge.
func (es *Escapes) add(r EscapeReason, detail string, omitted int, callSites ...CallSite) {
if es.CallSites[r] != nil {
@@ -407,11 +396,16 @@ func loadObjdump(binary io.Reader) (finalResults map[string][]string, finalErr e
// Execute go tool objdump ggiven the input.
cmd := exec.Command(flags.Go, "tool", "objdump", input.Name())
cmd.Stderr = os.Stderr
pipeOut, pipeErr := cmd.StdoutPipe()
if pipeErr != nil {
return nil, fmt.Errorf("unable to load objdump: %w", pipeErr)
pipeOut, err := cmd.StdoutPipe()
if err != nil {
return nil, fmt.Errorf("unable to load objdump: %w", err)
}
defer pipeOut.Close()
pipeErr, err := cmd.StderrPipe()
if err != nil {
return nil, fmt.Errorf("unable to load objdump: %w", err)
}
defer pipeErr.Close()
if startErr := cmd.Start(); startErr != nil {
return nil, fmt.Errorf("unable to start objdump: %w", startErr)
}
@@ -421,9 +415,20 @@ func loadObjdump(binary io.Reader) (finalResults map[string][]string, finalErr e
// indicate that the dump was incomplete and we could be missed some
// escapes that would have appeared. We need to force failure.
defer func() {
if waitErr := cmd.Wait(); finalErr == nil && waitErr != nil {
var (
wg sync.WaitGroup
buf bytes.Buffer
)
wg.Add(1)
go func() {
defer wg.Done()
io.Copy(&buf, pipeErr)
}()
waitErr := cmd.Wait()
wg.Wait()
if finalErr == nil && waitErr != nil {
// Override the function's return value in this case.
finalErr = fmt.Errorf("error running objdump: %v", waitErr)
finalErr = fmt.Errorf("error running objdump %s: %v (%s)", input.Name(), waitErr, buf.Bytes())
}
}()
@@ -636,7 +641,7 @@ func run(pass *analysis.Pass, binary io.Reader) (interface{}, error) {
// Note that if this analysis fails, then we don't actually
// fail the analyzer itself. We simply report every possible
// escape. In most cases this will work just fine.
log.Printf("WARNING: unable to load objdump: %v", callsErr)
log.Warningf("unable to load objdump: %v", callsErr)
}
allEscapes := make(map[string][]Escapes)
mergedEscapes := make(map[string]Escapes)
@@ -707,40 +712,42 @@ func run(pass *analysis.Pass, binary io.Reader) (interface{}, error) {
}
switch x := x.Call.Value.(type) {
case *ssa.Function:
if x.Pkg == nil {
// Can't resolve the package.
es.Add(unknownPackage, "no package", cs)
return
}
// Is this a local function? If yes, call the
// function to load the local function. The
// local escapes are the escapes found in the
// local function.
if x.Pkg.Pkg == pass.Pkg {
if x.Pkg != nil && x.Pkg.Pkg == pass.Pkg {
es.MergeWithCall(loadFunc(x), cs)
return
}
// If this package is the atomic package, the implementation
// may be replaced by instrinsics that don't have analysis.
if x.Pkg.Pkg.Path() == "sync/atomic" {
if x.Pkg != nil && x.Pkg.Pkg.Path() == "sync/atomic" {
return
}
// Recursively collect information.
var imp packageEscapeFacts
if !pass.ImportPackageFact(x.Pkg.Pkg, &imp) {
var funcEscapes Escapes
if !pass.ImportObjectFact(x.Object(), &funcEscapes) {
// If this is the unix package, and the
// function is RawSyscall, we can also
// ignore this case.
if x.Pkg != nil && x.Pkg.Pkg.Name() == "unix" && (x.Name() == "RawSyscall" || x.Name() == "RawSyscall6") {
return
}
// Unable to import the dependency; we must
// declare these as escaping.
es.Add(unknownPackage, "no analysis", cs)
message := fmt.Sprintf("no analysis for %q", x.Object().String())
es.Add(unknownPackage, message, cs)
return
}
// The escapes of this instruction are the
// escapes of the called function directly.
// Note that this may record many escapes.
es.MergeWithCall(imp.Funcs[x.RelString(x.Pkg.Pkg)], cs)
es.MergeWithCall(funcEscapes, cs)
return
case *ssa.Builtin:
// Ignore elided escapes.
@@ -846,7 +853,10 @@ func run(pass *analysis.Pass, binary io.Reader) (interface{}, error) {
// Complete all local functions.
for _, fn := range state.SrcFuncs {
loadFunc(fn)
funcEscapes := loadFunc(fn)
if obj := fn.Object(); obj != nil {
pass.ExportObjectFact(obj, &funcEscapes)
}
}
// Scan all functions for violations.
+5 -5
View File
@@ -164,8 +164,8 @@ func (*lockGuardFacts) AFact() {}
// globalGuard is a global value.
type globalGuard struct {
// Object indicates the object from which resolution should occur.
Object types.Object
// ObjectName indicates the object from which resolution should occur.
ObjectName string
// FieldList is the traversal path from object.
FieldList fieldList
@@ -179,7 +179,7 @@ type ssaPackager interface {
// resolveCommon implements resolution for all cases.
func (g *globalGuard) resolveCommon(pc *passContext, ls *lockState) resolvedValue {
state := pc.pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA)
v := state.Pkg.Members[g.Object.Name()].(ssa.Value)
v := state.Pkg.Members[g.ObjectName].(ssa.Value)
return makeResolvedValue(v, g.FieldList)
}
@@ -627,8 +627,8 @@ func (pc *passContext) findGlobalGuard(pos token.Pos, guardName string) (*global
return nil, false
}
return &globalGuard{
Object: globalObj,
FieldList: fl,
ObjectName: parts[0],
FieldList: fl,
}, true
}
+1 -2
View File
@@ -10,7 +10,7 @@ load("//tools/go_marshal:defs.bzl", "go_marshal", "marshal_deps", "marshal_test_
load("//tools/nogo:defs.bzl", "nogo_test")
load("//tools/bazeldefs:defs.bzl", _amd64_config = "amd64_config", _arch_config = "arch_config", _arm64_config = "arm64_config", _build_test = "build_test", _bzl_library = "bzl_library", _coreutil = "coreutil", _default_net_util = "default_net_util", _more_shards = "more_shards", _most_shards = "most_shards", _proto_library = "proto_library", _select_arch = "select_arch", _select_system = "select_system", _short_path = "short_path", _transition_allowlist = "transition_allowlist", _version = "version")
load("//tools/bazeldefs:cc.bzl", _cc_binary = "cc_binary", _cc_flags_supplier = "cc_flags_supplier", _cc_grpc_library = "cc_grpc_library", _cc_library = "cc_library", _cc_proto_library = "cc_proto_library", _cc_test = "cc_test", _cc_toolchain = "cc_toolchain", _gbenchmark = "gbenchmark", _gbenchmark_internal = "gbenchmark_internal", _grpcpp = "grpcpp", _gtest = "gtest", _vdso_linker_option = "vdso_linker_option")
load("//tools/bazeldefs:go.bzl", _bazel_worker_proto = "bazel_worker_proto", _gazelle = "gazelle", _go_binary = "go_binary", _go_embed_data = "go_embed_data", _go_grpc_and_proto_libraries = "go_grpc_and_proto_libraries", _go_library = "go_library", _go_path = "go_path", _go_proto_library = "go_proto_library", _go_rule = "go_rule", _go_test = "go_test", _select_goarch = "select_goarch", _select_goos = "select_goos")
load("//tools/bazeldefs:go.bzl", _gazelle = "gazelle", _go_binary = "go_binary", _go_embed_data = "go_embed_data", _go_grpc_and_proto_libraries = "go_grpc_and_proto_libraries", _go_library = "go_library", _go_path = "go_path", _go_proto_library = "go_proto_library", _go_rule = "go_rule", _go_test = "go_test", _select_goarch = "select_goarch", _select_goos = "select_goos")
load("//tools/bazeldefs:pkg.bzl", _pkg_deb = "pkg_deb", _pkg_tar = "pkg_tar")
load("//tools/bazeldefs:platforms.bzl", _default_platform = "default_platform", _platforms = "platforms")
load("//tools/bazeldefs:tags.bzl", "go_suffixes")
@@ -47,7 +47,6 @@ select_goos = _select_goos
select_goarch = _select_goarch
go_embed_data = _go_embed_data
go_proto_library = _go_proto_library
bazel_worker_proto = _bazel_worker_proto
# Packaging rules.
pkg_deb = _pkg_deb
+39
View File
@@ -0,0 +1,39 @@
diff '--color=auto' -r -u2 a/go/src/go/types/scope.go b/go/src/go/types/scope.go
--- a/go/src/go/types/scope.go 2022-01-06 19:14:25.000000000 +0000
+++ b/go/src/go/types/scope.go 2022-02-03 18:50:35.526563967 +0000
@@ -24,4 +24,5 @@
children []*Scope
elems map[string]Object // lazily allocated
+ sorted []string // lazily allocated
pos, end token.Pos // scope extent; may be invalid
comment string // for debugging only
@@ -32,5 +33,5 @@
// scope, if any. The comment is for debugging only.
func NewScope(parent *Scope, pos, end token.Pos, comment string) *Scope {
- s := &Scope{parent, nil, nil, pos, end, comment, false}
+ s := &Scope{parent, nil, nil, nil, pos, end, comment, false}
// don't add children to Universe scope!
if parent != nil && parent != Universe {
@@ -48,12 +49,14 @@
// Names returns the scope's element names in sorted order.
func (s *Scope) Names() []string {
- names := make([]string, len(s.elems))
- i := 0
- for name := range s.elems {
- names[i] = name
- i++
+ if len(s.sorted) != len(s.elems) {
+ s.sorted = make([]string, len(s.elems))
+ i := 0
+ for name := range s.elems {
+ s.sorted[i] = name
+ i++
+ }
+ sort.Strings(s.sorted)
}
- sort.Strings(names)
- return names
+ return s.sorted
}
Only in b/go/src/go/types: scope.go.orig
-1
View File
@@ -20,7 +20,6 @@ go_library(
"//tools/checkunsafe",
"//tools/nogo/facts",
"//tools/nogo/flags",
"//tools/worker",
"@co_honnef_go_tools//staticcheck:go_default_library",
"@co_honnef_go_tools//stylecheck:go_default_library",
"@org_golang_x_tools//go/analysis:go_default_library",
+6 -1
View File
@@ -15,6 +15,7 @@
package check
import (
"errors"
"fmt"
"go/build"
"io"
@@ -37,7 +38,11 @@ var findStdPkg = func(path string) (io.ReadCloser, error) {
}
// Attempt to resolve the library, and propagate this error.
return os.Open(fmt.Sprintf("%s/pkg/%s_%s/%s.a", root, flags.GOOS, flags.GOARCH, path))
f, err := os.Open(fmt.Sprintf("%s/pkg/%s_%s/%s.a", root, flags.GOOS, flags.GOARCH, path))
if err != nil && errors.Is(err, os.ErrNotExist) {
return nil, ErrSkip
}
return f, err
}
// releaseTags returns the default release tags.
+175 -150
View File
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More