mirror of
https://github.com/golang/go
synced 2024-11-18 08:44:43 -07:00
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. Change-Id: Ic1578ca014610197cfe54a9f4d044d122a7217e8 Reviewed-on: https://go-review.googlesource.com/38469 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
7ac2e413eb
commit
b1b4f67169
@ -362,10 +362,6 @@ func transformclosure(xfunc *Node) {
|
|||||||
xfunc.Func.Dcl = append(decls, xfunc.Func.Dcl...)
|
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)
|
dowidth(f.Type)
|
||||||
xfunc.Type = f.Type // update type of ODCLFUNC
|
xfunc.Type = f.Type // update type of ODCLFUNC
|
||||||
} else {
|
} else {
|
||||||
|
@ -864,6 +864,15 @@ func (t *Type) FieldSlice() []*Field {
|
|||||||
|
|
||||||
// SetFields sets struct/interface type t's fields/methods to fields.
|
// SetFields sets struct/interface type t's fields/methods to fields.
|
||||||
func (t *Type) SetFields(fields []*Field) {
|
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)
|
t.wantEtype(TSTRUCT)
|
||||||
for _, f := range fields {
|
for _, f := range fields {
|
||||||
// If type T contains a field F with a go:notinheap
|
// If type T contains a field F with a go:notinheap
|
||||||
|
Loading…
Reference in New Issue
Block a user