Skip to content

Commit

Permalink
Merge commit 'ed817f1c4055a559a94afffecbb91c78e4f39942' into update-g…
Browse files Browse the repository at this point in the history
…o1.21.4
  • Loading branch information
awly committed Nov 9, 2023
2 parents 56d25cd + ed817f1 commit fb7f245
Show file tree
Hide file tree
Showing 35 changed files with 541 additions and 189 deletions.
4 changes: 2 additions & 2 deletions VERSION
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
go1.21.3
time 2023-10-09T17:04:35Z
go1.21.4
time 2023-11-01T20:46:39Z
32 changes: 32 additions & 0 deletions src/cmd/cgo/internal/testcarchive/carchive_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1365,3 +1365,35 @@ func TestDeepStack(t *testing.T) {
t.Error(err)
}
}

func TestSharedObject(t *testing.T) {
// Test that we can put a Go c-archive into a C shared object.
globalSkip(t)
testenv.MustHaveGoBuild(t)
testenv.MustHaveCGO(t)
testenv.MustHaveBuildMode(t, "c-archive")

t.Parallel()

if !testWork {
defer func() {
os.Remove("libgo_s.a")
os.Remove("libgo_s.h")
os.Remove("libgo_s.so")
}()
}

cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo_s.a", "./libgo")
out, err := cmd.CombinedOutput()
t.Logf("%v\n%s", cmd.Args, out)
if err != nil {
t.Fatal(err)
}

ccArgs := append(cc, "-shared", "-o", "libgo_s.so", "libgo_s.a")
out, err = exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput()
t.Logf("%v\n%s", ccArgs, out)
if err != nil {
t.Fatal(err)
}
}
40 changes: 12 additions & 28 deletions src/cmd/compile/internal/typecheck/func.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,40 +94,24 @@ func ClosureType(clo *ir.ClosureExpr) *types.Type {
// and has one float64 argument and no results,
// the generated code looks like:
//
// clos = &struct{.F uintptr; i *int; s *string}{func.1, &i, &s}
// clos = &struct{F uintptr; X0 *int; X1 *string}{func.1, &i, &s}
//
// The use of the struct provides type information to the garbage
// collector so that it can walk the closure. We could use (in this case)
// [3]unsafe.Pointer instead, but that would leave the gc in the dark.
// The information appears in the binary in the form of type descriptors;
// the struct is unnamed so that closures in multiple packages with the
// same struct type can share the descriptor.

// Make sure the .F field is in the same package as the rest of the
// fields. This deals with closures in instantiated functions, which are
// compiled as if from the source package of the generic function.
var pkg *types.Pkg
if len(clo.Func.ClosureVars) == 0 {
pkg = types.LocalPkg
} else {
for _, v := range clo.Func.ClosureVars {
if pkg == nil {
pkg = v.Sym().Pkg
} else if pkg != v.Sym().Pkg {
base.Fatalf("Closure variables from multiple packages: %+v", clo)
}
}
}

fields := []*types.Field{
types.NewField(base.Pos, pkg.Lookup(".F"), types.Types[types.TUINTPTR]),
}
for _, v := range clo.Func.ClosureVars {
// collector so that it can walk the closure. We could use (in this
// case) [3]unsafe.Pointer instead, but that would leave the gc in
// the dark. The information appears in the binary in the form of
// type descriptors; the struct is unnamed and uses exported field
// names so that closures in multiple packages with the same struct
// type can share the descriptor.

fields := make([]*types.Field, 1+len(clo.Func.ClosureVars))
fields[0] = types.NewField(base.AutogeneratedPos, types.LocalPkg.Lookup("F"), types.Types[types.TUINTPTR])
for i, v := range clo.Func.ClosureVars {
typ := v.Type()
if !v.Byval() {
typ = types.NewPtr(typ)
}
fields = append(fields, types.NewField(base.Pos, v.Sym(), typ))
fields[1+i] = types.NewField(base.AutogeneratedPos, types.LocalPkg.LookupNum("X", i), typ)
}
typ := types.NewStruct(fields)
typ.SetNoalg(true)
Expand Down
3 changes: 0 additions & 3 deletions src/cmd/compile/internal/types/fmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -642,9 +642,6 @@ func fldconv(b *bytes.Buffer, f *Field, verb rune, mode fmtMode, visited map[*Ty
name = fmt.Sprint(f.Nname)
} else if verb == 'L' {
name = s.Name
if name == ".F" {
name = "F" // Hack for toolstash -cmp.
}
if !IsExported(name) && mode != fmtTypeIDName {
name = sconv(s, 0, mode) // qualify non-exported names (used on structs, not on funarg)
}
Expand Down
8 changes: 8 additions & 0 deletions src/cmd/compile/internal/types2/call.go
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,14 @@ func (check *Checker) arguments(call *syntax.CallExpr, sig *Signature, targs []T
for i, arg := range args {
// generic arguments cannot have a defined (*Named) type - no need for underlying type below
if asig, _ := arg.typ.(*Signature); asig != nil && asig.TypeParams().Len() > 0 {
// The argument type is a generic function signature. This type is
// pointer-identical with (it's copied from) the type of the generic
// function argument and thus the function object.
// Before we change the type (type parameter renaming, below), make
// a clone of it as otherwise we implicitly modify the object's type
// (go.dev/issues/63260).
clone := *asig
asig = &clone
// Rename type parameters for cases like f(g, g); this gives each
// generic function argument a unique type identity (go.dev/issues/59956).
// TODO(gri) Consider only doing this if a function argument appears
Expand Down
44 changes: 44 additions & 0 deletions src/cmd/compile/internal/types2/issues_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -920,3 +920,47 @@ func _() {
var conf Config
conf.Check(f.PkgName.Value, []*syntax.File{f}, nil) // must not panic
}

func TestIssue63260(t *testing.T) {
const src = `
package p
func _() {
use(f[*string])
}
func use(func()) {}
func f[I *T, T any]() {
var v T
_ = v
}`

info := Info{
Defs: make(map[*syntax.Name]Object),
}
pkg := mustTypecheck(src, nil, &info)

// get type parameter T in signature of f
T := pkg.Scope().Lookup("f").Type().(*Signature).TypeParams().At(1)
if T.Obj().Name() != "T" {
t.Fatalf("got type parameter %s, want T", T)
}

// get type of variable v in body of f
var v Object
for name, obj := range info.Defs {
if name.Value == "v" {
v = obj
break
}
}
if v == nil {
t.Fatal("variable v not found")
}

// type of v and T must be pointer-identical
if v.Type() != T {
t.Fatalf("types of v and T are not pointer-identical: %p != %p", v.Type().(*TypeParam), T)
}
}
2 changes: 0 additions & 2 deletions src/cmd/internal/moddeps/moddeps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ import (
// See issues 36852, 41409, and 43687.
// (Also see golang.org/issue/27348.)
func TestAllDependencies(t *testing.T) {
t.Skip("TODO(#63427): 1.21.3 contains unreleased changes from vendored modules")

goBin := testenv.GoToolPath(t)

// Ensure that all packages imported within GOROOT
Expand Down
19 changes: 13 additions & 6 deletions src/cmd/link/internal/ld/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -2599,15 +2599,22 @@ func assignAddress(ctxt *Link, sect *sym.Section, n int, s loader.Sym, va uint64

// Return whether we may need to split text sections.
//
// On PPC64x whem external linking a text section should not be larger than 2^25 bytes
// due to the size of call target offset field in the bl instruction. Splitting into
// smaller text sections smaller than this limit allows the system linker to modify the long
// calls appropriately. The limit allows for the space needed for tables inserted by the
// linker.
// On PPC64x, when external linking, a text section should not be
// larger than 2^25 bytes due to the size of call target offset field
// in the 'bl' instruction. Splitting into smaller text sections
// smaller than this limit allows the system linker to modify the long
// calls appropriately. The limit allows for the space needed for
// tables inserted by the linker.
//
// The same applies to Darwin/ARM64, with 2^27 byte threshold.
//
// Similarly for ARM, we split sections (at 2^25 bytes) to avoid
// inconsistencies between the Go linker's reachability calculations
// (e.g. will direct call from X to Y need a trampoline) and similar
// machinery in the external linker; see #58425 for more on the
// history here.
func splitTextSections(ctxt *Link) bool {
return (ctxt.IsPPC64() || (ctxt.IsARM64() && ctxt.IsDarwin())) && ctxt.IsExternal()
return (ctxt.IsARM() || ctxt.IsPPC64() || (ctxt.IsARM64() && ctxt.IsDarwin())) && ctxt.IsExternal()
}

// On Wasm, we reserve 4096 bytes for zero page, then 8192 bytes for wasm_exec.js
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/link/internal/ld/ld_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ func TestArchiveBuildInvokeWithExec(t *testing.T) {

func TestLargeTextSectionSplitting(t *testing.T) {
switch runtime.GOARCH {
case "ppc64", "ppc64le":
case "ppc64", "ppc64le", "arm":
case "arm64":
if runtime.GOOS == "darwin" {
break
Expand Down
2 changes: 1 addition & 1 deletion src/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.21

require (
golang.org/x/crypto v0.11.1-0.20230711161743-2e82bdd1719d
golang.org/x/net v0.12.1-0.20230712162946-57553cbff163
golang.org/x/net v0.12.1-0.20231027154334-5ca955b1789c
)

require (
Expand Down
4 changes: 2 additions & 2 deletions src/go.sum
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
golang.org/x/crypto v0.11.1-0.20230711161743-2e82bdd1719d h1:LiA25/KWKuXfIq5pMIBq1s5hz3HQxhJJSu/SUGlD+SM=
golang.org/x/crypto v0.11.1-0.20230711161743-2e82bdd1719d/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/net v0.12.1-0.20230712162946-57553cbff163 h1:1EDKNuaCsog7zGLEml1qRuO4gt23jORUQX2f0IKZ860=
golang.org/x/net v0.12.1-0.20230712162946-57553cbff163/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/net v0.12.1-0.20231027154334-5ca955b1789c h1:d+VvAxu4S13DWtf73R5eY//VaCk3aUcVdyYjM1SX7zw=
golang.org/x/net v0.12.1-0.20231027154334-5ca955b1789c/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
Expand Down
2 changes: 1 addition & 1 deletion src/go/build/deps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ var depsRules = `
unicode, fmt !< net, os, os/signal;
os/signal, STR
os/signal, internal/safefilepath, STR
< path/filepath
< io/ioutil;
Expand Down
8 changes: 8 additions & 0 deletions src/go/types/call.go
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,14 @@ func (check *Checker) arguments(call *ast.CallExpr, sig *Signature, targs []Type
for i, arg := range args {
// generic arguments cannot have a defined (*Named) type - no need for underlying type below
if asig, _ := arg.typ.(*Signature); asig != nil && asig.TypeParams().Len() > 0 {
// The argument type is a generic function signature. This type is
// pointer-identical with (it's copied from) the type of the generic
// function argument and thus the function object.
// Before we change the type (type parameter renaming, below), make
// a clone of it as otherwise we implicitly modify the object's type
// (go.dev/issues/63260).
clone := *asig
asig = &clone
// Rename type parameters for cases like f(g, g); this gives each
// generic function argument a unique type identity (go.dev/issues/59956).
// TODO(gri) Consider only doing this if a function argument appears
Expand Down
44 changes: 44 additions & 0 deletions src/go/types/issues_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -930,3 +930,47 @@ func _() {
var conf Config
conf.Check(f.Name.Name, fset, []*ast.File{f}, nil) // must not panic
}

func TestIssue63260(t *testing.T) {
const src = `
package p
func _() {
use(f[*string])
}
func use(func()) {}
func f[I *T, T any]() {
var v T
_ = v
}`

info := Info{
Defs: make(map[*ast.Ident]Object),
}
pkg := mustTypecheck(src, nil, &info)

// get type parameter T in signature of f
T := pkg.Scope().Lookup("f").Type().(*Signature).TypeParams().At(1)
if T.Obj().Name() != "T" {
t.Fatalf("got type parameter %s, want T", T)
}

// get type of variable v in body of f
var v Object
for name, obj := range info.Defs {
if name.Name == "v" {
v = obj
break
}
}
if v == nil {
t.Fatal("variable v not found")
}

// type of v and T must be pointer-identical
if v.Type() != T {
t.Fatalf("types of v and T are not pointer-identical: %p != %p", v.Type().(*TypeParam), T)
}
}
Loading

0 comments on commit fb7f245

Please sign in to comment.