aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/fmt
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2012-01-12 01:31:45 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2012-01-12 01:31:45 +0000
commit9a0e3259f44ad2de9c65f14f756dab01b3598391 (patch)
tree86a3b8019380d5fad53258c4baba3dd9e1e7c736 /libgo/go/fmt
parentc6135f063335419e4b5df0b4e1caf145882c8a4b (diff)
downloadgcc-9a0e3259f44ad2de9c65f14f756dab01b3598391.zip
gcc-9a0e3259f44ad2de9c65f14f756dab01b3598391.tar.gz
gcc-9a0e3259f44ad2de9c65f14f756dab01b3598391.tar.bz2
libgo: Update to weekly.2011-12-14.
From-SVN: r183118
Diffstat (limited to 'libgo/go/fmt')
-rw-r--r--libgo/go/fmt/fmt_test.go34
-rw-r--r--libgo/go/fmt/format.go4
-rw-r--r--libgo/go/fmt/print.go7
-rw-r--r--libgo/go/fmt/scan_test.go12
4 files changed, 50 insertions, 7 deletions
diff --git a/libgo/go/fmt/fmt_test.go b/libgo/go/fmt/fmt_test.go
index 63c3338..d7fe296 100644
--- a/libgo/go/fmt/fmt_test.go
+++ b/libgo/go/fmt/fmt_test.go
@@ -813,3 +813,37 @@ func TestPanics(t *testing.T) {
}
}
}
+
+// Test that erroneous String routine doesn't cause fatal recursion.
+var recurCount = 0
+
+type Recur struct {
+ i int
+ failed *bool
+}
+
+func (r Recur) String() string {
+ if recurCount++; recurCount > 10 {
+ *r.failed = true
+ return "FAIL"
+ }
+ // This will call badVerb. Before the fix, that would cause us to recur into
+ // this routine to print %!p(value). Now we don't call the user's method
+ // during an error.
+ return Sprintf("recur@%p value: %d", r, r.i)
+}
+
+func TestBadVerbRecursion(t *testing.T) {
+ failed := false
+ r := Recur{3, &failed}
+ Sprintf("recur@%p value: %d\n", &r, r.i)
+ if failed {
+ t.Error("fail with pointer")
+ }
+ failed = false
+ r = Recur{4, &failed}
+ Sprintf("recur@%p, value: %d\n", r, r.i)
+ if failed {
+ t.Error("fail with value")
+ }
+}
diff --git a/libgo/go/fmt/format.go b/libgo/go/fmt/format.go
index fbafa9d..5f62c06 100644
--- a/libgo/go/fmt/format.go
+++ b/libgo/go/fmt/format.go
@@ -331,9 +331,9 @@ func (f *fmt) fmt_q(s string) {
func (f *fmt) fmt_qc(c int64) {
var quoted string
if f.plus {
- quoted = strconv.QuoteRuneToASCII(int(c))
+ quoted = strconv.QuoteRuneToASCII(rune(c))
} else {
- quoted = strconv.QuoteRune(int(c))
+ quoted = strconv.QuoteRune(rune(c))
}
f.padString(quoted)
}
diff --git a/libgo/go/fmt/print.go b/libgo/go/fmt/print.go
index 8b15a82..9f157da 100644
--- a/libgo/go/fmt/print.go
+++ b/libgo/go/fmt/print.go
@@ -74,6 +74,7 @@ type GoStringer interface {
type pp struct {
n int
panicking bool
+ erroring bool // printing an error condition
buf bytes.Buffer
// field holds the current item, as an interface{}.
field interface{}
@@ -124,6 +125,7 @@ var ppFree = newCache(func() interface{} { return new(pp) })
func newPrinter() *pp {
p := ppFree.get().(*pp)
p.panicking = false
+ p.erroring = false
p.fmt.init(&p.buf)
return p
}
@@ -299,6 +301,7 @@ func (p *pp) unknownType(v interface{}) {
}
func (p *pp) badVerb(verb rune) {
+ p.erroring = true
p.add('%')
p.add('!')
p.add(verb)
@@ -316,6 +319,7 @@ func (p *pp) badVerb(verb rune) {
p.buf.Write(nilAngleBytes)
}
p.add(')')
+ p.erroring = false
}
func (p *pp) fmtBool(v bool, verb rune) {
@@ -606,6 +610,9 @@ func (p *pp) catchPanic(field interface{}, verb rune) {
}
func (p *pp) handleMethods(verb rune, plus, goSyntax bool, depth int) (wasString, handled bool) {
+ if p.erroring {
+ return
+ }
// Is it a Formatter?
if formatter, ok := p.field.(Formatter); ok {
handled = true
diff --git a/libgo/go/fmt/scan_test.go b/libgo/go/fmt/scan_test.go
index 0689bf3..b26c828 100644
--- a/libgo/go/fmt/scan_test.go
+++ b/libgo/go/fmt/scan_test.go
@@ -56,6 +56,7 @@ var (
stringVal string
stringVal1 string
bytesVal []byte
+ runeVal rune
complex64Val complex64
complex128Val complex128
renamedBoolVal renamedBool
@@ -225,9 +226,9 @@ var scanfTests = []ScanfTest{
{"%v", "0377\n", &intVal, 0377},
{"%v", "0x44\n", &intVal, 0x44},
{"%d", "72\n", &intVal, 72},
- {"%c", "a\n", &intVal, 'a'},
- {"%c", "\u5072\n", &intVal, 0x5072},
- {"%c", "\u1234\n", &intVal, '\u1234'},
+ {"%c", "a\n", &runeVal, 'a'},
+ {"%c", "\u5072\n", &runeVal, '\u5072'},
+ {"%c", "\u1234\n", &runeVal, '\u1234'},
{"%d", "73\n", &int8Val, int8(73)},
{"%d", "+74\n", &int16Val, int16(74)},
{"%d", "75\n", &int32Val, int32(75)},
@@ -322,6 +323,7 @@ var s, t string
var c complex128
var x, y Xs
var z IntString
+var r1, r2, r3 rune
var multiTests = []ScanfMultiTest{
{"", "", []interface{}{}, []interface{}{}, ""},
@@ -333,7 +335,7 @@ var multiTests = []ScanfMultiTest{
{"%3d22%3d", "33322333", args(&i, &j), args(333, 333), ""},
{"%6vX=%3fY", "3+2iX=2.5Y", args(&c, &f), args((3 + 2i), 2.5), ""},
{"%d%s", "123abc", args(&i, &s), args(123, "abc"), ""},
- {"%c%c%c", "2\u50c2X", args(&i, &j, &k), args('2', '\u50c2', 'X'), ""},
+ {"%c%c%c", "2\u50c2X", args(&r1, &r2, &r3), args('2', '\u50c2', 'X'), ""},
// Custom scanners.
{"%e%f", "eefffff", args(&x, &y), args(Xs("ee"), Xs("fffff")), ""},
@@ -347,7 +349,7 @@ var multiTests = []ScanfMultiTest{
{"X%d", "10X", args(&intVal), nil, "input does not match format"},
// Bad UTF-8: should see every byte.
- {"%c%c%c", "\xc2X\xc2", args(&i, &j, &k), args(utf8.RuneError, 'X', utf8.RuneError), ""},
+ {"%c%c%c", "\xc2X\xc2", args(&r1, &r2, &r3), args(utf8.RuneError, 'X', utf8.RuneError), ""},
}
func testScan(name string, t *testing.T, scan func(r io.Reader, a ...interface{}) (int, error)) {