aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/fmt/fmt_test.go
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2014-06-06 22:37:27 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2014-06-06 22:37:27 +0000
commit6736ef96eab222e58e6294f42be981a5afb59811 (patch)
tree2bc668fae9bf96f9a3988e0b0a16685bde8c4f0b /libgo/go/fmt/fmt_test.go
parent38a138411da4206c53f9a153ee9c3624fce58a52 (diff)
downloadgcc-6736ef96eab222e58e6294f42be981a5afb59811.zip
gcc-6736ef96eab222e58e6294f42be981a5afb59811.tar.gz
gcc-6736ef96eab222e58e6294f42be981a5afb59811.tar.bz2
libgo: Merge to master revision 19184.
The next revision, 19185, renames several runtime files, and will be handled in a separate change. From-SVN: r211328
Diffstat (limited to 'libgo/go/fmt/fmt_test.go')
-rw-r--r--libgo/go/fmt/fmt_test.go90
1 files changed, 69 insertions, 21 deletions
diff --git a/libgo/go/fmt/fmt_test.go b/libgo/go/fmt/fmt_test.go
index 42b3c22..ce837ba 100644
--- a/libgo/go/fmt/fmt_test.go
+++ b/libgo/go/fmt/fmt_test.go
@@ -11,6 +11,7 @@ import (
"math"
"runtime"
"strings"
+ "sync/atomic"
"testing"
"time"
"unicode"
@@ -497,18 +498,18 @@ var fmtTests = []struct {
{"%v", map[float64]int{math.NaN(): 1, math.NaN(): 2}, "map[NaN:<nil> NaN:<nil>]"},
// Used to crash because nByte didn't allow for a sign.
- {"%b", int64(-1 << 63), "-1000000000000000000000000000000000000000000000000000000000000000"},
+ {"%b", int64(-1 << 63), zeroFill("-1", 63, "")},
// Used to panic.
- {"%0100d", 1, "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"},
- {"%0100d", -1, "-000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"},
- {"%0.100f", 1.0, "1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},
- {"%0.100f", -1.0, "-1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},
+ {"%0100d", 1, zeroFill("", 100, "1")},
+ {"%0100d", -1, zeroFill("-", 99, "1")},
+ {"%0.100f", 1.0, zeroFill("1.", 100, "")},
+ {"%0.100f", -1.0, zeroFill("-1.", 100, "")},
// Zero padding floats used to put the minus sign in the middle.
{"%020f", -1.0, "-000000000001.000000"},
{"%20f", -1.0, " -1.000000"},
- {"%0100f", -1.0, "-00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.000000"},
+ {"%0100f", -1.0, zeroFill("-", 99, "1.000000")},
// Complex fmt used to leave the plus flag set for future entries in the array
// causing +2+0i and +3+0i instead of 2+0i and 3+0i.
@@ -517,6 +518,33 @@ var fmtTests = []struct {
// Incomplete format specification caused crash.
{"%.", 3, "%!.(int=3)"},
+
+ // Used to panic with out-of-bounds for very large numeric representations.
+ // nByte is set to handle one bit per uint64 in %b format, with a negative number.
+ // See issue 6777.
+ {"%#064x", 1, zeroFill("0x", 64, "1")},
+ {"%#064x", -1, zeroFill("-0x", 63, "1")},
+ {"%#064b", 1, zeroFill("", 64, "1")},
+ {"%#064b", -1, zeroFill("-", 63, "1")},
+ {"%#064o", 1, zeroFill("", 64, "1")},
+ {"%#064o", -1, zeroFill("-", 63, "1")},
+ {"%#064d", 1, zeroFill("", 64, "1")},
+ {"%#064d", -1, zeroFill("-", 63, "1")},
+ // Test that we handle the crossover above the size of uint64
+ {"%#072x", 1, zeroFill("0x", 72, "1")},
+ {"%#072x", -1, zeroFill("-0x", 71, "1")},
+ {"%#072b", 1, zeroFill("", 72, "1")},
+ {"%#072b", -1, zeroFill("-", 71, "1")},
+ {"%#072o", 1, zeroFill("", 72, "1")},
+ {"%#072o", -1, zeroFill("-", 71, "1")},
+ {"%#072d", 1, zeroFill("", 72, "1")},
+ {"%#072d", -1, zeroFill("-", 71, "1")},
+}
+
+// zeroFill generates zero-filled strings of the specified width. The length
+// of the suffix (but not the prefix) is compensated for in the width calculation.
+func zeroFill(prefix string, width int, suffix string) string {
+ return prefix + strings.Repeat("0", width-len(suffix)) + suffix
}
func TestSprintf(t *testing.T) {
@@ -606,46 +634,66 @@ func TestReorder(t *testing.T) {
}
func BenchmarkSprintfEmpty(b *testing.B) {
- for i := 0; i < b.N; i++ {
+ benchmarkSprintf(b, func(buf *bytes.Buffer) {
Sprintf("")
- }
+ })
}
func BenchmarkSprintfString(b *testing.B) {
- for i := 0; i < b.N; i++ {
+ benchmarkSprintf(b, func(buf *bytes.Buffer) {
Sprintf("%s", "hello")
- }
+ })
}
func BenchmarkSprintfInt(b *testing.B) {
- for i := 0; i < b.N; i++ {
+ benchmarkSprintf(b, func(buf *bytes.Buffer) {
Sprintf("%d", 5)
- }
+ })
}
func BenchmarkSprintfIntInt(b *testing.B) {
- for i := 0; i < b.N; i++ {
+ benchmarkSprintf(b, func(buf *bytes.Buffer) {
Sprintf("%d %d", 5, 6)
- }
+ })
}
func BenchmarkSprintfPrefixedInt(b *testing.B) {
- for i := 0; i < b.N; i++ {
+ benchmarkSprintf(b, func(buf *bytes.Buffer) {
Sprintf("This is some meaningless prefix text that needs to be scanned %d", 6)
- }
+ })
}
func BenchmarkSprintfFloat(b *testing.B) {
- for i := 0; i < b.N; i++ {
+ benchmarkSprintf(b, func(buf *bytes.Buffer) {
Sprintf("%g", 5.23184)
- }
+ })
}
func BenchmarkManyArgs(b *testing.B) {
- var buf bytes.Buffer
- for i := 0; i < b.N; i++ {
+ benchmarkSprintf(b, func(buf *bytes.Buffer) {
buf.Reset()
- Fprintf(&buf, "%2d/%2d/%2d %d:%d:%d %s %s\n", 3, 4, 5, 11, 12, 13, "hello", "world")
+ Fprintf(buf, "%2d/%2d/%2d %d:%d:%d %s %s\n", 3, 4, 5, 11, 12, 13, "hello", "world")
+ })
+}
+
+func benchmarkSprintf(b *testing.B, f func(buf *bytes.Buffer)) {
+ const CallsPerSched = 1000
+ procs := runtime.GOMAXPROCS(-1)
+ N := int32(b.N / CallsPerSched)
+ c := make(chan bool, procs)
+ for p := 0; p < procs; p++ {
+ go func() {
+ var buf bytes.Buffer
+ for atomic.AddInt32(&N, -1) >= 0 {
+ for g := 0; g < CallsPerSched; g++ {
+ f(&buf)
+ }
+ }
+ c <- true
+ }()
+ }
+ for p := 0; p < procs; p++ {
+ <-c
}
}