cmd/gc: pad structs which end in zero-sized fields

For a non-zero-sized struct with a final zero-sized field,
add a byte to the size (before rounding to alignment).  This
change ensures that taking the address of the zero-sized field
will not incorrectly leak the following object in memory.

reflect.funcLayout also needs this treatment.

Fixes #9401

Change-Id: I1dc503dc5af4ca22c8f8c048fb7b4541cc957e0f
Reviewed-on: https://go-review.googlesource.com/2452
Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
Keith Randall 2015-01-07 09:25:23 -08:00
parent 654a185f20
commit 6f07ac2f28
3 changed files with 69 additions and 8 deletions

View file

@ -247,3 +247,44 @@ func TestEqString(t *testing.T) {
}
}
}
func TestTrailingZero(t *testing.T) {
// make sure we add padding for structs with trailing zero-sized fields
type T1 struct {
n int32
z [0]byte
}
if unsafe.Sizeof(T1{}) != 8 {
t.Errorf("sizeof(%#v)==%d, want 8", T1{}, unsafe.Sizeof(T1{}))
}
type T2 struct {
n int64
z struct{}
}
if unsafe.Sizeof(T2{}) != 16 {
t.Errorf("sizeof(%#v)==%d, want 16", T2{}, unsafe.Sizeof(T2{}))
}
type T3 struct {
n byte
z [4]struct{}
}
if unsafe.Sizeof(T3{}) != 2 {
t.Errorf("sizeof(%#v)==%d, want 2", T3{}, unsafe.Sizeof(T3{}))
}
// make sure padding can double for both zerosize and alignment
type T4 struct {
a int32
b int16
c int8
z struct{}
}
if unsafe.Sizeof(T4{}) != 8 {
t.Errorf("sizeof(%#v)==%d, want 8", T4{}, unsafe.Sizeof(T4{}))
}
// make sure we don't pad a zero-sized thing
type T5 struct {
}
if unsafe.Sizeof(T5{}) != 0 {
t.Errorf("sizeof(%#v)==%d, want 0", T5{}, unsafe.Sizeof(T5{}))
}
}