Bare init functions omit calls to dependent init functions and the
use of an init guard. They are useful in cases where the client uses
a different calling convention for init functions, or cases where
it is easier for a client to analyze bare init functions.
LGTM=adonovan
R=adonovan
CC=golang-codereviews, iant
https://golang.org/cl/78780043
Previously, each word could be a package import path or a
comma-separated list of *.go file names. Now, if the
first word ends with ".go", all words are assumed to be
Go source files. This makes it impossible to specify
two ad-hoc packages from source files, but no-one needs that.
FromArgs also takes a boolean indicating whether tests
are wanted or not.
Also: ssadump: add -test flag to set that boolean.
For the oracle it's always true.
LGTM=gri
R=gri
CC=golang-codereviews
https://golang.org/cl/61470047
The Importer type has been replaced with Config and Program.
Clients populate a Config, directly or more usually via
convenience functions. They then call its Load() method to do
all of the typechecking and transitive-closure computation.
ssa.NewProgram and ssa.CreatePackages have been fused into
ssa.Create, which now cannot fail, since (*Config).Load()
reports all type errors.
Also:
- The addition of an ssa.GlobalDebug builder mode flag
eliminates a loop-over-packages repeated in many clients.
- PackageInfo.Err flag unexported. Clients never see bad infos now.
- cmd/ssadump: now only looks for func "main" in package "main".
- importsOf deleted, was dead code.
STILL TODO:
- ParseFile seems like API creep (though it's convenient)
and CreateFromFiles is dangerous (w.r.t. FileSet identity).
Need to think more...
- the need for clients to rely on elementwise correspondence
of Config.CreatePkgs and Program.Created is a little sad.
- The command-line interface has not changed.
That will happen in a follow-up.
r recommends using a repeated flag: -package p -package q ...
R=gri
CC=axwalk, frederik.zipp, golang-codereviews
https://golang.org/cl/49530047
Packages were not being created for all types.Packages,
specifically, indirectly imported packages were missing.
(*Program).CreatePackages now iterates over the type-checker's
package map too.
Also: removed all concurrency from importer. I think it was
incorrect (and hard to fix).
Also: change LoadInitialPackages so that all named packages
are loaded from source. This happens regardless of whether
GCImporter is used to satisfy imports.
Details:
- importer.Config.SourceImports flag determines whether to
load all packages from *.go source.
(Before, this was indicated by Config.Build != nil.)
- importer.Config.Build field effectively defaults to
&go/build.Default. A zero importer.Config is now usable.
- importer.Importer.Config field is now exported.
- LoadPackage renamed to ImportPackage since the resulting
packages may come from GCImporter (and be incomplete).
- doImport and ImportPackage fused.
Fixesgolang/go#7028
R=gri, axwalk
CC=golang-codereviews
https://golang.org/cl/48770043
Also report an error for "cross-interpretation": not supported
due to the interpreter's assumption that host and target
{int,uint,uintptr} are the same. (Too tedious and messy to fix.)
Tested manually:
% cat d.go
package main
const m = ^uintptr(0)
const w = m>>8&1 + m>>16&1 + m>>32&1
func main() { println(m, w) }
% ./ssadump -build=P -run d.go
package main:
const m m = 18446744073709551615:uintptr
const w w = 3:uintptr
18446744073709551615 3
% GOARCH=386 ./ssadump -build=P -run d.go
package main:
const m m = 4294967295:uintptr
const w w = 2:uintptr
Error: Cross-interpretation is not yet supported (target has GOARCH 386, interpreter has amd64).
Fixesgolang/go#7080
R=gri
CC=golang-codereviews
https://golang.org/cl/49070043
This allows us to run/analyze multiple tests.
Also it causes the production code packages to be properly initialized.
Also:
- cmd/ssadump: improved usage message (add example;
incorporate LoadInitialPackages usage; explain how -run
finds main).
- pointer, oracle, ssa/interp: use CreateTestMainPackage.
- ssa/builder.go: remove 'rundefers' instruction from package init,
which no longer uses 'defer'.
R=gri
CC=golang-dev
https://golang.org/cl/15920047
A function such as this:
func one() (x int) {
defer func() { recover() }()
x = 1
panic("return")
}
that combines named return parameters (NRPs) with deferred calls
that call recover, may return non-zero values despite the
fact it doesn't even contain a return statement. (!)
This requires a change to the SSA API: all functions'
control-flow graphs now have a second entry point, called
Recover, which is the block at which control flow resumes
after a recovered panic. The Recover block simply loads the
NRPs and returns them.
As an optimization, most functions don't need a Recover block,
so it is omitted. In fact it is only needed for functions that
have NRPs and defer a call to another function that _may_ call
recover.
Dataflow analysis of SSA now requires extra work, since every
may-panic instruction has an implicit control-flow edge to
the Recover block. The only dataflow analysis so far implemented
is SSA renaming, for which we make the following simplifying
assumption: the Recover block only loads the NRPs and returns.
This means we don't really need to analyze it, we can just
skip the "lifting" of such NRPs. We also special-case the Recover
block in the dominance computation.
Rejected alternative approaches:
- Specifying a Recover block for every defer instruction (like a
traditional exception handler).
This seemed like excessive generality, since Go programs
only need the same degenerate form of Recover block.
- Adding an instruction to set the Recover block immediately
after the named return values are set up, so that dominance
can be computed without special-casing.
This didn't seem worth the effort.
Interpreter:
- This CL completely reimplements the panic/recover/
defer logic in the interpreter. It's clearer and simpler
and closer to the model in the spec.
- Some runtime panic messages have been changed to be closer
to gc's, since tests depend on it.
- The interpreter now requires that the runtime.runtimeError
type be part of the SSA program. This requires that clients
import this package prior to invoking the interpreter.
This in turn requires (Importer).ImportPackage(path string),
which this CL adds.
- All $GOROOT/test/recover{,1,2,3}.go tests are now passing.
NB, the bug described in coverage.go (defer/recover in a concatenated
init function) remains. Will be fixed in a follow-up.
Fixesgolang/go#6381
R=gri
CC=crawshaw, golang-dev
https://golang.org/cl/13844043
Motivation: pointer analysis tools (like the oracle) want the
user to specify a set of initial packages, like 'go test'.
This change enables the user to specify a set of packages on
the command line using importer.LoadInitialPackages(args).
Each argument is interpreted as either:
- a comma-separated list of *.go source files together
comprising one non-importable ad-hoc package.
e.g. "src/pkg/net/http/triv.go" gives us [main].
- an import path, denoting both the imported package
and its non-importable external test package, if any.
e.g. "fmt" gives us [fmt, fmt_test].
Current type-checker limitations mean that only the first
import path may contribute tests: multiple packages augmented
by *_test.go files could create import cycles, which 'go test'
avoids by building a separate executable for each one.
That approach is less attractive for static analysis.
Details: (many files touched, but importer.go is the crux)
importer:
- PackageInfo.Importable boolean indicates whether
package is importable.
- un-expose Importer.Packages; expose AllPackages() instead.
- CreatePackageFromArgs has become LoadInitialPackages.
- imports() moved to util.go, renamed importsOf().
- InitialPackagesUsage usage message exported to clients.
- the package name for ad-hoc packages now comes from the
'package' decl, not "main".
ssa.Program:
- added CreatePackages() method
- PackagesByPath un-exposed, renamed 'imported'.
- expose AllPackages and ImportedPackage accessors.
oracle:
- describe: explain and workaround a go/types bug.
Misc:
- Removed various unnecessary error.Error() calls in Printf args.
R=crawshaw
CC=golang-dev
https://golang.org/cl/13579043
1. ParseFiles (in util.go) parses each file in its own goroutine.
2. (*Importer).LoadPackage asynchronously prefetches the
import graph by scanning the imports of each loaded package
and calling LoadPackage on each one.
LoadPackage is now thread-safe and idempotent: it uses a
condition variable per package; the first goroutine to
request a package becomes responsible for loading it and
broadcasts to the others (waiting) when it becomes ready.
ssadump runs 34% faster when loading the oracle.
Also, refactorings:
- delete SourceLoader mechanism; just expose go/build.Context directly.
- CreateSourcePackage now also returns an error directly,
rather than via PackageInfo.Err, since every client wants that.
R=crawshaw
CC=golang-dev
https://golang.org/cl/13509045
(Its former location was based on a misunderstanding of 'go build'.)
Also: set GOMAXPROCS to NumCPU by default.
R=crawshaw
CC=golang-dev
https://golang.org/cl/13354043