Skip to content

Commit 8241a96

Browse files
authored
Merge branch 'master' into encoding_add_full_support_for_marshalers_with_pointer_receivers
2 parents 78d2393 + 7fcd4a7 commit 8241a96

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+813
-129
lines changed

api/next/62516.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
pkg testing, method (*B) Chdir(string) #62516
2+
pkg testing, method (*F) Chdir(string) #62516
3+
pkg testing, method (*T) Chdir(string) #62516
4+
pkg testing, type TB interface, Chdir(string) #62516

doc/godebug.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,18 @@ see the [runtime documentation](/pkg/runtime#hdr-Environment_Variables)
151151
and the [go command documentation](/cmd/go#hdr-Build_and_test_caching).
152152

153153
### Go 1.24
154-
Go 1.24 made XML marshaling consistent: custom marshalers ([`MarshalXML`](/pkg/encoding/xml#Marshaler), [`MarshalXMLAttr`](/pkg/encoding/xml#MarshalerAttr), [`MarshalText`](/pkg/encoding#TextMarshaler)) are now always called when appropriate no matter if their receivers are pointers or values even if the related data fields are non-addressable. Also, [`MarshalXMLAttr`](/pkg/encoding/xml#MarshalerAttr) and [`MarshalText`](/pkg/encoding#TextMarshaler) are now called when appropriate for struct fields marked as attribute/CDATA/chardata even if the field type is an interface. This behavior can be reverted with the [`xmlinconsistentmarshal` setting](/pkg/encoding/xml/#Marshal).
154+
Go 1.24 made XML marshaling consistent: custom marshalers ([`MarshalXML`](/pkg/encoding/xml#Marshaler),
155+
[`MarshalXMLAttr`](/pkg/encoding/xml#MarshalerAttr), [`MarshalText`](/pkg/encoding#TextMarshaler))
156+
are now always called when appropriate no matter if their receivers are pointers or values
157+
even if the related data fields are non-addressable. Also, [`MarshalXMLAttr`](/pkg/encoding/xml#MarshalerAttr)
158+
and [`MarshalText`](/pkg/encoding#TextMarshaler) are now called when appropriate for struct fields
159+
marked as attribute/CDATA/chardata even if the field type is an interface.
160+
This behavior can be reverted with the [`xmlinconsistentmarshal` setting](/pkg/encoding/xml/#Marshal).
161+
162+
Go 1.24 changed the global [`math/rand.Seed`](/pkg/math/rand/#Seed) to be a
163+
no-op. This setting is controlled by the `randseednop` setting.
164+
For Go 1.24 it defaults to `randseednop=1`.
165+
Using `randseednop=0` reverts to the pre-Go 1.24 behavior.
155166

156167
### Go 1.23
157168

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Calls to the deprecated top-level [Seed] function no longer have any effect. To
2+
restore the old behavior set `GODEBUG=randseednop=0`. For more background see
3+
the proposal [#67273](/issue/67273).
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
The new [T.Chdir] and [B.Chdir] methods can be used to change the working
2+
directory for the duration of a test or benchmark.

src/bytes/bytes_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ func TestIndexRune(t *testing.T) {
489489
{"a☺b☻c☹d\xe2\x98\xff\xed\xa0\x80", 0xD800, -1}, // Surrogate pair
490490
{"a☺b☻c☹d\xe2\x98\xff\xed\xa0\x80", utf8.MaxRune + 1, -1},
491491

492-
// Test the cutover to to bytealg.Index when it is triggered in
492+
// Test the cutover to bytealg.Index when it is triggered in
493493
// the middle of rune that contains consecutive runs of equal bytes.
494494
{"aaaaaKKKK\U000bc104", '\U000bc104', 17}, // cutover: (n + 16) / 8
495495
{"aaaaaKKKK鄄", '鄄', 17},

src/cmd/cgo/doc.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,30 @@ passing uninitialized C memory to Go code if the Go code is going to
425425
store pointer values in it. Zero out the memory in C before passing it
426426
to Go.
427427
428+
# Optimizing calls of C code
429+
430+
When passing a Go pointer to a C function the compiler normally ensures
431+
that the Go object lives on the heap. If the C function does not keep
432+
a copy of the Go pointer, and never passes the Go pointer back to Go code,
433+
then this is unnecessary. The #cgo noescape directive may be used to tell
434+
the compiler that no Go pointers escape via the named C function.
435+
If the noescape directive is used and the C function does not handle the
436+
pointer safely, the program may crash or see memory corruption.
437+
438+
For example:
439+
440+
// #cgo noescape cFunctionName
441+
442+
When a Go function calls a C function, it prepares for the C function to
443+
call back to a Go function. The #cgo nocallback directive may be used to
444+
tell the compiler that these preparations are not necessary.
445+
If the nocallback directive is used and the C function does call back into
446+
Go code, the program will panic.
447+
448+
For example:
449+
450+
// #cgo nocallback cFunctionName
451+
428452
# Special cases
429453
430454
A few special C types which would normally be represented by a pointer

src/cmd/cgo/gcc.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,8 @@ func (f *File) ProcessCgoDirectives() {
9494
directive := fields[1]
9595
funcName := fields[2]
9696
if directive == "nocallback" {
97-
fatalf("#cgo nocallback disabled until Go 1.23")
9897
f.NoCallbacks[funcName] = true
9998
} else if directive == "noescape" {
100-
fatalf("#cgo noescape disabled until Go 1.23")
10199
f.NoEscapes[funcName] = true
102100
}
103101
}

src/cmd/cgo/internal/test/test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ int add(int x, int y) {
117117
118118
// escape vs noescape
119119
120-
// TODO(#56378): enable in Go 1.23:
121-
// #cgo noescape handleGoStringPointerNoescape
120+
#cgo noescape handleGoStringPointerNoescape
121+
#cgo nocallback handleGoStringPointerNoescape
122122
void handleGoStringPointerNoescape(void *s) {}
123123
124124
void handleGoStringPointerEscape(void *s) {}

src/cmd/cgo/internal/testerrors/testdata/notmatchedcfunction.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
package main
66

77
/*
8-
// TODO(#56378): change back to "#cgo noescape noMatchedCFunction: no matched C function" in Go 1.23
9-
// ERROR MESSAGE: #cgo noescape disabled until Go 1.23
8+
// ERROR MESSAGE: #cgo noescape noMatchedCFunction: no matched C function
109
#cgo noescape noMatchedCFunction
1110
*/
1211
import "C"

src/cmd/cgo/out.go

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ func (p *Package) writeDefs() {
104104
fmt.Fprintf(fgo2, "var _Cgo_always_false bool\n")
105105
fmt.Fprintf(fgo2, "//go:linkname _Cgo_use runtime.cgoUse\n")
106106
fmt.Fprintf(fgo2, "func _Cgo_use(interface{})\n")
107+
fmt.Fprintf(fgo2, "//go:linkname _Cgo_keepalive runtime.cgoKeepAlive\n")
108+
fmt.Fprintf(fgo2, "//go:noescape\n")
109+
fmt.Fprintf(fgo2, "func _Cgo_keepalive(interface{})\n")
107110
}
108111
fmt.Fprintf(fgo2, "//go:linkname _Cgo_no_callback runtime.cgoNoCallback\n")
109112
fmt.Fprintf(fgo2, "func _Cgo_no_callback(bool)\n")
@@ -639,17 +642,20 @@ func (p *Package) writeDefsFunc(fgo2 io.Writer, n *Name, callsMalloc *bool) {
639642
fmt.Fprintf(fgo2, "\t_Cgo_no_callback(false)\n")
640643
}
641644

642-
// skip _Cgo_use when noescape exist,
645+
// Use _Cgo_keepalive instead of _Cgo_use when noescape & nocallback exist,
643646
// so that the compiler won't force to escape them to heap.
644-
if !p.noEscapes[n.C] {
645-
fmt.Fprintf(fgo2, "\tif _Cgo_always_false {\n")
646-
if d.Type.Params != nil {
647-
for i := range d.Type.Params.List {
648-
fmt.Fprintf(fgo2, "\t\t_Cgo_use(p%d)\n", i)
649-
}
647+
// Instead, make the compiler keep them alive by using _Cgo_keepalive.
648+
touchFunc := "_Cgo_use"
649+
if p.noEscapes[n.C] && p.noCallbacks[n.C] {
650+
touchFunc = "_Cgo_keepalive"
651+
}
652+
fmt.Fprintf(fgo2, "\tif _Cgo_always_false {\n")
653+
if d.Type.Params != nil {
654+
for _, name := range paramnames {
655+
fmt.Fprintf(fgo2, "\t\t%s(%s)\n", touchFunc, name)
650656
}
651-
fmt.Fprintf(fgo2, "\t}\n")
652657
}
658+
fmt.Fprintf(fgo2, "\t}\n")
653659
fmt.Fprintf(fgo2, "\treturn\n")
654660
fmt.Fprintf(fgo2, "}\n")
655661
}

src/cmd/compile/internal/devirtualize/devirtualize.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func StaticCall(call *ir.CallExpr) {
6363
// dictionary parameter. We could devirtualize this call if we
6464
// could derive an appropriate dictionary argument.
6565
//
66-
// TODO(mdempsky): If typ has has a promoted non-generic method,
66+
// TODO(mdempsky): If typ has a promoted non-generic method,
6767
// then that method won't require a dictionary argument. We could
6868
// still devirtualize those calls.
6969
//

src/cmd/compile/internal/devirtualize/pgo.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ func maybeDevirtualizeFunctionCall(p *pgoir.Profile, fn *ir.Func, call *ir.CallE
242242
}
243243
// runtime.memhash_varlen does not look like a closure, but it uses
244244
// runtime.getclosureptr to access data encoded by callers, which are
245-
// are generated by cmd/compile/internal/reflectdata.genhash.
245+
// generated by cmd/compile/internal/reflectdata.genhash.
246246
if callee.Sym().Pkg.Path == "runtime" && callee.Sym().Name == "memhash_varlen" {
247247
if base.Debug.PGODebug >= 3 {
248248
fmt.Printf("callee %s is a closure (runtime.memhash_varlen), skipping\n", ir.FuncName(callee))

src/cmd/compile/internal/ir/reassignment.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import (
1818
// opposed to a new walk on every call).
1919
type ReassignOracle struct {
2020
fn *Func
21-
// maps candidate name to its defining assignment (or for
21+
// maps candidate name to its defining assignment (or
2222
// for params, defining func).
2323
singleDef map[*Name]Node
2424
}

src/cmd/compile/internal/liveness/intervals.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ func (c *IntervalsBuilder) Live(pos int) error {
168168
}
169169

170170
// Kill method should be invoked on instruction at position p if instr
171-
// should be treated as as having a kill (lifetime end) for the
171+
// should be treated as having a kill (lifetime end) for the
172172
// resource. See the example in the comment at the beginning of this
173173
// file for an example. Note that if we see a kill at position K for a
174174
// resource currently live since J, this will result in a lifetime

src/cmd/compile/internal/liveness/mergelocals.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,7 @@ func nextRegion(cands []*ir.Name, idx int) int {
682682
// given subrange of cands described by st and en (indices into our
683683
// candidate var list), where the variables within this range have
684684
// already been determined to be compatible with respect to type,
685-
// size, etc. Overlapping is done in a a greedy fashion: we select the
685+
// size, etc. Overlapping is done in a greedy fashion: we select the
686686
// first element in the st->en range, then walk the rest of the
687687
// elements adding in vars whose lifetimes don't overlap with the
688688
// first element, then repeat the process until we run out of work.

src/cmd/compile/internal/riscv64/ssa.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,8 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
288288
ssa.OpRISCV64FADDS, ssa.OpRISCV64FSUBS, ssa.OpRISCV64FMULS, ssa.OpRISCV64FDIVS,
289289
ssa.OpRISCV64FEQS, ssa.OpRISCV64FNES, ssa.OpRISCV64FLTS, ssa.OpRISCV64FLES,
290290
ssa.OpRISCV64FADDD, ssa.OpRISCV64FSUBD, ssa.OpRISCV64FMULD, ssa.OpRISCV64FDIVD,
291-
ssa.OpRISCV64FEQD, ssa.OpRISCV64FNED, ssa.OpRISCV64FLTD, ssa.OpRISCV64FLED,
292-
ssa.OpRISCV64FSGNJD:
291+
ssa.OpRISCV64FEQD, ssa.OpRISCV64FNED, ssa.OpRISCV64FLTD, ssa.OpRISCV64FLED, ssa.OpRISCV64FSGNJD,
292+
ssa.OpRISCV64MIN, ssa.OpRISCV64MAX, ssa.OpRISCV64MINU, ssa.OpRISCV64MAXU:
293293
r := v.Reg()
294294
r1 := v.Args[0].Reg()
295295
r2 := v.Args[1].Reg()

src/cmd/compile/internal/ssa/_gen/RISCV64.rules

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -834,3 +834,13 @@
834834
(F(MADD|NMADD|MSUB|NMSUB)S x y neg:(FNEGS z)) && neg.Uses == 1 => (F(MSUB|NMSUB|MADD|NMADD)S x y z)
835835
(F(MADD|NMADD|MSUB|NMSUB)D neg:(FNEGD x) y z) && neg.Uses == 1 => (F(NMSUB|MSUB|NMADD|MADD)D x y z)
836836
(F(MADD|NMADD|MSUB|NMSUB)D x y neg:(FNEGD z)) && neg.Uses == 1 => (F(MSUB|NMSUB|MADD|NMADD)D x y z)
837+
838+
//
839+
// Optimisations for rva22u64 and above.
840+
//
841+
842+
// Integer minimum and maximum.
843+
(Min64 x y) && buildcfg.GORISCV64 >= 22 => (MIN x y)
844+
(Max64 x y) && buildcfg.GORISCV64 >= 22 => (MAX x y)
845+
(Min64u x y) && buildcfg.GORISCV64 >= 22 => (MINU x y)
846+
(Max64u x y) && buildcfg.GORISCV64 >= 22 => (MAXU x y)

src/cmd/compile/internal/ssa/_gen/RISCV64Ops.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,12 @@ func init() {
235235
{name: "XOR", argLength: 2, reg: gp21, asm: "XOR", commutative: true}, // arg0 ^ arg1
236236
{name: "XORI", argLength: 1, reg: gp11, asm: "XORI", aux: "Int64"}, // arg0 ^ auxint
237237

238+
// Minimum and maximum
239+
{name: "MIN", argLength: 2, reg: gp21, asm: "MIN", commutative: true}, // min(arg0,arg1), signed
240+
{name: "MAX", argLength: 2, reg: gp21, asm: "MAX", commutative: true}, // max(arg0,arg1), signed
241+
{name: "MINU", argLength: 2, reg: gp21, asm: "MINU", commutative: true}, // min(arg0,arg1), unsigned
242+
{name: "MAXU", argLength: 2, reg: gp21, asm: "MAXU", commutative: true}, // max(arg0,arg1), unsigned
243+
238244
// Generate boolean values
239245
{name: "SEQZ", argLength: 1, reg: gp11, asm: "SEQZ"}, // arg0 == 0, result is 0 or 1
240246
{name: "SNEZ", argLength: 1, reg: gp11, asm: "SNEZ"}, // arg0 != 0, result is 0 or 1

src/cmd/compile/internal/ssa/_gen/genericOps.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,12 @@ var genericOps = []opData{
285285
{name: "Abs", argLength: 1}, // absolute value arg0
286286
{name: "Copysign", argLength: 2}, // copy sign from arg0 to arg1
287287

288+
// Integer min/max implementation, if hardware is available.
289+
{name: "Min64", argLength: 2}, // min(arg0,arg1), signed
290+
{name: "Max64", argLength: 2}, // max(arg0,arg1), signed
291+
{name: "Min64u", argLength: 2}, // min(arg0,arg1), unsigned
292+
{name: "Max64u", argLength: 2}, // max(arg0,arg1), unsigned
293+
288294
// Float min/max implementation, if hardware is available.
289295
{name: "Min64F", argLength: 2}, // min(arg0,arg1)
290296
{name: "Min32F", argLength: 2}, // min(arg0,arg1)

src/cmd/compile/internal/ssa/opGen.go

Lines changed: 88 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cmd/compile/internal/ssa/prove.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,7 @@ func (ft *factsTable) newLimit(v *Value, newLim limit) bool {
618618
// extract relation between its args. For example, if
619619
// We learn v is false, and v is defined as a<b, then we learn a>=b.
620620
if v.Type.IsBoolean() {
621-
// If we reach here, is is because we have a more restrictive
621+
// If we reach here, it is because we have a more restrictive
622622
// value for v than the default. The only two such values
623623
// are constant true or constant false.
624624
if lim.min != lim.max {

0 commit comments

Comments
 (0)