Commit 8ee2d5bc authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder

cmd/compile: strengthen SetFields/Width safety guarantee

It is currently possible in the compiler to create a struct type,
calculate the widths of types that depend on it,
and then alter the struct type.

transformclosure has local protection against this.
Protect against it at a deeper level.

This is preparation to call dowidth automatically,
rather than explicitly.

This is a re-roll of CL 38469.

Change-Id: Ic5b4baa250618504611fc57cbf51ab01d1eddf80
Reviewed-on: https://go-review.googlesource.com/38534
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarMatthew Dempsky <mdempsky@google.com>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 8dafdb1b
......@@ -364,10 +364,6 @@ func transformclosure(xfunc *Node) {
xfunc.Func.Dcl = append(decls, xfunc.Func.Dcl...)
}
// Recalculate param offsets.
if f.Type.Width > 0 {
Fatalf("transformclosure: width is already calculated")
}
dowidth(f.Type)
xfunc.Type = f.Type // update type of ODCLFUNC
} else {
......
......@@ -864,6 +864,15 @@ func (t *Type) FieldSlice() []*Field {
// SetFields sets struct/interface type t's fields/methods to fields.
func (t *Type) SetFields(fields []*Field) {
// If we've calculated the width of t before,
// then some other type such as a function signature
// might now have the wrong type.
// Rather than try to track and invalidate those,
// enforce that SetFields cannot be called once
// t's width has been calculated.
if t.WidthCalculated() {
Fatalf("SetFields of %v: width previously calculated", t)
}
t.wantEtype(TSTRUCT)
for _, f := range fields {
// If type T contains a field F with a go:notinheap
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment