Skip to content

Commit cb8ccea

Browse files
authored
Merge pull request #54 from golang/master
[pull] master from golang:master
2 parents c4e0131 + e28acf5 commit cb8ccea

12 files changed

Lines changed: 167 additions & 46 deletions

File tree

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

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3573,16 +3573,14 @@ func (s *state) exprCheckPtr(n ir.Node, checkPtrOK bool) *ssa.Value {
35733573
bound := n.X.Type().NumElem()
35743574
a := s.expr(n.X)
35753575
i := s.expr(n.Index)
3576+
len := s.constInt(types.Types[types.TINT], bound)
35763577
if bound == 0 {
3577-
// Bounds check will never succeed. Might as well
3578-
// use constants for the bounds check.
3579-
z := s.constInt(types.Types[types.TINT], 0)
3580-
s.boundsCheck(z, z, ssa.BoundsIndex, false)
3578+
// Bounds check will never succeed.
3579+
s.boundsCheck(i, len, ssa.BoundsIndex, false)
35813580
// The return value won't be live. In case bounds checks
35823581
// are turned off, load from (*T)(nil) to cause a segfault.
35833582
return s.load(n.Type(), s.constNil(n.Type().PtrTo()))
35843583
}
3585-
len := s.constInt(types.Types[types.TINT], bound)
35863584
s.boundsCheck(i, len, ssa.BoundsIndex, n.Bounded()) // checks i == 0
35873585
return s.newValue1I(ssa.OpArraySelect, n.Type(), 0, a)
35883586
}
@@ -4545,12 +4543,21 @@ func (s *state) assignWhichMayOverlap(left ir.Node, right *ssa.Value, deref bool
45454543

45464544
i := s.expr(left.Index) // index
45474545
if n == 0 {
4546+
_ = s.expr(left.X) // Evaluating left.X for any side-effects.
45484547
// The bounds check must fail. Might as well
45494548
// ignore the actual index and just use zeros.
45504549
z := s.constInt(types.Types[types.TINT], 0)
45514550
s.boundsCheck(z, z, ssa.BoundsIndex, false)
45524551
return
45534552
}
4553+
if t.Size() == 0 {
4554+
_ = s.expr(left.X) // Evaluating left.X for any side-effects.
4555+
// Generate bounds check for left, since this can happen
4556+
// for 0-size assignment case, see issue #79236.
4557+
len := s.constInt(types.Types[types.TINT], n)
4558+
s.boundsCheck(i, len, ssa.BoundsIndex, false)
4559+
return
4560+
}
45544561
if n != 1 {
45554562
// This can happen in weird, always-panics cases, like:
45564563
// var x [0][2]int
@@ -4560,11 +4567,8 @@ func (s *state) assignWhichMayOverlap(left ir.Node, right *ssa.Value, deref bool
45604567
// they are somewhere inside an outer [0].
45614568
// We can ignore the actual assignment, it is dynamically
45624569
// unreachable. See issue 77635.
4563-
return
4564-
}
4565-
if t.Size() == 0 {
4566-
len := s.constInt(types.Types[types.TINT], n)
4567-
s.boundsCheck(i, len, ssa.BoundsIndex, false)
4570+
// Still, evaluating left.X for any side-effects.
4571+
_ = s.expr(left.X)
45684572
return
45694573
}
45704574

@@ -5276,6 +5280,7 @@ func (s *state) addr(n ir.Node) *ssa.Value {
52765280
// &x[i], which will always panic when evaluated.
52775281
// We just return something reasonable in this case.
52785282
// It will be dynamically unreachable. See issue 77635.
5283+
s.boundsCheckArrayIndex(n)
52795284
return s.newValue1A(ssa.OpAddr, n.Type().PtrTo(), ir.Syms.Zerobase, s.sb)
52805285
}
52815286

@@ -5458,6 +5463,21 @@ func (s *state) nilCheck(ptr *ssa.Value) *ssa.Value {
54585463
return s.newValue2(ssa.OpNilCheck, ptr.Type, ptr, s.mem())
54595464
}
54605465

5466+
// boundsCheckArrayIndex generates bounds checking code for array indexing operations.
5467+
func (s *state) boundsCheckArrayIndex(n ir.Node) {
5468+
if n.Op() != ir.OINDEX {
5469+
return
5470+
}
5471+
nn := n.(*ir.IndexExpr)
5472+
typ := nn.X.Type()
5473+
if typ.IsArray() {
5474+
_ = s.expr(nn.X) // for side effects
5475+
idx := s.expr(nn.Index)
5476+
len := s.constInt(types.Types[types.TINT], typ.NumElem())
5477+
s.boundsCheck(idx, len, ssa.BoundsIndex, nn.Bounded())
5478+
}
5479+
}
5480+
54615481
// boundsCheck generates bounds checking code. Checks if 0 <= idx <[=] len, branches to exit if not.
54625482
// Starts a new block on return.
54635483
// On input, len must be converted to full int width and be nonnegative.

src/cmd/go/internal/base/base.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@ func Fatal(err error) {
175175
var exitStatus = 0
176176
var exitMu sync.Mutex
177177

178+
// SetExitStatus sets exit status to n if
179+
// n is higher than the current exit status.
178180
func SetExitStatus(n int) {
179181
exitMu.Lock()
180182
if exitStatus < n {
@@ -183,6 +185,7 @@ func SetExitStatus(n int) {
183185
exitMu.Unlock()
184186
}
185187

188+
// GetExitStatus reports the current exit status.
186189
func GetExitStatus() int {
187190
return exitStatus
188191
}

src/cmd/go/internal/tool/tool.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,13 @@ func runBuiltTool(toolName string, env, cmdline []string) error {
424424
fmt.Fprintf(os.Stderr, "go tool %s: %s\n", toolName, err)
425425
}
426426
if ok {
427-
base.SetExitStatus(e.ExitCode())
427+
n := e.ExitCode()
428+
if n == -1 {
429+
// If the tool was terminated by a signal,
430+
// set a non-zero exit status. See go.dev/issue/79540.
431+
n = 1
432+
}
433+
base.SetExitStatus(n)
428434
} else {
429435
base.SetExitStatus(1)
430436
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
[short] skip 'runs go build'
2+
[GOOS:plan9] skip 'signals differ on Plan 9'
3+
[GOOS:windows] skip 'os.Interrupt is not implemented on Windows'
4+
5+
! go tool interrupter
6+
stderr 'go tool interrupter: signal: interrupt'
7+
8+
-- go.mod --
9+
module example.com/interrupter
10+
11+
go 1.26.0
12+
13+
tool example.com/interrupter/cmd/interrupter
14+
15+
-- cmd/interrupter/main.go --
16+
package main
17+
18+
import "os"
19+
20+
func main() {
21+
p, err := os.FindProcess(os.Getpid())
22+
if err != nil {
23+
panic(err)
24+
}
25+
if err := p.Signal(os.Interrupt); err != nil {
26+
panic(err)
27+
}
28+
select {}
29+
}

src/debug/dwarf/buf.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,10 @@ func (b *buf) varint() (c uint64, bits uint) {
146146

147147
// Unsigned int is just a varint.
148148
func (b *buf) uint() uint64 {
149-
x, _ := b.varint()
149+
x, bits := b.varint()
150+
if bits == 0 {
151+
b.error("underflow")
152+
}
150153
return x
151154
}
152155

@@ -157,6 +160,9 @@ func (b *buf) int() int64 {
157160
if x&(1<<(bits-1)) != 0 {
158161
x |= -1 << bits
159162
}
163+
if bits == 0 {
164+
b.error("underflow")
165+
}
160166
return x
161167
}
162168

src/debug/dwarf/entry_test.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -267,9 +267,10 @@ func Test64Bit(t *testing.T) {
267267
}
268268

269269
for _, test := range tests {
270-
data, err := New(nil, nil, nil, test.info, nil, nil, nil, nil)
270+
data, err := New([]byte{0}, nil, nil, test.info, nil, nil, nil, nil)
271271
if err != nil {
272272
t.Errorf("%s: %v", test.name, err)
273+
continue
273274
}
274275

275276
r := data.Reader()
@@ -445,12 +446,17 @@ func TestIssue51758(t *testing.T) {
445446
}
446447

447448
func TestIssue52045(t *testing.T) {
448-
var abbrev, aranges, frame, line, pubnames, ranges, str []byte
449+
var aranges, frame, line, pubnames, ranges, str []byte
450+
abbrev := []byte{0}
449451
info := []byte{0x7, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}
450452

451453
// A hand-crafted input corresponding to a minimal-size
452454
// .debug_info (header only, no DIEs) and an empty abbrev table.
453-
data0, _ := New(abbrev, aranges, frame, info, line, pubnames, ranges, str)
455+
data0, err := New(abbrev, aranges, frame, info, line, pubnames, ranges, str)
456+
if err != nil {
457+
t.Fatal(err)
458+
}
459+
454460
reader0 := data0.Reader()
455461
entry0, _ := reader0.SeekPC(0x0)
456462
// main goal is to make sure we can get here without crashing

src/debug/dwarf/line_test.go

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -431,32 +431,3 @@ func TestPathJoin(t *testing.T) {
431431
}
432432
}
433433
}
434-
435-
func TestPathLineReaderMalformed(t *testing.T) {
436-
// This test case drawn from issue #52354. What's happening
437-
// here is that the stmtList attribute in the compilation
438-
// unit is malformed (negative).
439-
var aranges, frame, pubnames, ranges, str []byte
440-
abbrev := []byte{0x10, 0x20, 0x20, 0x20, 0x21, 0x20, 0x10, 0x21, 0x61,
441-
0x0, 0x0, 0xff, 0x20, 0xff, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
442-
0x20, 0x20, 0x20, 0x20, 0x20, 0x20}
443-
info := []byte{0x0, 0x0, 0x0, 0x9, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0,
444-
0x20, 0x10, 0x10}
445-
line := []byte{0x20}
446-
Data0, err := New(abbrev, aranges, frame, info, line, pubnames, ranges, str)
447-
if err != nil {
448-
t.Fatalf("error unexpected: %v", err)
449-
}
450-
Reader0 := Data0.Reader()
451-
Entry0, err := Reader0.Next()
452-
if err != nil {
453-
t.Fatalf("error unexpected: %v", err)
454-
}
455-
LineReader0, err := Data0.LineReader(Entry0)
456-
if err == nil {
457-
t.Fatalf("expected error")
458-
}
459-
if LineReader0 != nil {
460-
t.Fatalf("expected nil line reader")
461-
}
462-
}

src/debug/elf/file.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ func NewFile(r io.ReaderAt) (*File, error) {
460460
// section header at index 0.
461461
if shstrndx == int(SHN_XINDEX) {
462462
shstrndx = int(link)
463-
if shstrndx < int(SHN_LORESERVE) {
463+
if shstrndx < int(SHN_LORESERVE) || shstrndx >= shnum {
464464
return nil, &FormatError{shoff, "invalid ELF shstrndx contained in sh_link", shstrndx}
465465
}
466466
}

src/encoding/gob/decode.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,12 @@ func decodeIntoValue(state *decoderState, op decOp, isPtr bool, value reflect.Va
594594
func (dec *Decoder) decodeMap(mtyp reflect.Type, state *decoderState, value reflect.Value, keyOp, elemOp decOp, ovfl error) {
595595
n := int(state.decodeUint())
596596
if value.IsNil() {
597+
// This is a map, not a slice, but capping the
598+
// size works either way.
599+
n = saferio.SliceCapWithSize(uint64(mtyp.Elem().Size()), uint64(n))
600+
if n < 0 {
601+
n = 1
602+
}
597603
value.Set(reflect.MakeMapWithSize(mtyp, n))
598604
}
599605
keyIsPtr := mtyp.Key().Kind() == reflect.Pointer

src/runtime/testdata/testprog/gc.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ func gcMemoryLimit(gcPercent int) {
396396
// should do considerably better than this bound.
397397
bound := int64(myLimit + 16<<20)
398398
if runtime.GOOS == "darwin" {
399-
bound += 24 << 20 // Be more lax on Darwin, see issue 73136.
399+
bound += 48 << 20 // Be more lax on Darwin, see issue 73136.
400400
}
401401
start := time.Now()
402402
for time.Since(start) < 200*time.Millisecond {

0 commit comments

Comments
 (0)