encoding/xml: allow attributes stored in pointers to be marshaled.

Fixes #5334.

R=golang-dev, dave, rsc
CC=golang-dev
https://golang.org/cl/8653047
diff --git a/src/pkg/encoding/xml/marshal.go b/src/pkg/encoding/xml/marshal.go
index 47b0017..fae0f6a 100644
--- a/src/pkg/encoding/xml/marshal.go
+++ b/src/pkg/encoding/xml/marshal.go
@@ -271,7 +271,7 @@
 			continue
 		}
 		fv := finfo.value(val)
-		if finfo.flags&fOmitEmpty != 0 && isEmptyValue(fv) {
+		if (finfo.flags&fOmitEmpty != 0 || fv.Kind() == reflect.Ptr) && isEmptyValue(fv) {
 			continue
 		}
 		p.WriteByte(' ')
@@ -285,6 +285,11 @@
 		}
 		p.WriteString(finfo.name)
 		p.WriteString(`="`)
+		// Handle pointer values by following the pointer,
+		// Pointer is known to be non-nil because we called isEmptyValue above.
+		if fv.Kind() == reflect.Ptr {
+			fv = fv.Elem()
+		}
 		if err := p.marshalSimple(fv.Type(), fv); err != nil {
 			return err
 		}
@@ -363,6 +368,10 @@
 			continue
 		}
 		vf := finfo.value(val)
+		// Handle pointer values by following the pointer
+		if vf.Kind() == reflect.Ptr && !isEmptyValue(vf) {
+			vf = vf.Elem()
+		}
 		switch finfo.flags & fMode {
 		case fCharData:
 			var scratch [64]byte
diff --git a/src/pkg/encoding/xml/marshal_test.go b/src/pkg/encoding/xml/marshal_test.go
index ca14a1e..fa2ba52 100644
--- a/src/pkg/encoding/xml/marshal_test.go
+++ b/src/pkg/encoding/xml/marshal_test.go
@@ -276,6 +276,25 @@
 	X []string `xml:"A>B,omitempty"`
 }
 
+type PointerFieldsTest struct {
+	XMLName  Name    `xml:"dummy"`
+	Name     *string `xml:"name,attr"`
+	Age      *uint   `xml:"age,attr"`
+	Empty    *string `xml:"empty,attr"`
+	Contents *string `xml:",chardata"`
+}
+
+type ChardataEmptyTest struct {
+	XMLName  Name    `xml:"test"`
+	Contents *string `xml:",chardata"`
+}
+
+var (
+	nameAttr     = "Sarah"
+	ageAttr      = uint(12)
+	contentsAttr = "lorem ipsum"
+)
+
 // Unless explicitly stated as such (or *Plain), all of the
 // tests below are two-way tests. When introducing new tests,
 // please try to make them two-way as well to ensure that
@@ -673,6 +692,20 @@
 		ExpectXML: `<OmitAttrTest></OmitAttrTest>`,
 	},
 
+	// pointer fields
+	{
+		Value:       &PointerFieldsTest{Name: &nameAttr, Age: &ageAttr, Contents: &contentsAttr},
+		ExpectXML:   `<dummy name="Sarah" age="12">lorem ipsum</dummy>`,
+		MarshalOnly: true,
+	},
+
+	// empty chardata pointer field
+	{
+		Value:       &ChardataEmptyTest{},
+		ExpectXML:   `<test></test>`,
+		MarshalOnly: true,
+	},
+
 	// omitempty on fields
 	{
 		Value: &OmitFieldTest{