Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
840d86c
[release-branch.go1.26] runtime: fix printfloat, printcomplex buffer …
prattmic Feb 27, 2026
1368bc2
[release-branch.go1.26] cmd/compile: fix bloop test
randall77 Mar 3, 2026
ace2cf6
[release-branch.go1.26] cmd/compile/internal/typecheck: simplify tcSl…
cuonglm Mar 3, 2026
99df9bd
[release-branch.go1.26] net: correctly handle non-nil empty cmsg buff…
database64128 Mar 1, 2026
ba8c3d0
[release-branch.go1.26] net/http: restore accidentally removed packag…
neild Mar 4, 2026
2b01132
[release-branch.go1.26] runtime/poll: fix race condition in Window's …
qmuntal Mar 8, 2026
e29f355
[release-branch.go1.26] cmd/go/internal/cache: update trim timestamp …
matloob Mar 9, 2026
3bf3014
[release-branch.go1.26] test/convert5: skip mipsle
Rongronggg9 Feb 10, 2026
1a44be4
[release-branch.go1.26] internal/poll: move rsan to heap on windows
database64128 Mar 9, 2026
943235a
[release-branch.go1.26] builtin: update new function comment
siutsin Feb 18, 2026
12bf7d8
[release-branch.go1.26] builtin: incorporate all feedback into doc st…
cixtor Feb 25, 2026
26548d4
[release-branch.go1.26] cmd/fix: pull in CL 755980
dmitshur Mar 23, 2026
895fbae
[release-branch.go1.26] doc: remove template use in godebug.md
dmitshur Mar 18, 2026
08edcb8
[release-branch.go1.26] test/fixedbugs: remove issue46234 test timeout
qmuntal Feb 20, 2026
9fe1db7
[release-branch.go1.26] runtime: fix value of ENOSYS on mips from 38 …
Jorropo Feb 22, 2026
68f42c5
[release-branch.go1.26] cmd/compile: gate instrumentEnterExit on NoRa…
derekparker Feb 23, 2026
f14d3a8
[release-branch.go1.26] cmd/compile: skip race detector test failure …
abner-chenc Mar 19, 2026
82b95c1
[release-branch.go1.26] cmd/compile: ternary rewrite of rewrite shoul…
dr2chase Feb 25, 2026
3206e14
[release-branch.go1.26] net/url: reattach package doc comment
neild Mar 24, 2026
cce667a
[release-branch.go1.26] cmd/compile: handle zero-sized values more ge…
randall77 Feb 17, 2026
98d4c11
[release-branch.go1.26] cmd/compile: treat all zero-sized values as S…
randall77 Feb 20, 2026
e27183e
[release-branch.go1.26] cmd/compile: fix internal compiler error: bad…
francisco3ferraz Feb 26, 2026
608303d
[release-branch.go1.26] cmd/link: skip special symbols for label symb…
cherrymui Mar 17, 2026
4ef2787
[release-branch.go1.26] runtime/race: apply LLVM zero-initialization fix
prattmic Mar 18, 2026
8028a51
[release-branch.go1.26] crypto/x509: hoist policy pruning out of loop
rolandshoemaker Mar 23, 2026
7b4ed1d
[release-branch.go1.26] crypto/x509: fix signature checking limit
rolandshoemaker Mar 5, 2026
917949c
[release-branch.go1.26] net/url: permit colons in the host subcompone…
neild Mar 26, 2026
b6176f4
[release-branch.go1.26] internal/syscall/unix: properly support AT_SY…
neild Mar 23, 2026
babb1c3
[release-branch.go1.26] html/template: properly track JS template lit…
rolandshoemaker Mar 23, 2026
ceb4da6
[release-branch.go1.26] crypto/x509: fix wildcard constraint map case…
rolandshoemaker Mar 23, 2026
3a4577a
[release-branch.go1.26] cmd/compile: fix mem access overlap detection
JunyangShao Mar 12, 2026
c4b4bd7
[release-branch.go1.26] cmd/compile: fix loopbce overflow check logic
JunyangShao Mar 6, 2026
a34b5e4
[release-branch.go1.26] archive/tar: limit the number of old GNU spar…
neild Mar 23, 2026
7cafb41
[release-branch.go1.26] crypto/tls: prevent deadlock when client send…
rolandshoemaker Mar 23, 2026
096f21b
[release-branch.go1.26] cmd/go: disallow cgo trust boundary bypass
thatnealpatel Feb 24, 2026
9c8bf0e
[release-branch.go1.26] go1.26.2
gopherbot Apr 7, 2026
dfe2a5f
Merge tag 'go1.26.2' of github.com:golang/go into bradfitz/go1.26.2
bradfitz Apr 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions VERSION
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
go1.26.1
time 2026-03-05T20:45:11Z
go1.26.2
time 2026-03-27T21:58:29Z
2 changes: 0 additions & 2 deletions doc/godebug.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,7 @@ are also treated as invalid.
The defaults that will be compiled into a main package
are reported by the command:

