gob: send empty but non-nil maps.
Fixes #2082.

R=golang-dev, dsymonds, r
CC=golang-dev
https://golang.org/cl/4798042
diff --git a/src/pkg/gob/codec_test.go b/src/pkg/gob/codec_test.go
index 03fec26..a5fb91c 100644
--- a/src/pkg/gob/codec_test.go
+++ b/src/pkg/gob/codec_test.go
@@ -573,30 +573,32 @@
 	s1 := "string1"
 	s2 := "string2"
 	type T1 struct {
-		A, B, C int
-		M       map[string]*float64
-		N       *[3]float64
-		Strs    *[2]string
-		Int64s  *[]int64
-		RI      complex64
-		S       string
-		Y       []byte
-		T       *T2
+		A, B, C  int
+		M        map[string]*float64
+		EmptyMap map[string]int // to check that we receive a non-nil map.
+		N        *[3]float64
+		Strs     *[2]string
+		Int64s   *[]int64
+		RI       complex64
+		S        string
+		Y        []byte
+		T        *T2
 	}
 	pi := 3.14159
 	e := 2.71828
 	t1 := &T1{
-		A:      17,
-		B:      18,
-		C:      -5,
-		M:      map[string]*float64{"pi": &pi, "e": &e},
-		N:      &[3]float64{1.5, 2.5, 3.5},
-		Strs:   &[2]string{s1, s2},
-		Int64s: &[]int64{77, 89, 123412342134},
-		RI:     17 - 23i,
-		S:      "Now is the time",
-		Y:      []byte("hello, sailor"),
-		T:      &T2{"this is T2"},
+		A:        17,
+		B:        18,
+		C:        -5,
+		M:        map[string]*float64{"pi": &pi, "e": &e},
+		EmptyMap: make(map[string]int),
+		N:        &[3]float64{1.5, 2.5, 3.5},
+		Strs:     &[2]string{s1, s2},
+		Int64s:   &[]int64{77, 89, 123412342134},
+		RI:       17 - 23i,
+		S:        "Now is the time",
+		Y:        []byte("hello, sailor"),
+		T:        &T2{"this is T2"},
 	}
 	b := new(bytes.Buffer)
 	err := NewEncoder(b).Encode(t1)
@@ -611,6 +613,13 @@
 	if !reflect.DeepEqual(t1, &_t1) {
 		t.Errorf("encode expected %v got %v", *t1, _t1)
 	}
+	// Be absolutely sure the received map is non-nil.
+	if t1.EmptyMap == nil {
+		t.Errorf("nil map sent")
+	}
+	if _t1.EmptyMap == nil {
+		t.Errorf("nil map received")
+	}
 }
 
 func TestOverflow(t *testing.T) {
diff --git a/src/pkg/gob/doc.go b/src/pkg/gob/doc.go
index aaf429c..35d882a 100644
--- a/src/pkg/gob/doc.go
+++ b/src/pkg/gob/doc.go
@@ -113,6 +113,11 @@
 All other slices and arrays are sent as an unsigned count followed by that many
 elements using the standard gob encoding for their type, recursively.
 
+Maps are sent as an unsigned count followed by that man key, element
+pairs. Empty but non-nil maps are sent, so if the sender has allocated
+a map, the receiver will allocate a map even no elements are
+transmitted.
+
 Structs are sent as a sequence of (field number, field value) pairs.  The field
 value is sent using the standard gob encoding for its type, recursively.  If a
 field has the zero value for its type, it is omitted from the transmission.  The
diff --git a/src/pkg/gob/encode.go b/src/pkg/gob/encode.go
index 7845598..c4c8219 100644
--- a/src/pkg/gob/encode.go
+++ b/src/pkg/gob/encode.go
@@ -557,7 +557,9 @@
 				// the iteration.
 				v := reflect.ValueOf(unsafe.Unreflect(t, unsafe.Pointer(p)))
 				mv := reflect.Indirect(v)
-				if !state.sendZero && mv.Len() == 0 {
+				// We send zero-length (but non-nil) maps because the
+				// receiver might want to use the map.  (Maps don't use append.)
+				if !state.sendZero && mv.IsNil() {
 					return
 				}
 				state.update(i)