]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: strengthen SetFields/Width safety guarantee
authorJosh Bleecher Snyder <josharian@gmail.com>
Thu, 23 Mar 2017 18:40:47 +0000 (11:40 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Thu, 23 Mar 2017 19:16:27 +0000 (19:16 +0000)
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>
src/cmd/compile/internal/gc/closure.go
src/cmd/compile/internal/gc/type.go

index 41ee74b8e033218ce5df62b4ca0f9c1e2fb7f7e0..9f0c073454168e08b122255672c607517b086115 100644 (file)
@@ -362,10 +362,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 {
index 49d222507bf11f9328c4e864cda3dcd7e9a98dac..772894f076cc75875165fab3fcc94cc7be6982c0 100644 (file)
@@ -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