aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitri Shuralyov <dmitshur@google.com>2022-08-01 15:54:13 +0000
committerDmitri Shuralyov <dmitshur@google.com>2022-08-01 15:54:13 +0000
commit349da2d42d3193af7f54170ae842166e4571134a (patch)
treea0b59dc2dfa4440add9d954efe1908272933247a
parent7d5078e3bf2d865526e8ec2d211f61b2fac2936f (diff)
parent15da892a4950a4caac987ee72c632436329f62d5 (diff)
downloadgo-dev.boringcrypto.go1.17.tar.gz
go-dev.boringcrypto.go1.17.zip
[dev.boringcrypto.go1.17] all: merge go1.17.13 into dev.boringcrypto.go1.17dev.boringcrypto.go1.17
Change-Id: Iaf4f2cb506aab9e22a5df5b937c38fc108f1e1c1
-rw-r--r--src/cmd/compile/internal/ssa/loopbce.go7
-rw-r--r--src/cmd/compile/internal/walk/complit.go8
-rw-r--r--src/math/big/floatmarsh.go7
-rw-r--r--src/math/big/floatmarsh_test.go12
-rw-r--r--src/math/big/ratmarsh.go6
-rw-r--r--src/math/big/ratmarsh_test.go12
-rw-r--r--src/runtime/time.go12
-rw-r--r--src/runtime/traceback.go15
-rw-r--r--test/fixedbugs/issue52953.go29
-rw-r--r--test/fixedbugs/issue53600.go42
-rw-r--r--test/fixedbugs/issue53600.out8
11 files changed, 153 insertions, 5 deletions
diff --git a/src/cmd/compile/internal/ssa/loopbce.go b/src/cmd/compile/internal/ssa/loopbce.go
index 5a4bc1d60a..fd03efb417 100644
--- a/src/cmd/compile/internal/ssa/loopbce.go
+++ b/src/cmd/compile/internal/ssa/loopbce.go
@@ -159,6 +159,13 @@ func findIndVar(f *Func) []indVar {
step = -step
}
+ if flags&indVarMaxInc != 0 && max.Op == OpConst64 && max.AuxInt+step < max.AuxInt {
+ // For a <= comparison, we need to make sure that a value equal to
+ // max can be incremented without overflowing.
+ // (For a < comparison, the %step check below ensures no overflow.)
+ continue
+ }
+
// Up to now we extracted the induction variable (ind),
// the increment delta (inc), the temporary sum (nxt),
// the mininum value (min) and the maximum value (max).
diff --git a/src/cmd/compile/internal/walk/complit.go b/src/cmd/compile/internal/walk/complit.go
index abd920d646..1f288d21c1 100644
--- a/src/cmd/compile/internal/walk/complit.go
+++ b/src/cmd/compile/internal/walk/complit.go
@@ -621,6 +621,12 @@ func oaslit(n *ir.AssignStmt, init *ir.Nodes) bool {
// not a special composite literal assignment
return false
}
+ if x.Addrtaken() {
+ // If x is address-taken, the RHS may (implicitly) uses LHS.
+ // Not safe to do a special composite literal assignment
+ // (which may expand to multiple assignments).
+ return false
+ }
switch n.Y.Op() {
default:
@@ -629,7 +635,7 @@ func oaslit(n *ir.AssignStmt, init *ir.Nodes) bool {
case ir.OSTRUCTLIT, ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT:
if ir.Any(n.Y, func(y ir.Node) bool { return ir.Uses(y, x) }) {
- // not a special composite literal assignment
+ // not safe to do a special composite literal assignment if RHS uses LHS.
return false
}
anylit(n.Y, n.X, init)
diff --git a/src/math/big/floatmarsh.go b/src/math/big/floatmarsh.go
index d1c1dab069..990e085abe 100644
--- a/src/math/big/floatmarsh.go
+++ b/src/math/big/floatmarsh.go
@@ -8,6 +8,7 @@ package big
import (
"encoding/binary"
+ "errors"
"fmt"
)
@@ -67,6 +68,9 @@ func (z *Float) GobDecode(buf []byte) error {
*z = Float{}
return nil
}
+ if len(buf) < 6 {
+ return errors.New("Float.GobDecode: buffer too small")
+ }
if buf[0] != floatGobVersion {
return fmt.Errorf("Float.GobDecode: encoding version %d not supported", buf[0])
@@ -83,6 +87,9 @@ func (z *Float) GobDecode(buf []byte) error {
z.prec = binary.BigEndian.Uint32(buf[2:])
if z.form == finite {
+ if len(buf) < 10 {
+ return errors.New("Float.GobDecode: buffer too small for finite form float")
+ }
z.exp = int32(binary.BigEndian.Uint32(buf[6:]))
z.mant = z.mant.setBytes(buf[10:])
}
diff --git a/src/math/big/floatmarsh_test.go b/src/math/big/floatmarsh_test.go
index c056d78b80..401f45a51f 100644
--- a/src/math/big/floatmarsh_test.go
+++ b/src/math/big/floatmarsh_test.go
@@ -137,3 +137,15 @@ func TestFloatJSONEncoding(t *testing.T) {
}
}
}
+
+func TestFloatGobDecodeShortBuffer(t *testing.T) {
+ for _, tc := range [][]byte{
+ []byte{0x1, 0x0, 0x0, 0x0},
+ []byte{0x1, 0xfa, 0x0, 0x0, 0x0, 0x0},
+ } {
+ err := NewFloat(0).GobDecode(tc)
+ if err == nil {
+ t.Error("expected GobDecode to return error for malformed input")
+ }
+ }
+}
diff --git a/src/math/big/ratmarsh.go b/src/math/big/ratmarsh.go
index fbc7b6002d..56102e845b 100644
--- a/src/math/big/ratmarsh.go
+++ b/src/math/big/ratmarsh.go
@@ -45,12 +45,18 @@ func (z *Rat) GobDecode(buf []byte) error {
*z = Rat{}
return nil
}
+ if len(buf) < 5 {
+ return errors.New("Rat.GobDecode: buffer too small")
+ }
b := buf[0]
if b>>1 != ratGobVersion {
return fmt.Errorf("Rat.GobDecode: encoding version %d not supported", b>>1)
}
const j = 1 + 4
i := j + binary.BigEndian.Uint32(buf[j-4:j])
+ if len(buf) < int(i) {
+ return errors.New("Rat.GobDecode: buffer too small")
+ }
z.a.neg = b&1 != 0
z.a.abs = z.a.abs.setBytes(buf[j:i])
z.b.abs = z.b.abs.setBytes(buf[i:])
diff --git a/src/math/big/ratmarsh_test.go b/src/math/big/ratmarsh_test.go
index 351d109f8d..55a9878bb8 100644
--- a/src/math/big/ratmarsh_test.go
+++ b/src/math/big/ratmarsh_test.go
@@ -123,3 +123,15 @@ func TestRatXMLEncoding(t *testing.T) {
}
}
}
+
+func TestRatGobDecodeShortBuffer(t *testing.T) {
+ for _, tc := range [][]byte{
+ []byte{0x2},
+ []byte{0x2, 0x0, 0x0, 0x0, 0xff},
+ } {
+ err := NewRat(1, 2).GobDecode(tc)
+ if err == nil {
+ t.Error("expected GobDecode to return error for malformed input")
+ }
+ }
+}
diff --git a/src/runtime/time.go b/src/runtime/time.go
index 517a493a70..70e21d4482 100644
--- a/src/runtime/time.go
+++ b/src/runtime/time.go
@@ -390,7 +390,11 @@ func dodeltimer(pp *p, i int) int {
if i == 0 {
updateTimer0When(pp)
}
- atomic.Xadd(&pp.numTimers, -1)
+ n := atomic.Xadd(&pp.numTimers, -1)
+ if n == 0 {
+ // If there are no timers, then clearly none are modified.
+ atomic.Store64(&pp.timerModifiedEarliest, 0)
+ }
return smallestChanged
}
@@ -414,7 +418,11 @@ func dodeltimer0(pp *p) {
siftdownTimer(pp.timers, 0)
}
updateTimer0When(pp)
- atomic.Xadd(&pp.numTimers, -1)
+ n := atomic.Xadd(&pp.numTimers, -1)
+ if n == 0 {
+ // If there are no timers, then clearly none are modified.
+ atomic.Store64(&pp.timerModifiedEarliest, 0)
+ }
}
// modtimer modifies an existing timer.
diff --git a/src/runtime/traceback.go b/src/runtime/traceback.go
index 814c323634..de593491a1 100644
--- a/src/runtime/traceback.go
+++ b/src/runtime/traceback.go
@@ -116,6 +116,7 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
}
waspanic := false
cgoCtxt := gp.cgoCtxt
+ stack := gp.stack
printing := pcbuf == nil && callback == nil
// If the PC is zero, it's likely a nil function call.
@@ -134,7 +135,7 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
if !f.valid() {
if callback != nil || printing {
print("runtime: unknown pc ", hex(frame.pc), "\n")
- tracebackHexdump(gp.stack, &frame, 0)
+ tracebackHexdump(stack, &frame, 0)
}
if callback != nil {
throw("unknown pc")
@@ -194,12 +195,15 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
frame.fn = findfunc(frame.pc)
f = frame.fn
flag = f.flag
+ frame.lr = gp.m.curg.sched.lr
frame.sp = gp.m.curg.sched.sp
+ stack = gp.m.curg.stack
cgoCtxt = gp.m.curg.cgoCtxt
case funcID_systemstack:
// systemstack returns normally, so just follow the
// stack transition.
frame.sp = gp.m.curg.sched.sp
+ stack = gp.m.curg.stack
cgoCtxt = gp.m.curg.cgoCtxt
flag &^= funcFlag_SPWRITE
}
@@ -268,7 +272,7 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
}
if callback != nil || doPrint {
print("runtime: unexpected return pc for ", funcname(f), " called from ", hex(frame.lr), "\n")
- tracebackHexdump(gp.stack, &frame, lrPtr)
+ tracebackHexdump(stack, &frame, lrPtr)
}
if callback != nil {
throw("unknown caller pc")
@@ -497,6 +501,13 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
break
}
+ if frame.pc == frame.lr && frame.sp == frame.fp {
+ // If the next frame is identical to the current frame, we cannot make progress.
+ print("runtime: traceback stuck. pc=", hex(frame.pc), " sp=", hex(frame.sp), "\n")
+ tracebackHexdump(stack, &frame, frame.sp)
+ throw("traceback stuck")
+ }
+
// Unwind to next frame.
frame.fn = flr
frame.pc = frame.lr
diff --git a/test/fixedbugs/issue52953.go b/test/fixedbugs/issue52953.go
new file mode 100644
index 0000000000..2085e4e3fe
--- /dev/null
+++ b/test/fixedbugs/issue52953.go
@@ -0,0 +1,29 @@
+// run
+
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 52953: miscompilation for composite literal assignment
+// when LHS is address-taken.
+
+package main
+
+type T struct {
+ Field1 bool
+}
+
+func main() {
+ var ret T
+ ret.Field1 = true
+ var v *bool = &ret.Field1
+ ret = T{Field1: *v}
+ check(ret.Field1)
+}
+
+//go:noinline
+func check(b bool) {
+ if !b {
+ panic("FAIL")
+ }
+}
diff --git a/test/fixedbugs/issue53600.go b/test/fixedbugs/issue53600.go
new file mode 100644
index 0000000000..fd3a9e5e47
--- /dev/null
+++ b/test/fixedbugs/issue53600.go
@@ -0,0 +1,42 @@
+// run
+
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "math"
+
+func main() {
+ f()
+ g()
+ h()
+}
+func f() {
+ for i := int64(math.MaxInt64); i <= math.MaxInt64; i++ {
+ if i < 0 {
+ println("done")
+ return
+ }
+ println(i, i < 0)
+ }
+}
+func g() {
+ for i := int64(math.MaxInt64) - 1; i <= math.MaxInt64; i++ {
+ if i < 0 {
+ println("done")
+ return
+ }
+ println(i, i < 0)
+ }
+}
+func h() {
+ for i := int64(math.MaxInt64) - 2; i <= math.MaxInt64; i += 2 {
+ if i < 0 {
+ println("done")
+ return
+ }
+ println(i, i < 0)
+ }
+}
diff --git a/test/fixedbugs/issue53600.out b/test/fixedbugs/issue53600.out
new file mode 100644
index 0000000000..5590c7dcfb
--- /dev/null
+++ b/test/fixedbugs/issue53600.out
@@ -0,0 +1,8 @@
+9223372036854775807 false
+done
+9223372036854775806 false
+9223372036854775807 false
+done
+9223372036854775805 false
+9223372036854775807 false
+done