- Add missing import.
- platform-specific files syswrite() wrapper presents
standard API to syscall.Write, even on Windows where
first arg is a Handle.
Fixesgolang/go#7100
R=gri, minux.ma, alex.brainman
CC=golang-codereviews
https://golang.org/cl/52250043
go/types no longer reports a constant value for a slice,
e.g. []byte("foo").
ssa.Const no longer support slice constants, only
bool/string/numeric and nil.
emitConv emits a Convert instruction for string->[]byte
conversions.
Added regression test for bug 6949.
R=gri
CC=golang-codereviews
https://golang.org/cl/50590043
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
Although such a control-flow path is impossible by
construction, we must avoid no-arg returns (even if
unreachable) in non-void functions.
Tested by adding a sanity-check that ssa.Return has the correct arity.
Also: added ssautil.Switches() test.
Fixesgolang/go#7702
R=gri, axwalk
CC=golang-codereviews
https://golang.org/cl/46520043
Cause: emitExtract requires a type for each component of the
receive tuple; blank supplies no such type.
Solution: remove type parameter for emitExtract as it is no
longer needed: since rev b75cc03b4a56 it is always identical
to the tuple.Type().At(index).
+ tests.
Fixesgolang/go#6806.
R=gri, gri
CC=axwalk, golang-dev
https://golang.org/cl/30410043
The previous code introduced spurious loop-carried
dependencies for variables local to a loop body (for example).
The SSA renaming pass now treats an Alloc instruction like a
Store of the zero value.
Also:
- added regression test
- improved log messages
- made the Store/Load/Alloc cases look more similar.
R=gri, gri
CC=golang-dev
https://golang.org/cl/26750043
Also, only examine functions defined in *_test.go files.
Added tests for empty and nonempty behaviour of CreateTestMainPackage.
(Required some surgery to interp_test.)
R=gri, gri
CC=golang-dev
https://golang.org/cl/25570044
Added test for []*map composite literals containing nested
literal subelements. This required implementing
(reflect.Value).Map{Keys,Index} in ssa/interp.
Plus two minor fixes in ssa/interp.
R=gri
CC=golang-dev
https://golang.org/cl/20470043
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
Before, we would concatenate all the init() blocks together,
resulting in incorrect treatment of a recovered panic in one
init block: the implicit return would cause the subsequent ones
to be skipped.
The result is simpler, and closer to what gc does.
The additional functions are visible in the call graph,
so some tests required updating.
R=gri
CC=crawshaw, golang-dev
https://golang.org/cl/14671044
Before: func(any, ...interface{}).
After: func(any, ...any)
They are no longer variadic, so you can't write print(x, y...).
(Recall that print(1) and print(interface{}(1)) behave
differently and that this is useful.)
Fixes bug 6560
R=gri
CC=golang-dev
https://golang.org/cl/14455054
The new method is functionally identical to typeCheck, and
obviates the LoadMainPackage method.
Updated all clients.
Fixes bug 6561.
R=gri
CC=golang-dev
https://golang.org/cl/14494051
The $GOROOT/tests may print "BUG" on failure but do not
necessarily exit zero, so we must capture their output too.
Details:
- make plan9 use unix's valueToBytes function (now in externals.go)
- direct the target's syscall.Write and print/println built-ins to a new utility, write(). This may capture the output into a global variable.
R=gri, r
CC=golang-dev
https://golang.org/cl/14550044
- This change implements the correct type-based equivalence
relation for aggregate types. e.g. comparison of struct
types no longer compares the anonymous fields. We do
analogous things for hash().
- equals() and eqnil() have been separated: the former panics
for uncomparable types, the latter permits comparisons of
slice/map/func types against a literal nil and is intended
for use only by "static" ssa.BinOp(EQL), not "dynamic" slice
comparisons encountered during (e.g.) interface comparisons,
which should panic regardless of operand nilness.
- we use a (global) typemap.Hasher to compute type hashes;
hashing the Type.String() value was not sound.
+ tests.
NB, this change unearthed a bug in defer/recover within
init(); it will be fixed in a followup change.
R=gri, crawshaw
CC=golang-dev
https://golang.org/cl/13719043
Running the interpreter on (most of) the tests package in
"encoding" unearthed a couple of ssa.builder bugs, already
fixed. This CL contains the interpreter fixes that were
required. (The "encoding" tests aren't added to the suite
since they're slow.)
Added intrinsics for:
math.Exp
math.Min
hash/crc32.haveSSE42
(reflect.Type).Field
(reflect.Type).NumField
(reflect.Type).NumMethod
reflect.New
(reflect.Value).NumMethod
syscall.RawSyscall (returns ENOSYS)
reflect.Set (a no-op)
Treat unsafe.Pointer -> *T conversions by returning new(T).
This is incorrect but at least preserves type-safety,
which is sufficient for these tests.
hashmap: treat nil *hashmap as an empty map.
R=gri
CC=golang-dev
https://golang.org/cl/12901046
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
Map literals should use the same recursion logic as
struct/array/slice literals to apply an implicit &-operator to
the nested literals when a pointer is wanted.
+ test.
Also:
- ensure we set the source location for all Lookup and
MapUpdate instructions.
- remove obsolete address.object field.
R=gri, crawshaw
CC=golang-dev
https://golang.org/cl/12787048
&x.f, &x[0], x[i:j], &*x all must panic if x==nil.
The first three are already addressed by the semantics of
FieldAddr, IndexAddr, Slice; updated docs to reflect this.
The final case requires generation of an additional dynamic check.
See golang.org/s/go12nil for details.
Tested on $GOROOT/test/nilptr2.go (with patch from CL 13108043)
Also: remove a TODO where a no-op will do.
R=gri, crawshaw
CC=golang-dev, rsc
https://golang.org/cl/13064044
Fix bug: the Signature for an interface method wrapper
erroneously had a non-nil receiver.
Function:
- Set Pkg field non-nil even for wrappers.
It is equal to that of the wrapped function.
Only wrappers of error.Error
(and its embeddings in other interfaces) may have nil.
Sanity checker now asserts this.
- FullName() now uses .Synthetic field to discriminate
synthetic methods, not Pkg==nil.
- Fullname() uses new relType() utility to print receiver type
name unqualified if it belongs to the same package.
(Alloc.String also uses relType utility.)
CallCommon:
- Description(): fix switch logic broken when we
eliminated the Recv field.
- better docs.
R=david.crawshaw, crawshaw, gri
CC=golang-dev
https://golang.org/cl/13057043
Package.CreateTestMainFunction() creates a function called
main and adds it to the package. This function calls
testing.Main in the Go library with the appropriate arguments:
slices of test, benchmark and example functions from the
package.
Tested by running the interpreter on the following tests:
- unicode/script_test.go
- unicode/digit_test.go
- hash/crc32/crc32_test.go
- path/path_test.go
It's also covered indirectly via the pointer analysis.
R=crawshaw, gri
CC=golang-dev
https://golang.org/cl/12814046
Was broken by CL 12378043.
- factored out some error checking code
- adjusted error positions
R=adonovan
TBR=adonovan
CC=golang-dev
https://golang.org/cl/12401043
stdlib_test runs the builder (in sanity-checking mode) over
the Go standard library. It also prints some stats about
the time and memory usage.
Also:
- importer.LoadPackage too (not just doImport) must consult
the cache to avoid creating duplicate Package instances for
the same import path when called serially from a test.
- importer: skip empty directories without an error.
- importer: print all errors, not just the first.
- visit.go: added AllFunctions utility for enumerating all
Functions in a Program.
- ssa.MethodSet is not safe to expose from the package since
it must be accessed under an (inaccessible) lock. (!!!)
This CL makes it unexported and restricts its use to the
single function Program.LookupMethod().
- Program.MethodSet() has gone.
Clients should instead iterate over the types.MethodSet
and call LookupMethod.
- Package.DumpTo(): improved efficiency of methodset printing
(by not creating wrappers) and accuracy (by showing * on
receiver type only when necessary).
- Program.CreatePackage: documented precondition and added
assertion.
R=gri
CC=golang-dev
https://golang.org/cl/12058048