public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Go patch committed: Update libgo to r60.3 release
@ 2011-10-22 20:16 Ian Lance Taylor
  0 siblings, 0 replies; only message in thread
From: Ian Lance Taylor @ 2011-10-22 20:16 UTC (permalink / raw)
  To: gcc-patches, gofrontend-dev

[-- Attachment #1: Type: text/plain, Size: 256 bytes --]

This patch updates the Go library to the r60.3 release.  This mainly
fixes a bug in the reflect package which permitted code to change types
in an unsafe manner.  Bootstrapped and ran Go testsuite on
x86_64-unknown-linux-gnu.  Committed to mainline.

Ian


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: patch --]
[-- Type: text/x-diff, Size: 69952 bytes --]

Index: libgo/MERGE
===================================================================
--- libgo/MERGE	(revision 179665)
+++ libgo/MERGE	(working copy)
@@ -1,4 +1,4 @@
-fd30c132d1bd
+c1702f36df03
 
 The first line of this file holds the Mercurial revision number of the
 last merge done from the master library sources.
Index: libgo/go/image/image.go
===================================================================
--- libgo/go/image/image.go	(revision 179665)
+++ libgo/go/image/image.go	(working copy)
@@ -3,6 +3,9 @@
 // license that can be found in the LICENSE file.
 
 // Package image implements a basic 2-D image library.
+//
+// See "The Go image package" for an introduction to this package:
+// http://blog.golang.org/2011/09/go-image-package.html
 package image
 
 // Config holds an image's color model and dimensions.