{{raw `
go list -f '{{.DefaultGODEBUG}}' my/main/package
`}}

Only differences from the base Go toolchain defaults are reported.

Expand Down
6 changes: 6 additions & 0 deletions src/archive/tar/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,12 @@ const (
// Max length of a special file (PAX header, GNU long name or link).
// This matches the limit used by libarchive.
maxSpecialFileSize = 1 << 20

// Maximum number of sparse file entries.
// We should never actually hit this limit
// (every sparse encoding will first be limited by maxSpecialFileSize),
// but this adds an additional layer of defense.
maxSparseFileEntries = 1 << 20
)

// blockPadding computes the number of bytes needed to pad offset up to the
Expand Down
28 changes: 24 additions & 4 deletions src/archive/tar/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,8 @@ func (tr *Reader) readOldGNUSparseMap(hdr *Header, blk *block) (sparseDatas, err
}
s := blk.toGNU().sparse()
spd := make(sparseDatas, 0, s.maxEntries())
for {
totalSize := len(s)
for totalSize < maxSpecialFileSize {
for i := 0; i < s.maxEntries(); i++ {
// This termination condition is identical to GNU and BSD tar.
if s.entry(i).offset()[0] == 0x00 {
Expand All @@ -501,7 +502,11 @@ func (tr *Reader) readOldGNUSparseMap(hdr *Header, blk *block) (sparseDatas, err
if p.err != nil {
return nil, p.err
}
spd = append(spd, sparseEntry{Offset: offset, Length: length})
var err error
spd, err = appendSparseEntry(spd, sparseEntry{Offset: offset, Length: length})
if err != nil {
return nil, err
}
}

if s.isExtended()[0] > 0 {
Expand All @@ -510,10 +515,12 @@ func (tr *Reader) readOldGNUSparseMap(hdr *Header, blk *block) (sparseDatas, err
return nil, err
}
s = blk.toSparse()
totalSize += len(s)
continue
}
return spd, nil // Done
}
return nil, errSparseTooLong
}

// readGNUSparseMap1x0 reads the sparse map as stored in GNU's PAX sparse format
Expand Down Expand Up @@ -586,7 +593,10 @@ func readGNUSparseMap1x0(r io.Reader) (sparseDatas, error) {
if err1 != nil || err2 != nil {
return nil, ErrHeader
}
spd = append(spd, sparseEntry{Offset: offset, Length: length})
spd, err = appendSparseEntry(spd, sparseEntry{Offset: offset, Length: length})
if err != nil {
return nil, err
}
}
return spd, nil
}
Expand Down Expand Up @@ -620,12 +630,22 @@ func readGNUSparseMap0x1(paxHdrs map[string]string) (sparseDatas, error) {
if err1 != nil || err2 != nil {
return nil, ErrHeader
}
spd = append(spd, sparseEntry{Offset: offset, Length: length})
spd, err = appendSparseEntry(spd, sparseEntry{Offset: offset, Length: length})
if err != nil {
return nil, err
}
sparseMap = sparseMap[2:]
}
return spd, nil
}

