aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/export_test.go18
-rw-r--r--src/runtime/print.go20
-rw-r--r--src/runtime/print_test.go65
3 files changed, 99 insertions, 4 deletions
diff --git a/src/runtime/export_test.go b/src/runtime/export_test.go
index f71494174c..bc471e50a0 100644
--- a/src/runtime/export_test.go
+++ b/src/runtime/export_test.go
@@ -2084,6 +2084,24 @@ func DumpPrintQuoted(s string) string {
return string(buf)
}
+// DumpPrint returns the output of print(v).
+func DumpPrint[T any](v T) string {
+ gp := getg()
+ gp.writebuf = make([]byte, 0, 2048)
+ print(v)
+ buf := gp.writebuf
+ gp.writebuf = nil
+
+ return string(buf)
+}
+
+var (
+ Float64Bytes = float64Bytes
+ Float32Bytes = float32Bytes
+ Complex128Bytes = complex128Bytes
+ Complex64Bytes = complex64Bytes
+)
+
func GetScanAlloc() uintptr {
c := getMCache(getg().m)
return c.scanAlloc
diff --git a/src/runtime/print.go b/src/runtime/print.go
index c8ce96546d..3abdf17ad8 100644
--- a/src/runtime/print.go
+++ b/src/runtime/print.go
@@ -122,23 +122,35 @@ func printbool(v bool) {
}
}
+// float64 requires 1+17+1+1+1+3 = 24 bytes max (sign+digits+decimal point+e+sign+exponent digits).
+const float64Bytes = 24
+
func printfloat64(v float64) {
- var buf [20]byte
+ var buf [float64Bytes]byte
gwrite(strconv.AppendFloat(buf[:0], v, 'g', -1, 64))
}
+// float32 requires 1+9+1+1+1+2 = 15 bytes max (sign+digits+decimal point+e+sign+exponent digits).
+const float32Bytes = 15
+
func printfloat32(v float32) {
- var buf [20]byte
+ var buf [float32Bytes]byte
gwrite(strconv.AppendFloat(buf[:0], float64(v), 'g', -1, 32))
}
+// complex128 requires 24+24+1+1+1 = 51 bytes max (paren+float64+float64+i+paren).
+const complex128Bytes = 2*float64Bytes + 3
+
func printcomplex128(c complex128) {
- var buf [44]byte
+ var buf [complex128Bytes]byte
gwrite(strconv.AppendComplex(buf[:0], c, 'g', -1, 128))
}
+// complex64 requires 15+15+1+1+1 = 33 bytes max (paren+float32+float32+i+paren).
+const complex64Bytes = 2*float32Bytes + 3
+
func printcomplex64(c complex64) {
- var buf [44]byte
+ var buf [complex64Bytes]byte
gwrite(strconv.AppendComplex(buf[:0], complex128(c), 'g', -1, 64))
}
diff --git a/src/runtime/print_test.go b/src/runtime/print_test.go
new file mode 100644
index 0000000000..cfc27ed95b
--- /dev/null
+++ b/src/runtime/print_test.go
@@ -0,0 +1,65 @@
+// Copyright 2026 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 runtime_test
+
+import (
+ "math"
+ "runtime"
+ "testing"
+)
+
+func FuzzPrintFloat64(f *testing.F) {
+ f.Add(math.SmallestNonzeroFloat64)
+ f.Add(math.MaxFloat64)
+ f.Add(-1.7976931348623157e+308) // requires 24 digits
+
+ f.Fuzz(func(t *testing.T, v float64) {
+ s := runtime.DumpPrint(v)
+ if len(s) > runtime.Float64Bytes {
+ t.Errorf("print(%f) got %s (len %d) want len <= %d", v, s, len(s), runtime.Float64Bytes)
+ }
+ })
+}
+
+func FuzzPrintFloat32(f *testing.F) {
+ f.Add(float32(math.SmallestNonzeroFloat32))
+ f.Add(float32(math.MaxFloat32))
+ f.Add(float32(-1.06338233e+37)) // requires 15 digits
+
+ f.Fuzz(func(t *testing.T, v float32) {
+ s := runtime.DumpPrint(v)
+ if len(s) > runtime.Float32Bytes {
+ t.Errorf("print(%f) got %s (len %d) want len <= %d", v, s, len(s), runtime.Float32Bytes)
+ }
+ })
+}
+
+func FuzzPrintComplex128(f *testing.F) {
+ f.Add(math.SmallestNonzeroFloat64, math.SmallestNonzeroFloat64)
+ f.Add(math.MaxFloat64, math.MaxFloat64)
+ f.Add(-1.7976931348623157e+308, -1.7976931348623157e+308) // requires 51 digits
+
+ f.Fuzz(func(t *testing.T, r, i float64) {
+ v := complex(r, i)
+ s := runtime.DumpPrint(v)
+ if len(s) > runtime.Complex128Bytes {
+ t.Errorf("print(%f) got %s (len %d) want len <= %d", v, s, len(s), runtime.Complex128Bytes)
+ }
+ })
+}
+
+func FuzzPrintComplex64(f *testing.F) {
+ f.Add(float32(math.SmallestNonzeroFloat32), float32(math.SmallestNonzeroFloat32))
+ f.Add(float32(math.MaxFloat32), float32(math.MaxFloat32))
+ f.Add(float32(-1.06338233e+37), float32(-1.06338233e+37)) // requires 33 digits
+
+ f.Fuzz(func(t *testing.T, r, i float32) {
+ v := complex(r, i)
+ s := runtime.DumpPrint(v)
+ if len(s) > runtime.Complex64Bytes {
+ t.Errorf("print(%f) got %s (len %d) want len <= %d", v, s, len(s), runtime.Complex64Bytes)
+ }
+ })
+}