Index: libgo/go/image/draw/draw.go
===================================================================
--- libgo/go/image/draw/draw.go	(revision 179665)
+++ libgo/go/image/draw/draw.go	(working copy)
@@ -2,10 +2,10 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Package draw provides image composition functions
-// in the style of the Plan 9 graphics library
-// (see http://plan9.bell-labs.com/magic/man2html/2/draw)
-// and the X Render extension.
+// Package draw provides image composition functions.
+//
+// See "The Go image/draw package" for an introduction to this package:
+// http://blog.golang.org/2011/09/go-imagedraw-package.html
 package draw
 
 import (
Index: libgo/go/exp/datafmt/parser.go
===================================================================
--- libgo/go/exp/datafmt/parser.go	(revision 179665)
+++ libgo/go/exp/datafmt/parser.go	(working copy)
@@ -1,368 +0,0 @@
-// Copyright 2009 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 datafmt
-
-import (
-	"go/scanner"
-	"go/token"
-	"os"
-	"strconv"
-	"strings"
-)
-
-// ----------------------------------------------------------------------------
-// Parsing
-
-type parser struct {
-	scanner.ErrorVector
-	scanner scanner.Scanner
-	file    *token.File
-	pos     token.Pos   // token position
-	tok     token.Token // one token look-ahead
-	lit     string      // token literal
-
-	packs map[string]string // PackageName -> ImportPath
-	rules map[string]expr   // RuleName -> Expression
-}
-
-func (p *parser) next() {
-	p.pos, p.tok, p.lit = p.scanner.Scan()
-	switch p.tok {
-	case token.CHAN, token.FUNC, token.INTERFACE, token.MAP, token.STRUCT:
-		// Go keywords for composite types are type names
-		// returned by reflect. Accept them as identifiers.
-		p.tok = token.IDENT // p.lit is already set correctly
-	}
-}
-
-func (p *parser) init(fset *token.FileSet, filename string, src []byte) {
-	p.ErrorVector.Reset()
-	p.file = fset.AddFile(filename, fset.Base(), len(src))
-	p.scanner.Init(p.file, src, p, scanner.AllowIllegalChars) // return '@' as token.ILLEGAL w/o error message
-	p.next()                                                  // initializes pos, tok, lit
-	p.packs = make(map[string]string)
-	p.rules = make(map[string]expr)
-}
-
-func (p *parser) error(pos token.Pos, msg string) {
-	p.Error(p.file.Position(pos), msg)
-}
-
-func (p *parser) errorExpected(pos token.Pos, msg string) {
-	msg = "expected " + msg
-	if pos == p.pos {
-		// the error happened at the current position;
-		// make the error message more specific
-		msg += ", found '" + p.tok.String() + "'"
-		if p.tok.IsLiteral() {
-			msg += " " + p.lit
-		}
-	}
-	p.error(pos, msg)
-}
-
-func (p *parser) expect(tok token.Token) token.Pos {
-	pos := p.pos
-	if p.tok != tok {
-		p.errorExpected(pos, "'"+tok.String()+"'")
-	}
-	p.next() // make progress in any case
-	return pos
-}
-
-func (p *parser) parseIdentifier() string {
-	name := p.lit
-	p.expect(token.IDENT)
-	return name
-}
-
-func (p *parser) parseTypeName() (string, bool) {
-	pos := p.pos
-	name, isIdent := p.parseIdentifier(), true
-	if p.tok == token.PERIOD {
-		// got a package name, lookup package
-		if importPath, found := p.packs[name]; found {
-			name = importPath
-		} else {
-			p.error(pos, "package not declared: "+name)
-		}
-		p.next()
-		name, isIdent = name+"."+p.parseIdentifier(), false
-	}
-	return name, isIdent
-}
-
-// Parses a rule name and returns it. If the rule name is
-// a package-qualified type name, the package name is resolved.
-// The 2nd result value is true iff the rule name consists of a
-// single identifier only (and thus could be a package name).
-//
-func (p *parser) parseRuleName() (string, bool) {
-	name, isIdent := "", false
-	switch p.tok {
-	case token.IDENT:
-		name, isIdent = p.parseTypeName()
-	case token.DEFAULT:
-		name = "default"
-		p.next()
-	case token.QUO:
-		name = "/"
-		p.next()
-	default:
-		p.errorExpected(p.pos, "rule name")
-		p.next() // make progress in any case
-	}
-	return name, isIdent
-}
-
-func (p *parser) parseString() string {
-	s := ""
-	if p.tok == token.STRING {
-		s, _ = strconv.Unquote(p.lit)
-		// Unquote may fail with an error, but only if the scanner found
-		// an illegal string in the first place. In this case the error
-		// has already been reported.
-		p.next()
-		return s
-	} else {
-		p.expect(token.STRING)
-	}
-	return s
-}
-
-func (p *parser) parseLiteral() literal {
-	s := []byte(p.parseString())
-
-	// A string literal may contain %-format specifiers. To simplify
-	// and speed up printing of the literal, split it into segments
-	// that start with "%" possibly followed by a last segment that
-	// starts with some other character.
-	var list []interface{}
-	i0 := 0
-	for i := 0; i < len(s); i++ {
-		if s[i] == '%' && i+1 < len(s) {
-			// the next segment starts with a % format
-			if i0 < i {
-				// the current segment is not empty, split it off
-				list = append(list, s[i0:i])
-				i0 = i
-			}
-			i++ // skip %; let loop skip over char after %
-		}
-	}
-	// the final segment may start with any character
-	// (it is empty iff the string is empty)
-	list = append(list, s[i0:])
-
-	// convert list into a literal
-	lit := make(literal, len(list))
-	for i := 0; i < len(list); i++ {
-		lit[i] = list[i].([]byte)
-	}
-
-	return lit
-}
-
-func (p *parser) parseField() expr {
-	var fname string
-	switch p.tok {
-	case token.ILLEGAL:
-		if p.lit != "@" {
-			return nil
-		}
-		fname = "@"
-		p.next()
-	case token.MUL:
-		fname = "*"
-		p.next()
-	case token.IDENT:
-		fname = p.parseIdentifier()
-	default:
-		return nil
-	}
-
-	var ruleName string
-	if p.tok == token.COLON {
-		p.next()
-		ruleName, _ = p.parseRuleName()
-	}
-
-	return &field{fname, ruleName}
-}
-
-func (p *parser) parseOperand() (x expr) {
-	switch p.tok {
-	case token.STRING:
-		x = p.parseLiteral()
-
-	case token.LPAREN:
-		p.next()
-		x = p.parseExpression()
-		if p.tok == token.SHR {
-			p.next()
-			x = &group{x, p.parseExpression()}
-		}
-		p.expect(token.RPAREN)
-
-	case token.LBRACK:
-		p.next()
-		x = &option{p.parseExpression()}
-		p.expect(token.RBRACK)
-
-	case token.LBRACE:
-		p.next()
-		x = p.parseExpression()
-		var div expr
-		if p.tok == token.QUO {
-			p.next()
-			div = p.parseExpression()
-		}
-		x = &repetition{x, div}
-		p.expect(token.RBRACE)
-
-	default:
-		x = p.parseField() // may be nil
-	}
-
-	return x
-}
-
-func (p *parser) parseSequence() expr {
-	var list []interface{}
-
-	for x := p.parseOperand(); x != nil; x = p.parseOperand() {
-		list = append(list, x)
-	}
-
-	// no need for a sequence if list.Len() < 2
-	switch len(list) {
-	case 0:
-		return nil
-	case 1:
-		return list[0].(expr)
-	}
-
-	// convert list into a sequence
-	seq := make(sequence, len(list))
-	for i := 0; i < len(list); i++ {
-		seq[i] = list[i].(expr)
-	}
-	return seq
-}
-
-func (p *parser) parseExpression() expr {
-	var list []interface{}
-
-	for {
-		x := p.parseSequence()
-		if x != nil {
-			list = append(list, x)
-		}
-		if p.tok != token.OR {
-			break
-		}
-		p.next()
-	}
-
-	// no need for an alternatives if list.Len() < 2
-	switch len(list) {
-	case 0:
-		return nil
-	case 1:
-		return list[0].(expr)
-	}
-
-	// convert list into a alternatives
-	alt := make(alternatives, len(list))
-	for i := 0; i < len(list); i++ {
-		alt[i] = list[i].(expr)
-	}
-	return alt
-}
-
-func (p *parser) parseFormat() {
-	for p.tok != token.EOF {
-		pos := p.pos
-
-		name, isIdent := p.parseRuleName()
-		switch p.tok {
-		case token.STRING:
-			// package declaration
-			importPath := p.parseString()
-
-			// add package declaration
-			if !isIdent {
-				p.error(pos, "illegal package name: "+name)
-			} else if _, found := p.packs[name]; !found {
-				p.packs[name] = importPath
-			} else {
-				p.error(pos, "package already declared: "+name)
-			}
-
-		case token.ASSIGN:
-			// format rule
-			p.next()
-			x := p.parseExpression()
-
-			// add rule
-			if _, found := p.rules[name]; !found {
-				p.rules[name] = x
-			} else {
-				p.error(pos, "format rule already declared: "+name)
-			}
-
-		default:
-			p.errorExpected(p.pos, "package declaration or format rule")
-			p.next() // make progress in any case
-		}
-
-		if p.tok == token.SEMICOLON {
-			p.next()
-		} else {
-			break
-		}
-	}
-	p.expect(token.EOF)
-}
-
-func remap(p *parser, name string) string {
-	i := strings.Index(name, ".")
-	if i >= 0 {
-		packageName, suffix := name[0:i], name[i:]
-		// lookup package
-		if importPath, found := p.packs[packageName]; found {
-			name = importPath + suffix
-		} else {
-			var invalidPos token.Position
-			p.Error(invalidPos, "package not declared: "+packageName)
-		}
-	}
-	return name
-}
-
-// Parse parses a set of format productions from source src. Custom
-// formatters may be provided via a map of formatter functions. If
-// there are no errors, the result is a Format and the error is nil.
-// Otherwise the format is nil and a non-empty ErrorList is returned.
-//
-func Parse(fset *token.FileSet, filename string, src []byte, fmap FormatterMap) (Format, os.Error) {
-	// parse source
-	var p parser
-	p.init(fset, filename, src)
-	p.parseFormat()
-
-	// add custom formatters, if any
-	for name, form := range fmap {
-		name = remap(&p, name)
-		if _, found := p.rules[name]; !found {
-			p.rules[name] = &custom{name, form}
-		} else {
-			var invalidPos token.Position
-			p.Error(invalidPos, "formatter already declared: "+name)
-		}
-	}
-
-	return p.rules, p.GetError(scanner.NoMultiples)
-}
Index: libgo/go/exp/datafmt/datafmt_test.go
===================================================================
--- libgo/go/exp/datafmt/datafmt_test.go	(revision 179665)
+++ libgo/go/exp/datafmt/datafmt_test.go	(working copy)
@@ -1,330 +0,0 @@
-// Copyright 2009 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 datafmt
-
-import (
-	"fmt"
-	"testing"
-	"go/token"
-)
-
-var fset = token.NewFileSet()
-
-func parse(t *testing.T, form string, fmap FormatterMap) Format {
-	f, err := Parse(fset, "", []byte(form), fmap)
-	if err != nil {
-		t.Errorf("Parse(%s): %v", form, err)
-		return nil
-	}
-	return f
-}
-
-func verify(t *testing.T, f Format, expected string, args ...interface{}) {
-	if f == nil {
-		return // allow other tests to run
-	}
-	result := f.Sprint(args...)
-	if result != expected {
-		t.Errorf(
-			"result  : `%s`\nexpected: `%s`\n\n",
-			result, expected)
-	}
-}
-
-func formatter(s *State, value interface{}, rule_name string) bool {
-	switch rule_name {
-	case "/":
-		fmt.Fprintf(s, "%d %d %d", s.Pos().Line, s.LinePos().Column, s.Pos().Column)
-		return true
-	case "blank":
-		s.Write([]byte{' '})
-		return true
-	case "int":
-		if value.(int)&1 == 0 {
-			fmt.Fprint(s, "even ")
-		} else {
-			fmt.Fprint(s, "odd ")
-		}
-		return true
-	case "nil":
-		return false
-	case "testing.T":
-		s.Write([]byte("testing.T"))
-		return true
-	}
-	panic("unreachable")
-	return false
-}
-
-func TestCustomFormatters(t *testing.T) {
-	fmap0 := FormatterMap{"/": formatter}
-	fmap1 := FormatterMap{"int": formatter, "blank": formatter, "nil": formatter}
-	fmap2 := FormatterMap{"testing.T": formatter}
-
-	f := parse(t, `int=`, fmap0)
-	verify(t, f, ``, 1, 2, 3)
-
-	f = parse(t, `int="#"`, nil)
-	verify(t, f, `###`, 1, 2, 3)
-
-	f = parse(t, `int="#";string="%s"`, fmap0)
-	verify(t, f, "#1 0 1#1 0 7#1 0 13\n2 0 0foo2 0 8\n", 1, 2, 3, "\n", "foo", "\n")
-
-	f = parse(t, ``, fmap1)
-	verify(t, f, `even odd even odd `, 0, 1, 2, 3)
-
-	f = parse(t, `/ =@:blank; float64="#"`, fmap1)
-	verify(t, f, `# # #`, 0.0, 1.0, 2.0)
-
-	f = parse(t, `float64=@:nil`, fmap1)
-	verify(t, f, ``, 0.0, 1.0, 2.0)
-
-	f = parse(t, `testing "testing"; ptr=*`, fmap2)
-	verify(t, f, `testing.T`, t)
-
-	// TODO needs more tests
-}
-
-// ----------------------------------------------------------------------------
-// Formatting of basic and simple composite types
-
-func check(t *testing.T, form, expected string, args ...interface{}) {
-	f := parse(t, form, nil)
-	if f == nil {
-		return // allow other tests to run
-	}
-	result := f.Sprint(args...)
-	if result != expected {
-		t.Errorf(
-			"format  : %s\nresult  : `%s`\nexpected: `%s`\n\n",
-			form, result, expected)
-	}
-}
-
-func TestBasicTypes(t *testing.T) {
-	check(t, ``, ``)
-	check(t, `bool=":%v"`, `:true:false`, true, false)
-	check(t, `int="%b %d %o 0x%x"`, `101010 42 52 0x2a`, 42)
-
-	check(t, `int="%"`, `%`, 42)
-	check(t, `int="%%"`, `%`, 42)
-	check(t, `int="**%%**"`, `**%**`, 42)
-	check(t, `int="%%%%%%"`, `%%%`, 42)
-	check(t, `int="%%%d%%"`, `%42%`, 42)
-
-	const i = -42
-	const is = `-42`
-	check(t, `int  ="%d"`, is, i)
-	check(t, `int8 ="%d"`, is, int8(i))
-	check(t, `int16="%d"`, is, int16(i))
-	check(t, `int32="%d"`, is, int32(i))
-	check(t, `int64="%d"`, is, int64(i))
-
-	const u = 42
-	const us = `42`
-	check(t, `uint  ="%d"`, us, uint(u))
-	check(t, `uint8 ="%d"`, us, uint8(u))
-	check(t, `uint16="%d"`, us, uint16(u))
-	check(t, `uint32="%d"`, us, uint32(u))
-	check(t, `uint64="%d"`, us, uint64(u))
-
-	const f = 3.141592
-	const fs = `3.141592`
-	check(t, `float64="%g"`, fs, f)
-	check(t, `float32="%g"`, fs, float32(f))
-	check(t, `float64="%g"`, fs, float64(f))
-}
-
-func TestArrayTypes(t *testing.T) {
-	var a0 [10]int
-	check(t, `array="array";`, `array`, a0)
-
-	a1 := [...]int{1, 2, 3}
-	check(t, `array="array";`, `array`, a1)
-	check(t, `array={*}; int="%d";`, `123`, a1)
-	check(t, `array={* / ", "}; int="%d";`, `1, 2, 3`, a1)
-	check(t, `array={* / *}; int="%d";`, `12233`, a1)
-
-	a2 := []interface{}{42, "foo", 3.14}
-	check(t, `array={* / ", "}; interface=*; string="bar"; default="%v";`, `42, bar, 3.14`, a2)
-}
-
-func TestChanTypes(t *testing.T) {
-	var c0 chan int
-	check(t, `chan="chan"`, `chan`, c0)
-
-	c1 := make(chan int)
-	go func() { c1 <- 42 }()
-	check(t, `chan="chan"`, `chan`, c1)
-	// check(t, `chan=*`, `42`, c1);  // reflection support for chans incomplete
-}
-
-func TestFuncTypes(t *testing.T) {
-	var f0 func() int
-	check(t, `func="func"`, `func`, f0)
-
-	f1 := func() int { return 42 }
-	check(t, `func="func"`, `func`, f1)
-	// check(t, `func=*`, `42`, f1);  // reflection support for funcs incomplete
-}
-
-func TestMapTypes(t *testing.T) {
-	var m0 map[string]int
-	check(t, `map="map"`, `map`, m0)
-
-	m1 := map[string]int{}
-	check(t, `map="map"`, `map`, m1)
-	// check(t, `map=*`, ``, m1);  // reflection support for maps incomplete
-}
-
-func TestPointerTypes(t *testing.T) {
-	var p0 *int
-	check(t, `ptr="ptr"`, `ptr`, p0)
-	check(t, `ptr=*`, ``, p0)
-	check(t, `ptr=*|"nil"`, `nil`, p0)
-
-	x := 99991
-	p1 := &x
-	check(t, `ptr="ptr"`, `ptr`, p1)
-	check(t, `ptr=*; int="%d"`, `99991`, p1)
-}
-
-func TestDefaultRule(t *testing.T) {
-	check(t, `default="%v"`, `42foo3.14`, 42, "foo", 3.14)
-	check(t, `default="%v"; int="%x"`, `abcdef`, 10, 11, 12, 13, 14, 15)
-	check(t, `default="%v"; int="%x"`, `ab**ef`, 10, 11, "**", 14, 15)
-	check(t, `default="%x"; int=@:default`, `abcdef`, 10, 11, 12, 13, 14, 15)
-}
-
-func TestGlobalSeparatorRule(t *testing.T) {
-	check(t, `int="%d"; / ="-"`, `1-2-3-4`, 1, 2, 3, 4)
-	check(t, `int="%x%x"; / ="*"`, `aa*aa`, 10, 10)
-}
-
-// ----------------------------------------------------------------------------
-// Formatting of a struct
-
-type T1 struct {
-	a int
-}
-
-const F1 = `datafmt "datafmt";` +
-	`int = "%d";` +
-	`datafmt.T1 = "<" a ">";`
-
-func TestStruct1(t *testing.T) { check(t, F1, "<42>", T1{42}) }
-
-// ----------------------------------------------------------------------------
-// Formatting of a struct with an optional field (ptr)
-
-type T2 struct {
-	s string
-	p *T1
-}
-
-const F2a = F1 +
-	`string = "%s";` +
-	`ptr = *;` +
-	`datafmt.T2 = s ["-" p "-"];`
-
-const F2b = F1 +
-	`string = "%s";` +
-	`ptr = *;` +
-	`datafmt.T2 = s ("-" p "-" | "empty");`
-
-func TestStruct2(t *testing.T) {
-	check(t, F2a, "foo", T2{"foo", nil})
-	check(t, F2a, "bar-<17>-", T2{"bar", &T1{17}})
-	check(t, F2b, "fooempty", T2{"foo", nil})
-}
-
-// ----------------------------------------------------------------------------
-// Formatting of a struct with a repetitive field (slice)
-
-type T3 struct {
-	s string
-	a []int
-}
-
-const F3a = `datafmt "datafmt";` +
-	`default = "%v";` +
-	`array = *;` +
-	`datafmt.T3 = s  {" " a a / ","};`
-
-const F3b = `datafmt "datafmt";` +
-	`int = "%d";` +
-	`string = "%s";` +
-	`array = *;` +
-	`nil = ;` +
-	`empty = *:nil;` +
-	`datafmt.T3 = s [a:empty ": " {a / "-"}]`
-
-func TestStruct3(t *testing.T) {
-	check(t, F3a, "foo", T3{"foo", nil})
-	check(t, F3a, "foo 00, 11, 22", T3{"foo", []int{0, 1, 2}})
-	check(t, F3b, "bar", T3{"bar", nil})
-	check(t, F3b, "bal: 2-3-5", T3{"bal", []int{2, 3, 5}})
-}
-
-// ----------------------------------------------------------------------------
-// Formatting of a struct with alternative field
-
-type T4 struct {
-	x *int
-	a []int
-}
-
-const F4a = `datafmt "datafmt";` +
-	`int = "%d";` +
-	`ptr = *;` +
-	`array = *;` +
-	`nil = ;` +
-	`empty = *:nil;` +
-	`datafmt.T4 = "<" (x:empty x | "-") ">" `
-
-const F4b = `datafmt "datafmt";` +
-	`int = "%d";` +
-	`ptr = *;` +
-	`array = *;` +
-	`nil = ;` +
-	`empty = *:nil;` +
-	`datafmt.T4 = "<" (a:empty {a / ", "} | "-") ">" `
-
-func TestStruct4(t *testing.T) {
-	x := 7
-	check(t, F4a, "<->", T4{nil, nil})
-	check(t, F4a, "<7>", T4{&x, nil})
-	check(t, F4b, "<->", T4{nil, nil})
-	check(t, F4b, "<2, 3, 7>", T4{nil, []int{2, 3, 7}})
-}
-
-// ----------------------------------------------------------------------------
-// Formatting a struct (documentation example)
-
-type Point struct {
-	name string
-	x, y int
-}
-
-const FPoint = `datafmt "datafmt";` +
-	`int = "%d";` +
-	`hexInt = "0x%x";` +
-	`string = "---%s---";` +
-	`datafmt.Point = name "{" x ", " y:hexInt "}";`
-
-func TestStructPoint(t *testing.T) {
-	p := Point{"foo", 3, 15}
-	check(t, FPoint, "---foo---{3, 0xf}", p)
-}
-
-// ----------------------------------------------------------------------------
-// Formatting a slice (documentation example)
-
-const FSlice = `int = "%b";` +
-	`array = { * / ", " }`
-
-func TestSlice(t *testing.T) { check(t, FSlice, "10, 11, 101, 111", []int{2, 3, 5, 7}) }
-
-// TODO add more tests
Index: libgo/go/exp/datafmt/datafmt.go
===================================================================
--- libgo/go/exp/datafmt/datafmt.go	(revision 179665)
+++ libgo/go/exp/datafmt/datafmt.go	(working copy)
@@ -1,710 +0,0 @@
-// Copyright 2009 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 datafmt implements syntax-directed, type-driven formatting
-	of arbitrary data structures. Formatting a data structure consists of
-	two phases: first, a parser reads a format specification and builds a
-	"compiled" format. Then, the format can be applied repeatedly to
-	arbitrary values. Applying a format to a value evaluates to a []byte
-	containing the formatted value bytes, or nil.
-
-	A format specification is a set of package declarations and format rules:
-
-		Format      = [ Entry { ";" Entry } [ ";" ] ] .
-		Entry       = PackageDecl | FormatRule .
-
-	(The syntax of a format specification is presented in the same EBNF
-	notation as used in the Go language specification. The syntax of white
-	space, comments, identifiers, and string literals is the same as in Go.)
-
-	A package declaration binds a package name (such as 'ast') to a
-	package import path (such as '"go/ast"'). Each package used (in
-	a type name, see below) must be declared once before use.
-
-		PackageDecl = PackageName ImportPath .
-		PackageName = identifier .
-		ImportPath  = string .
-
-	A format rule binds a rule name to a format expression. A rule name
-	may be a type name or one of the special names 'default' or '/'.
-	A type name may be the name of a predeclared type (for example, 'int',
-	'float32', etc.), the package-qualified name of a user-defined type
-	(for example, 'ast.MapType'), or an identifier indicating the structure
-	of unnamed composite types ('array', 'chan', 'func', 'interface', 'map',
-	or 'ptr'). Each rule must have a unique name; rules can be declared in
-	any order.
-
-		FormatRule  = RuleName "=" Expression .
-		RuleName    = TypeName | "default" | "/" .
-		TypeName    = [ PackageName "." ] identifier .
-
-	To format a value, the value's type name is used to select the format rule
-	(there is an override mechanism, see below). The format expression of the
-	selected rule specifies how the value is formatted. Each format expression,
-	when applied to a value, evaluates to a byte sequence or nil.
-
-	In its most general form, a format expression is a list of alternatives,
-	each of which is a sequence of operands:
-
-		Expression  = [ Sequence ] { "|" [ Sequence ] } .
-		Sequence    = Operand { Operand } .
-
-	The formatted result produced by an expression is the result of the first
-	alternative sequence that evaluates to a non-nil result; if there is no
-	such alternative, the expression evaluates to nil. The result produced by
-	an operand sequence is the concatenation of the results of its operands.
-	If any operand in the sequence evaluates to nil, the entire sequence
-	evaluates to nil.
-
-	There are five kinds of operands:
-
-		Operand     = Literal | Field | Group | Option | Repetition .
-
-	Literals evaluate to themselves, with two substitutions. First,
-	%-formats expand in the manner of fmt.Printf, with the current value
-	passed as the parameter. Second, the current indentation (see below)
-	is inserted after every newline or form feed character.
-
-		Literal     = string .
-
-	This table shows string literals applied to the value 42 and the
-	corresponding formatted result:
-
-		"foo"       foo
-		"%x"        2a
-		"x = %d"    x = 42
-		"%#x = %d"  0x2a = 42
-
-	A field operand is a field name optionally followed by an alternate
-	rule name. The field name may be an identifier or one of the special
-	names @ or *.
-
-		Field       = FieldName [ ":" RuleName ] .
-		FieldName   = identifier | "@" | "*" .
-
-	If the field name is an identifier, the current value must be a struct,
-	and there must be a field with that name in the struct. The same lookup
-	rules apply as in the Go language (for instance, the name of an anonymous
-	field is the unqualified type name). The field name denotes the field
-	value in the struct. If the field is not found, formatting is aborted
-	and an error message is returned. (TODO consider changing the semantics
-	such that if a field is not found, it evaluates to nil).
-
-	The special name '@' denotes the current value.
-
-	The meaning of the special name '*' depends on the type of the current
-	value:
-
-		array, slice types   array, slice element (inside {} only, see below)
-		interfaces           value stored in interface
-		pointers             value pointed to by pointer
-
-	(Implementation restriction: channel, function and map types are not
-	supported due to missing reflection support).
-
-	Fields are evaluated as follows: If the field value is nil, or an array
-	or slice element does not exist, the result is nil (see below for details
-	on array/slice elements). If the value is not nil the field value is
-	formatted (recursively) using the rule corresponding to its type name,
-	or the alternate rule name, if given.
-
-	The following example shows a complete format specification for a
-	struct 'myPackage.Point'. Assume the package
-
-		package myPackage  // in directory myDir/myPackage
-		type Point struct {
-			name string;
-			x, y int;
-		}
-
-	Applying the format specification
-
-		myPackage "myDir/myPackage";
-		int = "%d";
-		hexInt = "0x%x";
-		string = "---%s---";
-		myPackage.Point = name "{" x ", " y:hexInt "}";
-
-	to the value myPackage.Point{"foo", 3, 15} results in
-
-		---foo---{3, 0xf}
-
-	Finally, an operand may be a grouped, optional, or repeated expression.
-	A grouped expression ("group") groups a more complex expression (body)
-	so that it can be used in place of a single operand:
-
-		Group       = "(" [ Indentation ">>" ] Body ")" .
-		Indentation = Expression .
-		Body        = Expression .
-
-	A group body may be prefixed by an indentation expression followed by '>>'.
-	The indentation expression is applied to the current value like any other
-	expression and the result, if not nil, is appended to the current indentation
-	during the evaluation of the body (see also formatting state, below).
-
-	An optional expression ("option") is enclosed in '[]' brackets.
-
-		Option      = "[" Body "]" .
-
-	An option evaluates to its body, except that if the body evaluates to nil,
-	the option expression evaluates to an empty []byte. Thus an option's purpose
-	is to protect the expression containing the option from a nil operand.
-
-	A repeated expression ("repetition") is enclosed in '{}' braces.
-
-		Repetition  = "{" Body [ "/" Separator ] "}" .
-		Separator   = Expression .
-
-	A repeated expression is evaluated as follows: The body is evaluated
-	repeatedly and its results are concatenated until the body evaluates
-	to nil. The result of the repetition is the (possibly empty) concatenation,
-	but it is never nil. An implicit index is supplied for the evaluation of
-	the body: that index is used to address elements of arrays or slices. If
-	the corresponding elements do not exist, the field denoting the element
-	evaluates to nil (which in turn may terminate the repetition).
-
-	The body of a repetition may be followed by a '/' and a "separator"
-	expression. If the separator is present, it is invoked between repetitions
-	of the body.
-
-	The following example shows a complete format specification for formatting
-	a slice of unnamed type. Applying the specification
-
-		int = "%b";
-		array = { * / ", " };  // array is the type name for an unnamed slice
-
-	to the value '[]int{2, 3, 5, 7}' results in
-
-		10, 11, 101, 111
-
-	Default rule: If a format rule named 'default' is present, it is used for
-	formatting a value if no other rule was found. A common default rule is
-
-		default = "%v"
-
-	to provide default formatting for basic types without having to specify
-	a specific rule for each basic type.
-
-	Global separator rule: If a format rule named '/' is present, it is
-	invoked with the current value between literals. If the separator
-	expression evaluates to nil, it is ignored.
-
-	For instance, a global separator rule may be used to punctuate a sequence
-	of values with commas. The rules:
-
-		default = "%v";
-		/ = ", ";
-
-	will format an argument list by printing each one in its default format,
-	separated by a comma and a space.
-*/
-package datafmt
-
-import (
-	"bytes"
-	"fmt"
-	"go/token"
-	"io"
-	"os"
-	"reflect"
-	"runtime"
-)
-
-// ----------------------------------------------------------------------------
-// Format representation
-
-// Custom formatters implement the Formatter function type.
-// A formatter is invoked with the current formatting state, the
-// value to format, and the rule name under which the formatter
-// was installed (the same formatter function may be installed
-// under different names). The formatter may access the current state
-// to guide formatting and use State.Write to append to the state's
-// output.
-//
-// A formatter must return a boolean value indicating if it evaluated
-// to a non-nil value (true), or a nil value (false).
-//
-type Formatter func(state *State, value interface{}, ruleName string) bool
-
-// A FormatterMap is a set of custom formatters.
-// It maps a rule name to a formatter function.
-//
-type FormatterMap map[string]Formatter
-
-// A parsed format expression is built from the following nodes.
-//
-type (
-	expr interface{}
-
-	alternatives []expr // x | y | z
-
-	sequence []expr // x y z
-
-	literal [][]byte // a list of string segments, possibly starting with '%'
-
-	field struct {
-		fieldName string // including "@", "*"
-		ruleName  string // "" if no rule name specified
-	}
-
-	group struct {
-		indent, body expr // (indent >> body)
-	}
-
-	option struct {
-		body expr // [body]
-	}
-
-	repetition struct {
-		body, separator expr // {body / separator}
-	}
-
-	custom struct {
-		ruleName string
-		fun      Formatter
-	}
-)
-
-// A Format is the result of parsing a format specification.
-// The format may be applied repeatedly to format values.
-//
-type Format map[string]expr
-
-// ----------------------------------------------------------------------------
-// Formatting
-
-// An application-specific environment may be provided to Format.Apply;
-// the environment is available inside custom formatters via State.Env().
-// Environments must implement copying; the Copy method must return an
-// complete copy of the receiver. This is necessary so that the formatter
-// can save and restore an environment (in case of an absent expression).
-//
-// If the Environment doesn't change during formatting (this is under
-// control of the custom formatters), the Copy function can simply return
-// the receiver, and thus can be very light-weight.
-//
-type Environment interface {
-	Copy() Environment
-}
-
-// State represents the current formatting state.
-// It is provided as argument to custom formatters.
-//
-type State struct {
-	fmt       Format         // format in use
-	env       Environment    // user-supplied environment
-	errors    chan os.Error  // not chan *Error (errors <- nil would be wrong!)
-	hasOutput bool           // true after the first literal has been written
-	indent    bytes.Buffer   // current indentation
-	output    bytes.Buffer   // format output
-	linePos   token.Position // position of line beginning (Column == 0)
-	default_  expr           // possibly nil
-	separator expr           // possibly nil
-}
-
-func newState(fmt Format, env Environment, errors chan os.Error) *State {
-	s := new(State)
-	s.fmt = fmt
-	s.env = env
-	s.errors = errors
-	s.linePos = token.Position{Line: 1}
-
-	// if we have a default rule, cache its expression for fast access
-	if x, found := fmt["default"]; found {
-		s.default_ = x
-	}
-
-	// if we have a global separator rule, cache its expression for fast access
-	if x, found := fmt["/"]; found {
-		s.separator = x
-	}
-
-	return s
-}
-
-// Env returns the environment passed to Format.Apply.
-func (s *State) Env() interface{} { return s.env }
-
-// LinePos returns the position of the current line beginning
-// in the state's output buffer. Line numbers start at 1.
-//
-func (s *State) LinePos() token.Position { return s.linePos }
-
-// Pos returns the position of the next byte to be written to the
-// output buffer. Line numbers start at 1.
-//
-func (s *State) Pos() token.Position {
-	offs := s.output.Len()
-	return token.Position{Line: s.linePos.Line, Column: offs - s.linePos.Offset, Offset: offs}
-}
-
-// Write writes data to the output buffer, inserting the indentation
-// string after each newline or form feed character. It cannot return an error.
-//
-func (s *State) Write(data []byte) (int, os.Error) {
-	n := 0
-	i0 := 0
-	for i, ch := range data {
-		if ch == '\n' || ch == '\f' {
-			// write text segment and indentation
-			n1, _ := s.output.Write(data[i0 : i+1])
-			n2, _ := s.output.Write(s.indent.Bytes())
-			n += n1 + n2
-			i0 = i + 1
-			s.linePos.Offset = s.output.Len()
-			s.linePos.Line++
-		}
-	}
-	n3, _ := s.output.Write(data[i0:])
-	return n + n3, nil
-}
-
-type checkpoint struct {
-	env       Environment
-	hasOutput bool
-	outputLen int
-	linePos   token.Position
-}
-
-func (s *State) save() checkpoint {
-	saved := checkpoint{nil, s.hasOutput, s.output.Len(), s.linePos}
-	if s.env != nil {
-		saved.env = s.env.Copy()
-	}
-	return saved
-}
-
-func (s *State) restore(m checkpoint) {
-	s.env = m.env
-	s.output.Truncate(m.outputLen)
-}
-
-func (s *State) error(msg string) {
-	s.errors <- os.NewError(msg)
-	runtime.Goexit()
-}
-
-// TODO At the moment, unnamed types are simply mapped to the default
-//      names below. For instance, all unnamed arrays are mapped to
-//      'array' which is not really sufficient. Eventually one may want
-//      to be able to specify rules for say an unnamed slice of T.
-//
-
-func typename(typ reflect.Type) string {
-	switch typ.Kind() {
-	case reflect.Array:
-		return "array"
-	case reflect.Slice:
-		return "array"
-	case reflect.Chan:
-		return "chan"
-	case reflect.Func:
-		return "func"
-	case reflect.Interface:
-		return "interface"
-	case reflect.Map:
-		return "map"
-	case reflect.Ptr:
-		return "ptr"
-	}
-	return typ.String()
-}
-
-func (s *State) getFormat(name string) expr {
-	if fexpr, found := s.fmt[name]; found {
-		return fexpr
-	}
-
-	if s.default_ != nil {
-		return s.default_
-	}
-
-	s.error(fmt.Sprintf("no format rule for type: '%s'", name))
-	return nil
-}
-
-// eval applies a format expression fexpr to a value. If the expression
-// evaluates internally to a non-nil []byte, that slice is appended to
-// the state's output buffer and eval returns true. Otherwise, eval
-// returns false and the state remains unchanged.
-//
-func (s *State) eval(fexpr expr, value reflect.Value, index int) bool {
-	// an empty format expression always evaluates
-	// to a non-nil (but empty) []byte
-	if fexpr == nil {
-		return true
-	}
-
-	switch t := fexpr.(type) {
-	case alternatives:
-		// append the result of the first alternative that evaluates to
-		// a non-nil []byte to the state's output
-		mark := s.save()
-		for _, x := range t {
-			if s.eval(x, value, index) {
-				return true
-			}
-			s.restore(mark)
-		}
-		return false
-
-	case sequence:
-		// append the result of all operands to the state's output
-		// unless a nil result is encountered
-		mark := s.save()
-		for _, x := range t {
-			if !s.eval(x, value, index) {
-				s.restore(mark)
-				return false
-			}
-		}
-		return true
-
-	case literal:
-		// write separator, if any
-		if s.hasOutput {
-			// not the first literal
-			if s.separator != nil {
-				sep := s.separator // save current separator
-				s.separator = nil  // and disable it (avoid recursion)
-				mark := s.save()
-				if !s.eval(sep, value, index) {
-					s.restore(mark)
-				}
-				s.separator = sep // enable it again
-			}
-		}
-		s.hasOutput = true
-		// write literal segments
-		for _, lit := range t {
-			if len(lit) > 1 && lit[0] == '%' {
-				// segment contains a %-format at the beginning
-				if lit[1] == '%' {
-					// "%%" is printed as a single "%"
-					s.Write(lit[1:])
-				} else {
-					// use s instead of s.output to get indentation right
-					fmt.Fprintf(s, string(lit), value.Interface())
-				}
-			} else {
-				// segment contains no %-formats
-				s.Write(lit)
-			}
-		}
-		return true // a literal never evaluates to nil
-
-	case *field:
-		// determine field value
-		switch t.fieldName {
-		case "@":
-			// field value is current value
-
-		case "*":
-			// indirection: operation is type-specific
-			switch v := value; v.Kind() {
-			case reflect.Array:
-				if v.Len() <= index {
-					return false
-				}
-				value = v.Index(index)
-
-			case reflect.Slice:
-				if v.IsNil() || v.Len() <= index {
-					return false
-				}
-				value = v.Index(index)
-
-			case reflect.Map:
-				s.error("reflection support for maps incomplete")
-
-			case reflect.Ptr:
-				if v.IsNil() {
-					return false
-				}
-				value = v.Elem()
-
-			case reflect.Interface:
-				if v.IsNil() {
-					return false
-				}
-				value = v.Elem()
-
-			case reflect.Chan:
-				s.error("reflection support for chans incomplete")
-
-			case reflect.Func:
-				s.error("reflection support for funcs incomplete")
-
-			default:
-				s.error(fmt.Sprintf("error: * does not apply to `%s`", value.Type()))
-			}
-
-		default:
-			// value is value of named field
-			var field reflect.Value
-			if sval := value; sval.Kind() == reflect.Struct {
-				field = sval.FieldByName(t.fieldName)
-				if !field.IsValid() {
-					// TODO consider just returning false in this case
-					s.error(fmt.Sprintf("error: no field `%s` in `%s`", t.fieldName, value.Type()))
-				}
-			}
-			value = field
-		}
-
-		// determine rule
-		ruleName := t.ruleName
-		if ruleName == "" {
-			// no alternate rule name, value type determines rule
-			ruleName = typename(value.Type())
-		}
-		fexpr = s.getFormat(ruleName)
-
-		mark := s.save()
-		if !s.eval(fexpr, value, index) {
-			s.restore(mark)
-			return false
-		}
-		return true
-
-	case *group:
-		// remember current indentation
-		indentLen := s.indent.Len()
-
-		// update current indentation
-		mark := s.save()
-		s.eval(t.indent, value, index)
-		// if the indentation evaluates to nil, the state's output buffer
-		// didn't change - either way it's ok to append the difference to
-		// the current indentation
-		s.indent.Write(s.output.Bytes()[mark.outputLen:s.output.Len()])
-		s.restore(mark)
-
-		// format group body
-		mark = s.save()
-		b := true
-		if !s.eval(t.body, value, index) {
-			s.restore(mark)
-			b = false
-		}
-
-		// reset indentation
-		s.indent.Truncate(indentLen)
-		return b
-
-	case *option:
-		// evaluate the body and append the result to the state's output
-		// buffer unless the result is nil
-		mark := s.save()
-		if !s.eval(t.body, value, 0) { // TODO is 0 index correct?
-			s.restore(mark)
-		}
-		return true // an option never evaluates to nil
-
-	case *repetition:
-		// evaluate the body and append the result to the state's output
-		// buffer until a result is nil
-		for i := 0; ; i++ {
-			mark := s.save()
-			// write separator, if any
-			if i > 0 && t.separator != nil {
-				// nil result from separator is ignored
-				mark := s.save()
-				if !s.eval(t.separator, value, i) {
-					s.restore(mark)
-				}
-			}
-			if !s.eval(t.body, value, i) {
-				s.restore(mark)
-				break
-			}
-		}
-		return true // a repetition never evaluates to nil
-
-	case *custom:
-		// invoke the custom formatter to obtain the result
-		mark := s.save()
-		if !t.fun(s, value.Interface(), t.ruleName) {
-			s.restore(mark)
-			return false
-		}
-		return true
-	}
-
-	panic("unreachable")
-	return false
-}
-
-// Eval formats each argument according to the format
-// f and returns the resulting []byte and os.Error. If
-// an error occurred, the []byte contains the partially
-// formatted result. An environment env may be passed
-// in which is available in custom formatters through
-// the state parameter.
-//
-func (f Format) Eval(env Environment, args ...interface{}) ([]byte, os.Error) {
-	if f == nil {
-		return nil, os.NewError("format is nil")
-	}
-
-	errors := make(chan os.Error)
-	s := newState(f, env, errors)
-
-	go func() {
-		for _, v := range args {
-			fld := reflect.ValueOf(v)
-			if !fld.IsValid() {
-				errors <- os.NewError("nil argument")
-				return
-			}
-			mark := s.save()
-			if !s.eval(s.getFormat(typename(fld.Type())), fld, 0) { // TODO is 0 index correct?
-				s.restore(mark)
-			}
-		}
-		errors <- nil // no errors
-	}()
-
-	err := <-errors
-	return s.output.Bytes(), err
-}
-
-// ----------------------------------------------------------------------------
-// Convenience functions
-
-// Fprint formats each argument according to the format f
-// and writes to w. The result is the total number of bytes
-// written and an os.Error, if any.
-//
-func (f Format) Fprint(w io.Writer, env Environment, args ...interface{}) (int, os.Error) {
-	data, err := f.Eval(env, args...)
-	if err != nil {
-		// TODO should we print partial result in case of error?
-		return 0, err
-	}
-	return w.Write(data)
-}
-
-// Print formats each argument according to the format f
-// and writes to standard output. The result is the total
-// number of bytes written and an os.Error, if any.
-//
-func (f Format) Print(args ...interface{}) (int, os.Error) {
-	return f.Fprint(os.Stdout, nil, args...)
-}
-
-// Sprint formats each argument according to the format f
-// and returns the resulting string. If an error occurs
-// during formatting, the result string contains the
-// partially formatted result followed by an error message.
-//
-func (f Format) Sprint(args ...interface{}) string {
-	var buf bytes.Buffer
-	_, err := f.Fprint(&buf, nil, args...)
-	if err != nil {
-		var i interface{} = args
-		fmt.Fprintf(&buf, "--- Sprint(%s) failed: %v", fmt.Sprint(i), err)
-	}
-	return buf.String()
-}
Index: libgo/go/reflect/value.go
===================================================================
--- libgo/go/reflect/value.go	(revision 179665)
+++ libgo/go/reflect/value.go	(working copy)
@@ -829,14 +829,7 @@ func (v Value) CanInterface() bool {
 	if iv.kind == Invalid {
 		panic(&ValueError{"reflect.Value.CanInterface", iv.kind})
 	}
-	// TODO(rsc): Check flagRO too.  Decide what to do about asking for
-	// interface for a value obtained via an unexported field.
-	// If the field were of a known type, say chan int or *sync.Mutex,
-	// the caller could interfere with the data after getting the
-	// interface.  But fmt.Print depends on being able to look.
-	// Now that reflect is more efficient the special cases in fmt
-	// might be less important.
-	return v.InternalMethod == 0
+	return v.InternalMethod == 0 && iv.flag&flagRO == 0
 }
 
 // Interface returns v's value as an interface{}.
@@ -844,22 +837,28 @@ func (v Value) CanInterface() bool {
 // (as opposed to Type.Method), Interface cannot return an
 // interface value, so it panics.
 func (v Value) Interface() interface{} {
-	return v.internal().Interface()
+	return valueInterface(v, true)
 }
 
-func (iv internalValue) Interface() interface{} {
+func valueInterface(v Value, safe bool) interface{} {
+	iv := v.internal()
+	return iv.valueInterface(safe)
+}
+
+func (iv internalValue) valueInterface(safe bool) interface{} {
 	if iv.kind == 0 {
 		panic(&ValueError{"reflect.Value.Interface", iv.kind})
 	}
 	if iv.method {
 		panic("reflect.Value.Interface: cannot create interface value for method with bound receiver")
 	}
-	/*
-		if v.flag()&noExport != 0 {
-			panic("reflect.Value.Interface: cannot return value obtained from unexported struct field")
-		}
-	*/
 
+	if safe && iv.flag&flagRO != 0 {
+		// Do not allow access to unexported values via Interface,
+		// because they might be pointers that should not be 
+		// writable or methods or function that should not be callable.
+		panic("reflect.Value.Interface: cannot return value obtained from unexported field or method")
+	}
 	if iv.kind == Interface {
 		// Special case: return the element inside the interface.
 		// Won't recurse further because an interface cannot contain an interface.
@@ -1695,7 +1694,7 @@ func convertForAssignment(what string, a
 		if addr == nil {
 			addr = unsafe.Pointer(new(interface{}))
 		}
-		x := iv.Interface()
+		x := iv.valueInterface(false)
 		if dst.NumMethod() == 0 {
 			*(*interface{})(addr) = x
 		} else {
Index: libgo/go/reflect/deepequal.go
===================================================================
--- libgo/go/reflect/deepequal.go	(revision 179665)
+++ libgo/go/reflect/deepequal.go	(working copy)
@@ -104,7 +104,7 @@ func deepValueEqual(v1, v2 Value, visite
 		return true
 	default:
 		// Normal equality suffices
-		return v1.Interface() == v2.Interface()
+		return valueInterface(v1, false) == valueInterface(v2, false)
 	}
 
 	panic("Not reached")
Index: libgo/go/reflect/all_test.go
===================================================================
--- libgo/go/reflect/all_test.go	(revision 179665)
+++ libgo/go/reflect/all_test.go	(working copy)
@@ -853,13 +853,13 @@ func TestIsNil(t *testing.T) {
 
 func TestInterfaceExtraction(t *testing.T) {
 	var s struct {
-		w io.Writer
+		W io.Writer
 	}
 
-	s.w = os.Stdout
+	s.W = os.Stdout
 	v := Indirect(ValueOf(&s)).Field(0).Interface()
-	if v != s.w.(interface{}) {
-		t.Error("Interface() on interface: ", v, s.w)
+	if v != s.W.(interface{}) {
+		t.Error("Interface() on interface: ", v, s.W)
 	}
 }
 
@@ -1190,18 +1190,18 @@ type D2 struct {
 }
 
 type S0 struct {
-	a, b, c int
+	A, B, C int
 	D1
 	D2
 }
 
 type S1 struct {
-	b int
+	B int
 	S0
 }
 
 type S2 struct {
-	a int
+	A int
 	*S1
 }
 
@@ -1216,36 +1216,36 @@ type S1y struct {
 type S3 struct {
 	S1x
 	S2
-	d, e int
+	D, E int
 	*S1y
 }
 
 type S4 struct {
 	*S4
-	a int
+	A int
 }
 
 var fieldTests = []FTest{
 	{struct{}{}, "", nil, 0},
-	{struct{}{}, "foo", nil, 0},
-	{S0{a: 'a'}, "a", []int{0}, 'a'},
-	{S0{}, "d", nil, 0},
-	{S1{S0: S0{a: 'a'}}, "a", []int{1, 0}, 'a'},
-	{S1{b: 'b'}, "b", []int{0}, 'b'},
+	{struct{}{}, "Foo", nil, 0},
+	{S0{A: 'a'}, "A", []int{0}, 'a'},
+	{S0{}, "D", nil, 0},
+	{S1{S0: S0{A: 'a'}}, "A", []int{1, 0}, 'a'},
+	{S1{B: 'b'}, "B", []int{0}, 'b'},
 	{S1{}, "S0", []int{1}, 0},
-	{S1{S0: S0{c: 'c'}}, "c", []int{1, 2}, 'c'},
-	{S2{a: 'a'}, "a", []int{0}, 'a'},
+	{S1{S0: S0{C: 'c'}}, "C", []int{1, 2}, 'c'},
+	{S2{A: 'a'}, "A", []int{0}, 'a'},
 	{S2{}, "S1", []int{1}, 0},
-	{S2{S1: &S1{b: 'b'}}, "b", []int{1, 0}, 'b'},
-	{S2{S1: &S1{S0: S0{c: 'c'}}}, "c", []int{1, 1, 2}, 'c'},
-	{S2{}, "d", nil, 0},
+	{S2{S1: &S1{B: 'b'}}, "B", []int{1, 0}, 'b'},
+	{S2{S1: &S1{S0: S0{C: 'c'}}}, "C", []int{1, 1, 2}, 'c'},
+	{S2{}, "D", nil, 0},
 	{S3{}, "S1", nil, 0},
-	{S3{S2: S2{a: 'a'}}, "a", []int{1, 0}, 'a'},
-	{S3{}, "b", nil, 0},
-	{S3{d: 'd'}, "d", []int{2}, 0},
-	{S3{e: 'e'}, "e", []int{3}, 'e'},
-	{S4{a: 'a'}, "a", []int{1}, 'a'},
-	{S4{}, "b", nil, 0},
+	{S3{S2: S2{A: 'a'}}, "A", []int{1, 0}, 'a'},
+	{S3{}, "B", nil, 0},
+	{S3{D: 'd'}, "D", []int{2}, 0},
+	{S3{E: 'e'}, "E", []int{3}, 'e'},
+	{S4{A: 'a'}, "A", []int{1}, 'a'},
+	{S4{}, "B", nil, 0},
 }
 
 func TestFieldByIndex(t *testing.T) {
@@ -1566,3 +1566,68 @@ func TestTagGet(t *testing.T) {
 		}
 	}
 }
+
+type Private struct {
+	x int
+	y **int
+}
+
+func (p *Private) m() {
+}
+
+type Public struct {
+	X int
+	Y **int
+}
+
+func (p *Public) M() {
+}
+
+func TestUnexported(t *testing.T) {
+	var pub Public
+	v := ValueOf(&pub)
+	isValid(v.Elem().Field(0))
+	isValid(v.Elem().Field(1))
+	isValid(v.Elem().FieldByName("X"))
+	isValid(v.Elem().FieldByName("Y"))
+	isValid(v.Type().Method(0).Func)
+	isNonNil(v.Elem().Field(0).Interface())
+	isNonNil(v.Elem().Field(1).Interface())
+	isNonNil(v.Elem().FieldByName("X").Interface())
+	isNonNil(v.Elem().FieldByName("Y").Interface())
+	isNonNil(v.Type().Method(0).Func.Interface())
+
+	var priv Private
+	v = ValueOf(&priv)
+	isValid(v.Elem().Field(0))
+	isValid(v.Elem().Field(1))
+	isValid(v.Elem().FieldByName("x"))
+	isValid(v.Elem().FieldByName("y"))
+	isValid(v.Type().Method(0).Func)
+	shouldPanic(func() { v.Elem().Field(0).Interface() })
+	shouldPanic(func() { v.Elem().Field(1).Interface() })
+	shouldPanic(func() { v.Elem().FieldByName("x").Interface() })
+	shouldPanic(func() { v.Elem().FieldByName("y").Interface() })
+	shouldPanic(func() { v.Type().Method(0).Func.Interface() })
+}
+
+func shouldPanic(f func()) {
+	defer func() {
+		if recover() == nil {
+			panic("did not panic")
+		}
+	}()
+	f()
+}
+
+func isNonNil(x interface{}) {
+	if x == nil {
+		panic("nil interface")
+	}
+}
+
+func isValid(v Value) {
+	if !v.IsValid() {
+		panic("zero Value")
+	}
+}
Index: libgo/go/fmt/print.go
===================================================================
--- libgo/go/fmt/print.go	(revision 179665)
+++ libgo/go/fmt/print.go	(working copy)
@@ -258,10 +258,8 @@ func Sprintln(a ...interface{}) string {
 // the thing inside the interface, not the interface itself.
 func getField(v reflect.Value, i int) reflect.Value {
 	val := v.Field(i)
-	if i := val; i.Kind() == reflect.Interface {
-		if inter := i.Interface(); inter != nil {
-			return reflect.ValueOf(inter)
-		}
+	if val.Kind() == reflect.Interface && !val.IsNil() {
+		val = val.Elem()
 	}
 	return val
 }
@@ -288,27 +286,32 @@ func (p *pp) unknownType(v interface{}) 
 	p.buf.WriteByte('?')
 }
 
-func (p *pp) badVerb(verb int, val interface{}) {
+func (p *pp) badVerb(verb int, val interface{}, val1 reflect.Value) {
 	p.add('%')
 	p.add('!')
 	p.add(verb)
 	p.add('(')
-	if val == nil {
-		p.buf.Write(nilAngleBytes)
-	} else {
+	switch {
+	case val != nil:
 		p.buf.WriteString(reflect.TypeOf(val).String())
 		p.add('=')
 		p.printField(val, 'v', false, false, 0)
+	case val1.IsValid():
+		p.buf.WriteString(val1.Type().String())
+		p.add('=')
+		p.printValue(val1, 'v', false, false, 0)
+	default:
+		p.buf.Write(nilAngleBytes)
 	}
 	p.add(')')
 }
 
-func (p *pp) fmtBool(v bool, verb int, value interface{}) {
+func (p *pp) fmtBool(v bool, verb int, value interface{}, value1 reflect.Value) {
 	switch verb {
 	case 't', 'v':
 		p.fmt.fmt_boolean(v)
 	default:
-		p.badVerb(verb, value)
+		p.badVerb(verb, value, value1)
 	}
 }
 
@@ -322,7 +325,7 @@ func (p *pp) fmtC(c int64) {
 	p.fmt.pad(p.runeBuf[0:w])
 }
 
-func (p *pp) fmtInt64(v int64, verb int, value interface{}) {
+func (p *pp) fmtInt64(v int64, verb int, value interface{}, value1 reflect.Value) {
 	switch verb {
 	case 'b':
 		p.fmt.integer(v, 2, signed, ldigits)
@@ -336,7 +339,7 @@ func (p *pp) fmtInt64(v int64, verb int,
 		if 0 <= v && v <= unicode.MaxRune {
 			p.fmt.fmt_qc(v)
 		} else {
-			p.badVerb(verb, value)
+			p.badVerb(verb, value, value1)
 		}
 	case 'x':
 		p.fmt.integer(v, 16, signed, ldigits)
@@ -345,7 +348,7 @@ func (p *pp) fmtInt64(v int64, verb int,
 	case 'X':
 		p.fmt.integer(v, 16, signed, udigits)
 	default:
-		p.badVerb(verb, value)
+		p.badVerb(verb, value, value1)
 	}
 }
 
@@ -380,7 +383,7 @@ func (p *pp) fmtUnicode(v int64) {
 	p.fmt.sharp = sharp
 }
 
-func (p *pp) fmtUint64(v uint64, verb int, goSyntax bool, value interface{}) {
+func (p *pp) fmtUint64(v uint64, verb int, goSyntax bool, value interface{}, value1 reflect.Value) {
 	switch verb {
 	case 'b':
 		p.fmt.integer(int64(v), 2, unsigned, ldigits)
@@ -400,7 +403,7 @@ func (p *pp) fmtUint64(v uint64, verb in
 		if 0 <= v && v <= unicode.MaxRune {
 			p.fmt.fmt_qc(int64(v))
 		} else {
-			p.badVerb(verb, value)
+			p.badVerb(verb, value, value1)
 		}
 	case 'x':
 		p.fmt.integer(int64(v), 16, unsigned, ldigits)
@@ -409,11 +412,11 @@ func (p *pp) fmtUint64(v uint64, verb in
 	case 'U':
 		p.fmtUnicode(int64(v))
 	default:
-		p.badVerb(verb, value)
+		p.badVerb(verb, value, value1)
 	}
 }
 
-func (p *pp) fmtFloat32(v float32, verb int, value interface{}) {
+func (p *pp) fmtFloat32(v float32, verb int, value interface{}, value1 reflect.Value) {
 	switch verb {
 	case 'b':
 		p.fmt.fmt_fb32(v)
@@ -428,11 +431,11 @@ func (p *pp) fmtFloat32(v float32, verb 
 	case 'G':
 		p.fmt.fmt_G32(v)
 	default:
-		p.badVerb(verb, value)
+		p.badVerb(verb, value, value1)
 	}
 }
 
-func (p *pp) fmtFloat64(v float64, verb int, value interface{}) {
+func (p *pp) fmtFloat64(v float64, verb int, value interface{}, value1 reflect.Value) {
 	switch verb {
 	case 'b':
 		p.fmt.fmt_fb64(v)
@@ -447,33 +450,33 @@ func (p *pp) fmtFloat64(v float64, verb 
 	case 'G':
 		p.fmt.fmt_G64(v)
 	default:
-		p.badVerb(verb, value)
+		p.badVerb(verb, value, value1)
 	}
 }
 
-func (p *pp) fmtComplex64(v complex64, verb int, value interface{}) {
+func (p *pp) fmtComplex64(v complex64, verb int, value interface{}, value1 reflect.Value) {
 	switch verb {
 	case 'e', 'E', 'f', 'F', 'g', 'G':
 		p.fmt.fmt_c64(v, verb)
 	case 'v':
 		p.fmt.fmt_c64(v, 'g')
 	default:
-		p.badVerb(verb, value)
+		p.badVerb(verb, value, value1)
 	}
 }
 
-func (p *pp) fmtComplex128(v complex128, verb int, value interface{}) {
+func (p *pp) fmtComplex128(v complex128, verb int, value interface{}, value1 reflect.Value) {
 	switch verb {
 	case 'e', 'E', 'f', 'F', 'g', 'G':
 		p.fmt.fmt_c128(v, verb)
 	case 'v':
 		p.fmt.fmt_c128(v, 'g')
 	default:
-		p.badVerb(verb, value)
+		p.badVerb(verb, value, value1)
 	}
 }
 
-func (p *pp) fmtString(v string, verb int, goSyntax bool, value interface{}) {
+func (p *pp) fmtString(v string, verb int, goSyntax bool, value interface{}, value1 reflect.Value) {
 	switch verb {
 	case 'v':
 		if goSyntax {
@@ -490,11 +493,11 @@ func (p *pp) fmtString(v string, verb in
 	case 'q':
 		p.fmt.fmt_q(v)
 	default:
-		p.badVerb(verb, value)
+		p.badVerb(verb, value, value1)
 	}
 }
 
-func (p *pp) fmtBytes(v []byte, verb int, goSyntax bool, depth int, value interface{}) {
+func (p *pp) fmtBytes(v []byte, verb int, goSyntax bool, depth int, value interface{}, value1 reflect.Value) {
 	if verb == 'v' || verb == 'd' {
 		if goSyntax {
 			p.buf.Write(bytesBytes)
@@ -529,7 +532,7 @@ func (p *pp) fmtBytes(v []byte, verb int
 	case 'q':
 		p.fmt.fmt_q(s)
 	default:
-		p.badVerb(verb, value)
+		p.badVerb(verb, value, value1)
 	}
 }
 
@@ -539,12 +542,12 @@ func (p *pp) fmtPointer(field interface{
 	case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer:
 		u = value.Pointer()
 	default:
-		p.badVerb(verb, field)
+		p.badVerb(verb, field, value)
 		return
 	}
 	if goSyntax {
 		p.add('(')
-		p.buf.WriteString(reflect.TypeOf(field).String())
+		p.buf.WriteString(value.Type().String())
 		p.add(')')
 		p.add('(')
 		if u == 0 {
@@ -590,138 +593,192 @@ func (p *pp) catchPanic(val interface{},
 	}
 }
 
-func (p *pp) printField(field interface{}, verb int, plus, goSyntax bool, depth int) (wasString bool) {
-	if field == nil {
-		if verb == 'T' || verb == 'v' {
-			p.buf.Write(nilAngleBytes)
-		} else {
-			p.badVerb(verb, field)
-		}
-		return false
-	}
-
-	// Special processing considerations.
-	// %T (the value's type) and %p (its address) are special; we always do them first.
-	switch verb {
-	case 'T':
-		p.printField(reflect.TypeOf(field).String(), 's', false, false, 0)
-		return false
-	case 'p':
-		p.fmtPointer(field, reflect.ValueOf(field), verb, goSyntax)
-		return false
-	}
+func (p *pp) handleMethods(field interface{}, verb int, plus, goSyntax bool, depth int) (wasString, handled bool) {
 	// Is it a Formatter?
 	if formatter, ok := field.(Formatter); ok {
+		handled = true
+		wasString = false
 		defer p.catchPanic(field, verb)
 		formatter.Format(p, verb)
-		return false // this value is not a string
-
+		return
 	}
 	// Must not touch flags before Formatter looks at them.
 	if plus {
 		p.fmt.plus = false
 	}
+
 	// If we're doing Go syntax and the field knows how to supply it, take care of it now.
 	if goSyntax {
 		p.fmt.sharp = false
 		if stringer, ok := field.(GoStringer); ok {
+			wasString = false
+			handled = true
 			defer p.catchPanic(field, verb)
 			// Print the result of GoString unadorned.
-			p.fmtString(stringer.GoString(), 's', false, field)
-			return false // this value is not a string
+			p.fmtString(stringer.GoString(), 's', false, field, reflect.Value{})
+			return
 		}
 	} else {
 		// Is it a Stringer?
 		if stringer, ok := field.(Stringer); ok {
+			wasString = false
+			handled = true
 			defer p.catchPanic(field, verb)
 			p.printField(stringer.String(), verb, plus, false, depth)
-			return false // this value is not a string
+			return
 		}
 	}
+	handled = false
+	return
+}
+
+func (p *pp) printField(field interface{}, verb int, plus, goSyntax bool, depth int) (wasString bool) {
+	if field == nil {
+		if verb == 'T' || verb == 'v' {
+			p.buf.Write(nilAngleBytes)
+		} else {
+			p.badVerb(verb, field, reflect.Value{})
+		}
+		return false
+	}
+
+	// Special processing considerations.
+	// %T (the value's type) and %p (its address) are special; we always do them first.
+	switch verb {
+	case 'T':
+		p.printField(reflect.TypeOf(field).String(), 's', false, false, 0)
+		return false
+	case 'p':
+		p.fmtPointer(field, reflect.ValueOf(field), verb, goSyntax)
+		return false
+	}
+
+	if wasString, handled := p.handleMethods(field, verb, plus, goSyntax, depth); handled {
+		return wasString
+	}
 
 	// Some types can be done without reflection.
 	switch f := field.(type) {
 	case bool:
-		p.fmtBool(f, verb, field)
+		p.fmtBool(f, verb, field, reflect.Value{})
 		return false
 	case float32:
-		p.fmtFloat32(f, verb, field)
+		p.fmtFloat32(f, verb, field, reflect.Value{})
 		return false
 	case float64:
-		p.fmtFloat64(f, verb, field)
+		p.fmtFloat64(f, verb, field, reflect.Value{})
 		return false
 	case complex64:
-		p.fmtComplex64(complex64(f), verb, field)
+		p.fmtComplex64(complex64(f), verb, field, reflect.Value{})
 		return false
 	case complex128:
-		p.fmtComplex128(f, verb, field)
+		p.fmtComplex128(f, verb, field, reflect.Value{})
 		return false
 	case int:
-		p.fmtInt64(int64(f), verb, field)
+		p.fmtInt64(int64(f), verb, field, reflect.Value{})
 		return false
 	case int8:
-		p.fmtInt64(int64(f), verb, field)
+		p.fmtInt64(int64(f), verb, field, reflect.Value{})
 		return false
 	case int16:
-		p.fmtInt64(int64(f), verb, field)
+		p.fmtInt64(int64(f), verb, field, reflect.Value{})
 		return false
 	case int32:
-		p.fmtInt64(int64(f), verb, field)
+		p.fmtInt64(int64(f), verb, field, reflect.Value{})
 		return false
 	case int64:
-		p.fmtInt64(f, verb, field)
+		p.fmtInt64(f, verb, field, reflect.Value{})
 		return false
 	case uint:
-		p.fmtUint64(uint64(f), verb, goSyntax, field)
+		p.fmtUint64(uint64(f), verb, goSyntax, field, reflect.Value{})
 		return false
 	case uint8:
-		p.fmtUint64(uint64(f), verb, goSyntax, field)
+		p.fmtUint64(uint64(f), verb, goSyntax, field, reflect.Value{})
 		return false
 	case uint16:
-		p.fmtUint64(uint64(f), verb, goSyntax, field)
+		p.fmtUint64(uint64(f), verb, goSyntax, field, reflect.Value{})
 		return false
 	case uint32:
-		p.fmtUint64(uint64(f), verb, goSyntax, field)
+		p.fmtUint64(uint64(f), verb, goSyntax, field, reflect.Value{})
 		return false
 	case uint64:
-		p.fmtUint64(f, verb, goSyntax, field)
+		p.fmtUint64(f, verb, goSyntax, field, reflect.Value{})
 		return false
 	case uintptr:
-		p.fmtUint64(uint64(f), verb, goSyntax, field)
+		p.fmtUint64(uint64(f), verb, goSyntax, field, reflect.Value{})
 		return false
 	case string:
-		p.fmtString(f, verb, goSyntax, field)
+		p.fmtString(f, verb, goSyntax, field, reflect.Value{})
 		return verb == 's' || verb == 'v'
 	case []byte:
-		p.fmtBytes(f, verb, goSyntax, depth, field)
+		p.fmtBytes(f, verb, goSyntax, depth, field, reflect.Value{})
 		return verb == 's'
 	}
 
 	// Need to use reflection
-	value := reflect.ValueOf(field)
+	return p.printReflectValue(reflect.ValueOf(field), verb, plus, goSyntax, depth)
+}
+
+// printValue is like printField but starts with a reflect value, not an interface{} value.
+func (p *pp) printValue(value reflect.Value, verb int, plus, goSyntax bool, depth int) (wasString bool) {
+	if !value.IsValid() {
+		if verb == 'T' || verb == 'v' {
+			p.buf.Write(nilAngleBytes)
+		} else {
+			p.badVerb(verb, nil, value)
+		}
+		return false
+	}
 
+	// Special processing considerations.
+	// %T (the value's type) and %p (its address) are special; we always do them first.
+	switch verb {
+	case 'T':
+		p.printField(value.Type().String(), 's', false, false, 0)
+		return false
+	case 'p':
+		p.fmtPointer(nil, value, verb, goSyntax)
+		return false
+	}
+
+	// Handle values with special methods.
+	// Call always, even when field == nil, because handleMethods clears p.fmt.plus for us.
+	var field interface{}
+	if value.CanInterface() {
+		field = value.Interface()
+	}
+	if wasString, handled := p.handleMethods(field, verb, plus, goSyntax, depth); handled {
+		return wasString
+	}
+
+	return p.printReflectValue(value, verb, plus, goSyntax, depth)
+}
+
+// printReflectValue is the fallback for both printField and printValue.
+// It uses reflect to print the value.
+func (p *pp) printReflectValue(value reflect.Value, verb int, plus, goSyntax bool, depth int) (wasString bool) {
 BigSwitch:
 	switch f := value; f.Kind() {
 	case reflect.Bool:
-		p.fmtBool(f.Bool(), verb, field)
+		p.fmtBool(f.Bool(), verb, nil, value)
 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		p.fmtInt64(f.Int(), verb, field)
+		p.fmtInt64(f.Int(), verb, nil, value)
 	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		p.fmtUint64(uint64(f.Uint()), verb, goSyntax, field)
+		p.fmtUint64(uint64(f.Uint()), verb, goSyntax, nil, value)
 	case reflect.Float32, reflect.Float64:
 		if f.Type().Size() == 4 {
-			p.fmtFloat32(float32(f.Float()), verb, field)
+			p.fmtFloat32(float32(f.Float()), verb, nil, value)
 		} else {
-			p.fmtFloat64(float64(f.Float()), verb, field)
+			p.fmtFloat64(float64(f.Float()), verb, nil, value)
 		}
 	case reflect.Complex64, reflect.Complex128:
 		if f.Type().Size() == 8 {
-			p.fmtComplex64(complex64(f.Complex()), verb, field)
+			p.fmtComplex64(complex64(f.Complex()), verb, nil, value)
 		} else {
-			p.fmtComplex128(complex128(f.Complex()), verb, field)
+			p.fmtComplex128(complex128(f.Complex()), verb, nil, value)
 		}
 	case reflect.String:
-		p.fmtString(f.String(), verb, goSyntax, field)
+		p.fmtString(f.String(), verb, goSyntax, nil, value)
 	case reflect.Map:
 		if goSyntax {
 			p.buf.WriteString(f.Type().String())
@@ -738,9 +795,9 @@ BigSwitch:
 					p.buf.WriteByte(' ')
 				}
 			}
-			p.printField(key.Interface(), verb, plus, goSyntax, depth+1)
+			p.printValue(key, verb, plus, goSyntax, depth+1)
 			p.buf.WriteByte(':')
-			p.printField(f.MapIndex(key).Interface(), verb, plus, goSyntax, depth+1)
+			p.printValue(f.MapIndex(key), verb, plus, goSyntax, depth+1)
 		}
 		if goSyntax {
 			p.buf.WriteByte('}')
@@ -749,7 +806,7 @@ BigSwitch:
 		}
 	case reflect.Struct:
 		if goSyntax {
-			p.buf.WriteString(reflect.TypeOf(field).String())
+			p.buf.WriteString(value.Type().String())
 		}
 		p.add('{')
 		v := f
@@ -768,20 +825,20 @@ BigSwitch:
 					p.buf.WriteByte(':')
 				}
 			}
-			p.printField(getField(v, i).Interface(), verb, plus, goSyntax, depth+1)
+			p.printValue(getField(v, i), verb, plus, goSyntax, depth+1)
 		}
 		p.buf.WriteByte('}')
 	case reflect.Interface:
 		value := f.Elem()
 		if !value.IsValid() {
 			if goSyntax {
-				p.buf.WriteString(reflect.TypeOf(field).String())
+				p.buf.WriteString(value.Type().String())
 				p.buf.Write(nilParenBytes)
 			} else {
 				p.buf.Write(nilAngleBytes)
 			}
 		} else {
-			return p.printField(value.Interface(), verb, plus, goSyntax, depth+1)
+			return p.printValue(value, verb, plus, goSyntax, depth+1)
 		}
 	case reflect.Array, reflect.Slice:
 		// Byte slices are special.
@@ -797,11 +854,11 @@ BigSwitch:
 			for i := range bytes {
 				bytes[i] = byte(f.Index(i).Uint())
 			}
-			p.fmtBytes(bytes, verb, goSyntax, depth, field)
+			p.fmtBytes(bytes, verb, goSyntax, depth, nil, value)
 			return verb == 's'
 		}
 		if goSyntax {
-			p.buf.WriteString(reflect.TypeOf(field).String())
+			p.buf.WriteString(value.Type().String())
 			p.buf.WriteByte('{')
 		} else {
 			p.buf.WriteByte('[')
@@ -814,7 +871,7 @@ BigSwitch:
 					p.buf.WriteByte(' ')
 				}
 			}
-			p.printField(f.Index(i).Interface(), verb, plus, goSyntax, depth+1)
+			p.printValue(f.Index(i), verb, plus, goSyntax, depth+1)
 		}
 		if goSyntax {
 			p.buf.WriteByte('}')
@@ -829,17 +886,17 @@ BigSwitch:
 			switch a := f.Elem(); a.Kind() {
 			case reflect.Array, reflect.Slice:
 				p.buf.WriteByte('&')
-				p.printField(a.Interface(), verb, plus, goSyntax, depth+1)
+				p.printValue(a, verb, plus, goSyntax, depth+1)
 				break BigSwitch
 			case reflect.Struct:
 				p.buf.WriteByte('&')
-				p.printField(a.Interface(), verb, plus, goSyntax, depth+1)
+				p.printValue(a, verb, plus, goSyntax, depth+1)
 				break BigSwitch
 			}
 		}
 		if goSyntax {
 			p.buf.WriteByte('(')
-			p.buf.WriteString(reflect.TypeOf(field).String())
+			p.buf.WriteString(value.Type().String())
 			p.buf.WriteByte(')')
 			p.buf.WriteByte('(')
 			if v == 0 {
@@ -856,7 +913,7 @@ BigSwitch:
 		}
 		p.fmt0x64(uint64(v), true)
 	case reflect.Chan, reflect.Func, reflect.UnsafePointer:
-		p.fmtPointer(field, value, verb, goSyntax)
+		p.fmtPointer(nil, value, verb, goSyntax)
 	default:
 		p.unknownType(f)
 	}
Index: libgo/go/fmt/fmt_test.go
===================================================================
--- libgo/go/fmt/fmt_test.go	(revision 179665)
+++ libgo/go/fmt/fmt_test.go	(working copy)
@@ -61,7 +61,7 @@ type I int
 func (i I) String() string { return Sprintf("<%d>", int(i)) }
 
 type B struct {
-	i I
+	I I
 	j int
 }
 
@@ -83,8 +83,8 @@ func (g G) GoString() string {
 }
 
 type S struct {
-	f F // a struct field that Formats
-	g G // a struct field that GoStrings
+	F F // a struct field that Formats
+	G G // a struct field that GoStrings
 }
 
 // A type with a String method with pointer receiver for testing %p
@@ -332,8 +332,8 @@ var fmttests = []struct {
 	{"%+v", A{1, 2, "a", []int{1, 2}}, `{i:1 j:2 s:a x:[1 2]}`},
 
 	// +v on structs with Stringable items
-	{"%+v", B{1, 2}, `{i:<1> j:2}`},
-	{"%+v", C{1, B{2, 3}}, `{i:1 B:{i:<2> j:3}}`},
+	{"%+v", B{1, 2}, `{I:<1> j:2}`},
+	{"%+v", C{1, B{2, 3}}, `{i:1 B:{I:<2> j:3}}`},
 
 	// q on Stringable items
 	{"%s", I(23), `<23>`},
@@ -349,7 +349,7 @@ var fmttests = []struct {
 	{"%#v", uint64(1<<64 - 1), "0xffffffffffffffff"},
 	{"%#v", 1000000000, "1000000000"},
 	{"%#v", map[string]int{"a": 1, "b": 2}, `map[string] int{"a":1, "b":2}`},
-	{"%#v", map[string]B{"a": {1, 2}, "b": {3, 4}}, `map[string] fmt_test.B{"a":fmt_test.B{i:1, j:2}, "b":fmt_test.B{i:3, j:4}}`},
+	{"%#v", map[string]B{"a": {1, 2}, "b": {3, 4}}, `map[string] fmt_test.B{"a":fmt_test.B{I:1, j:2}, "b":fmt_test.B{I:3, j:4}}`},
 	{"%#v", []string{"a", "b"}, `[]string{"a", "b"}`},
 
 	// slices with other formats
@@ -384,11 +384,11 @@ var fmttests = []struct {
 	// Formatter
 	{"%x", F(1), "<x=F(1)>"},
 	{"%x", G(2), "2"},
-	{"%+v", S{F(4), G(5)}, "{f:<v=F(4)> g:5}"},
+	{"%+v", S{F(4), G(5)}, "{F:<v=F(4)> G:5}"},
 
 	// GoStringer
 	{"%#v", G(6), "GoString(6)"},
-	{"%#v", S{F(7), G(8)}, "fmt_test.S{f:<v=F(7)>, g:GoString(8)}"},
+	{"%#v", S{F(7), G(8)}, "fmt_test.S{F:<v=F(7)>, G:GoString(8)}"},
 
 	// %T
 	{"%T", (4 - 3i), "complex128"},
Index: libgo/go/go/ast/print_test.go
===================================================================
--- libgo/go/go/ast/print_test.go	(revision 179665)
+++ libgo/go/go/ast/print_test.go	(working copy)
@@ -41,10 +41,10 @@ var tests = []struct {
 		4  }`},
 
 	// structs
-	{struct{ x, y int }{42, 991},
-		`0  struct { x int; y int } {
-		1  .  x: 42
-		2  .  y: 991
+	{struct{ X, Y int }{42, 991},
+		`0  struct { X int; Y int } {
+		1  .  X: 42
+		2  .  Y: 991
 		3  }`},
 }
 
Index: libgo/Makefile.am
===================================================================
--- libgo/Makefile.am	(revision 179665)
+++ libgo/Makefile.am	(working copy)
@@ -242,7 +242,6 @@ toolexeclibgoencoding_DATA = \
 toolexeclibgoexpdir = $(toolexeclibgodir)/exp
 
 toolexeclibgoexp_DATA = \
-	exp/datafmt.gox \
 	exp/gui.gox \
 	exp/norm.gox \
 	exp/regexp.gox
@@ -1196,9 +1195,6 @@ go_encoding_hex_files = \
 go_encoding_pem_files = \
 	go/encoding/pem/pem.go
 
-go_exp_datafmt_files = \
-	go/exp/datafmt/datafmt.go \
-	go/exp/datafmt/parser.go
 go_exp_gui_files = \
 	go/exp/gui/gui.go
 go_exp_norm_files = \
@@ -1666,7 +1662,6 @@ libgo_go_objs = \
 	encoding/git85.lo \
 	encoding/hex.lo \
 	encoding/pem.lo \
-	exp/datafmt.lo \
 	exp/gui.lo \
 	exp/norm.lo \
 	exp/regexp.lo \
@@ -2592,15 +2587,6 @@ encoding/pem/check: $(CHECK_DEPS)
 	@$(CHECK)
 .PHONY: encoding/pem/check
 
-exp/datafmt.lo: $(go_exp_datafmt_files) bytes.gox fmt.gox go/scanner.gox \
-		go/token.gox io.gox os.gox reflect.gox runtime.gox \
-		strconv.gox strings.gox
-	$(BUILDPACKAGE)
-exp/datafmt/check: $(CHECK_DEPS)
-	@$(MKDIR_P) exp/datafmt
-	@$(CHECK)
-.PHONY: exp/datafmt/check
-
 exp/gui.lo: $(go_exp_gui_files) image.gox image/draw.gox os.gox
 	$(BUILDPACKAGE)
 exp/gui/check: $(CHECK_DEPS)
@@ -3234,8 +3220,6 @@ encoding/hex.gox: encoding/hex.lo
 encoding/pem.gox: encoding/pem.lo
 	$(BUILDGOX)
 
-exp/datafmt.gox: exp/datafmt.lo
-	$(BUILDGOX)
 exp/gui.gox: exp/gui.lo
 	$(BUILDGOX)
 exp/norm.gox: exp/norm.lo
@@ -3461,7 +3445,6 @@ TEST_PACKAGES = \
 	encoding/git85/check \
 	encoding/hex/check \
 	encoding/pem/check \
-	exp/datafmt/check \
 	exp/norm/check \
 	exp/regexp/check \
 	exp/regexp/syntax/check \
Index: gcc/testsuite/go.test/test/interface/fake.go
===================================================================
--- gcc/testsuite/go.test/test/interface/fake.go	(revision 179665)
+++ gcc/testsuite/go.test/test/interface/fake.go	(working copy)
@@ -12,20 +12,20 @@ package main
 import "reflect"
 
 type T struct {
-	f float32
-	g float32
+	F float32
+	G float32
 
-	s string
-	t string
+	S string
+	T string
 
-	u uint32
-	v uint32
+	U uint32
+	V uint32
 
-	w uint32
-	x uint32
+	W uint32
+	X uint32
 
-	y uint32
-	z uint32
+	Y uint32
+	Z uint32
 }
 
 func add(s, t string) string {
@@ -40,16 +40,16 @@ func assert(b bool) {
 
 func main() {
 	var x T
-	x.f = 1.0
-	x.g = x.f
-	x.s = add("abc", "def")
-	x.t = add("abc", "def")
-	x.u = 1
-	x.v = 2
-	x.w = 1 << 28
-	x.x = 2 << 28
-	x.y = 0x12345678
-	x.z = x.y
+	x.F = 1.0
+	x.G = x.F
+	x.S = add("abc", "def")
+	x.T = add("abc", "def")
+	x.U = 1
+	x.V = 2
+	x.W = 1 << 28
+	x.X = 2 << 28
+	x.Y = 0x12345678
+	x.Z = x.Y
 
 	// check mem and string
 	v := reflect.ValueOf(x)

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2011-10-22 16:21 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-10-22 20:16 Go patch committed: Update libgo to r60.3 release Ian Lance Taylor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).