func appendSparseEntry(spd sparseDatas, ent sparseEntry) (sparseDatas, error) {
if len(spd) >= maxSparseFileEntries {
return nil, errSparseTooLong
}
return append(spd, ent), nil
}

// Read reads from the current file in the tar archive.
// It returns (0, io.EOF) when it reaches the end of that file,
// until [Next] is called to advance to the next file.
Expand Down
11 changes: 11 additions & 0 deletions src/archive/tar/reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1145,6 +1145,17 @@ func TestReadOldGNUSparseMap(t *testing.T) {
input: makeInput(FormatGNU, "",
makeSparseStrings(sparseDatas{{10 << 30, 512}, {20 << 30, 512}})...),
wantMap: sparseDatas{{10 << 30, 512}, {20 << 30, 512}},
}, {
input: makeInput(FormatGNU, "",
makeSparseStrings(func() sparseDatas {
var datas sparseDatas
// This is more than enough entries to exceed our limit.
for i := range int64(1 << 20) {
datas = append(datas, sparseEntry{i * 2, (i * 2) + 1})
}
return datas
}())...),
wantErr: errSparseTooLong,
}}

for i, v := range vectors {
Expand Down
17 changes: 13 additions & 4 deletions src/builtin/builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ type Type int
// invocation.
type Type1 int

// TypeOrExpr is here for the purposes of documentation only. It is a stand-in
// for either a Go type or an expression.
type TypeOrExpr int

// IntegerType is here for the purposes of documentation only. It is a stand-in
// for any integer type: int, uint, int8 etc.
type IntegerType int
Expand Down Expand Up @@ -220,10 +224,15 @@ func max[T cmp.Ordered](x T, y ...T) T
// min will return NaN.
func min[T cmp.Ordered](x T, y ...T) T

// The new built-in function allocates memory. The first argument is a type,
// not a value, and the value returned is a pointer to a newly
// allocated zero value of that type.
func new(Type) *Type
// The built-in function new allocates a new, initialized variable and returns
// a pointer to it. It accepts a single argument, which may be either a type
// or an expression.
// If the argument is a type T, then new(T) allocates a variable of type T
// initialized to its zero value.
// Otherwise, the argument is an expression x and new(x) allocates a variable
// of the type of x initialized to the value of x. If that value is an untyped
// constant, it is first implicitly converted to its default type.
func new(TypeOrExpr) *Type

// The complex built-in function constructs a complex value from two
// floating-point values. The real and imaginary parts must be of the same
Expand Down
6 changes: 3 additions & 3 deletions src/cmd/compile/internal/bloop/bloop.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ func preserveStmt(curFn *ir.Func, stmt ir.Node) (ret ir.Node) {
if name != nil {
debugName(name, n.Pos())
ret = keepAliveAt([]ir.Node{name}, n)
} else if deref := n.X.(*ir.StarExpr); deref != nil {
} else if deref, ok := n.X.(*ir.StarExpr); ok && deref != nil {
ret = keepAliveAt([]ir.Node{deref}, n)
if base.Flag.LowerM > 1 {
base.WarnfAt(n.Pos(), "dereference will be kept alive")
Expand All @@ -159,7 +159,7 @@ func preserveStmt(curFn *ir.Func, stmt ir.Node) (ret ir.Node) {
if name != nil {
debugName(name, n.Pos())
ns = append(ns, name)
} else if deref := lhs.(*ir.StarExpr); deref != nil {
} else if deref, ok := lhs.(*ir.StarExpr); ok && deref != nil {
ns = append(ns, deref)
if base.Flag.LowerM > 1 {
base.WarnfAt(n.Pos(), "dereference will be kept alive")
Expand All @@ -174,7 +174,7 @@ func preserveStmt(curFn *ir.Func, stmt ir.Node) (ret ir.Node) {
if name != nil {
debugName(name, n.Pos())
ret = keepAliveAt([]ir.Node{name}, n)
} else if deref := n.X.(*ir.StarExpr); deref != nil {
} else if deref, ok := n.X.(*ir.StarExpr); ok && deref != nil {
ret = keepAliveAt([]ir.Node{deref}, n)
if base.Flag.LowerM > 1 {
base.WarnfAt(n.Pos(), "dereference will be kept alive")
Expand Down
3 changes: 1 addition & 2 deletions src/cmd/compile/internal/ssa/_gen/dec.rules
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,7 @@

(IMake _typ (StructMake ___)) => imakeOfStructMake(v)
(StructSelect (IData x)) && v.Type.Size() > 0 => (IData x)
(StructSelect (IData x)) && v.Type.Size() == 0 && v.Type.IsStruct() => (StructMake)
(StructSelect (IData x)) && v.Type.Size() == 0 && v.Type.IsArray() => (ArrayMake0)
(StructSelect (IData x)) && v.Type.Size() == 0 => (Empty)

(StructSelect [i] x:(StructMake ___)) => x.Args[i]

Expand Down
13 changes: 6 additions & 7 deletions src/cmd/compile/internal/ssa/_gen/generic.rules
Original file line number Diff line number Diff line change
Expand Up @@ -941,7 +941,7 @@

// struct operations
(StructSelect [i] x:(StructMake ___)) => x.Args[i]
(Load <t> _ _) && t.IsStruct() && CanSSA(t) && !t.IsSIMD() => rewriteStructLoad(v)
(Load <t> _ _) && t.IsStruct() && t.Size() > 0 && CanSSA(t) && !t.IsSIMD() => rewriteStructLoad(v)
(Store _ (StructMake ___) _) => rewriteStructStore(v)

(StructSelect [i] x:(Load <t> ptr mem)) && !CanSSA(t) =>
Expand All @@ -950,8 +950,7 @@
// Putting struct{*byte} and similar into direct interfaces.
(IMake _typ (StructMake ___)) => imakeOfStructMake(v)
(StructSelect (IData x)) && v.Type.Size() > 0 => (IData x)
(StructSelect (IData x)) && v.Type.Size() == 0 && v.Type.IsStruct() => (StructMake)
(StructSelect (IData x)) && v.Type.Size() == 0 && v.Type.IsArray() => (ArrayMake0)
(StructSelect (IData x)) && v.Type.Size() == 0 => (Empty)

// un-SSAable values use mem->mem copies
(Store {t} dst (Load src mem) mem) && !CanSSA(t) =>
Expand All @@ -962,19 +961,19 @@
// array ops
(ArraySelect (ArrayMake1 x)) => x

(Load <t> _ _) && t.IsArray() && t.NumElem() == 0 =>
(ArrayMake0)

(Load <t> ptr mem) && t.IsArray() && t.NumElem() == 1 && CanSSA(t) =>
(ArrayMake1 (Load <t.Elem()> ptr mem))

(Store _ (ArrayMake0) mem) => mem
(Store dst (ArrayMake1 e) mem) => (Store {e.Type} dst e mem)

// Putting [1]*byte and similar into direct interfaces.
(IMake _typ (ArrayMake1 val)) => (IMake _typ val)
(ArraySelect [0] (IData x)) => (IData x)

// zero-sized values.
(Load <t> _ _) && t.Size() == 0 => (Empty)
(Store _ (Empty) mem) => mem

// string ops
// Decomposing StringMake and lowering of StringPtr and StringLen
// happens in a later pass, dec, so that these operations are available
Expand Down
8 changes: 5 additions & 3 deletions src/cmd/compile/internal/ssa/_gen/genericOps.go
Original file line number Diff line number Diff line change
Expand Up @@ -537,12 +537,11 @@ var genericOps = []opData{
{name: "IData", argLength: 1}, // arg0=interface, returns data field

// Structs
{name: "StructMake", argLength: -1}, // args...=field0..n-1. Returns struct with n fields.
{name: "StructMake", argLength: -1}, // args...=field0..n-1. Returns struct with n fields. Must have >0 size (use Empty otherwise).
{name: "StructSelect", argLength: 1, aux: "Int64"}, // arg0=struct, auxint=field index. Returns the auxint'th field.

// Arrays
{name: "ArrayMake0"}, // Returns array with 0 elements
{name: "ArrayMake1", argLength: 1}, // Returns array with 1 element
{name: "ArrayMake1", argLength: 1}, // Returns array with 1 element. Use Empty if the element is zero-sized.
{name: "ArraySelect", argLength: 1, aux: "Int64"}, // arg0=array, auxint=index. Returns a[i].

// Spill&restore ops for the register allocator. These are
Expand Down Expand Up @@ -682,6 +681,9 @@ var genericOps = []opData{
// Helper instruction which is semantically equivalent to calling runtime.memequal, but some targets may prefer to custom lower it later, e.g. for specific constant sizes.
{name: "MemEq", argLength: 4, commutative: true, typ: "Bool"}, // arg0=ptr0, arg1=ptr1, arg2=size, arg3=memory.

// Value of a zero-sized type.
{name: "Empty", argLength: 0},

// SIMD
{name: "ZeroSIMD", argLength: 0}, // zero value of a vector

Expand Down
4 changes: 4 additions & 0 deletions src/cmd/compile/internal/ssa/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,10 @@ func checkFunc(f *Func) {
}
}

if (v.Op == OpStructMake || v.Op == OpArrayMake1) && v.Type.Size() == 0 {
f.Fatalf("zero-sized Make; use Empty instead %v", v)
}

if f.RegAlloc != nil && f.Config.SoftFloat && v.Type.IsFloat() {
f.Fatalf("unexpected floating-point type %v", v.LongString())
}
Expand Down
6 changes: 1 addition & 5 deletions src/cmd/compile/internal/ssa/copyelim.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,7 @@ func phielim(f *Func) {
// This is an early place in SSA where all values are examined.
// Rewrite all 0-sized Go values to remove accessors, dereferences, loads, etc.
if t := v.Type; (t.IsStruct() || t.IsArray()) && t.Size() == 0 {
if t.IsStruct() {
v.reset(OpStructMake)
} else {
v.reset(OpArrayMake0)
}
v.reset(OpEmpty)
}
// Modify all values so no arg (including args
// of OpCopy) is a copy.
Expand Down
10 changes: 7 additions & 3 deletions src/cmd/compile/internal/ssa/decompose.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ func decomposeUser(f *Func) {
// returned.
func decomposeUserArrayInto(f *Func, name *LocalSlot, slots []*LocalSlot) []*LocalSlot {
t := name.Type
if t.NumElem() == 0 {
if t.Size() == 0 {
// TODO(khr): Not sure what to do here. Probably nothing.
// Names for empty arrays aren't important.
return slots
Expand Down Expand Up @@ -362,6 +362,10 @@ func decomposeUserPhi(v *Value) {
// and then recursively decomposes the phis for each field.
func decomposeStructPhi(v *Value) {
t := v.Type
if t.Size() == 0 {
v.reset(OpEmpty)
return
}
n := t.NumFields()
fields := make([]*Value, 0, MaxStruct)
for i := 0; i < n; i++ {
Expand All @@ -385,8 +389,8 @@ func decomposeStructPhi(v *Value) {
// and then recursively decomposes the element phi.
func decomposeArrayPhi(v *Value) {
t := v.Type
if t.NumElem() == 0 {
v.reset(OpArrayMake0)
if t.Size() == 0 {
v.reset(OpEmpty)
return
}
if t.NumElem() != 1 {
Expand Down
8 changes: 1 addition & 7 deletions src/cmd/compile/internal/ssa/expand_calls.go
Original file line number Diff line number Diff line change
Expand Up @@ -508,13 +508,7 @@ func (x *expandState) rewriteSelectOrArg(pos src.XPos, b *Block, container, a, m

if at.Size() == 0 {
// For consistency, create these values even though they'll ultimately be unused
if at.IsArray() {
return makeOf(a, OpArrayMake0, nil)
}
if at.IsStruct() {
return makeOf(a, OpStructMake, nil)
}
return a
return makeOf(a, OpEmpty, nil)
}

sk := selKey{from: container, size: 0, offsetOrIndex: rc.storeOffset, typ: at}
Expand Down
Loading
Loading