compiler: fix interface lowering miscompilation with reflect

When using reflect, arbitrary types can be synthesized. This invalidates
a few assumptions in the interface-lowering pass, that think they can
see all types that are in use in a program and optimize accordingly.

The file size impact depends on the specific program. Sometimes it's
nonexistent, sometimes it's rather hefty (up to 30% bigger). Especially
the samd21 targets seem to be affected, with a 2000-6000 bytes increase
in code size. A moderately large case (the stdlib test) increases by
4%/6%/15% depending on the target.

I hope that this increase could be mitigated, but I don't see an obvious
way to do that.
This commit is contained in:
Ayke van Laethem
2019-09-24 13:48:42 +02:00
committed by Jaden Weiss
parent 4339cbd56f
commit a7794de99d
3 changed files with 22 additions and 43 deletions
+12
View File
@@ -254,6 +254,16 @@ func main() {
if rv.Len() != 2 || rv.Index(0).Int() != 3 {
panic("slice was changed while setting part of it")
}
// Test types that are created in reflect and never created elsewhere in a
// value-to-interface conversion.
v := reflect.ValueOf(new(unreferencedType))
switch v.Elem().Interface().(type) {
case unreferencedType:
println("type assertion succeeded for unreferenced type")
default:
println("type assertion failed (but should succeed)")
}
}
func emptyFunc() {
@@ -340,3 +350,5 @@ func assertSize(ok bool, typ string) {
panic("size mismatch for type " + typ)
}
}
type unreferencedType int
+1
View File
@@ -335,3 +335,4 @@ float32 4 32
float64 8 64
complex64 8 64
complex128 16 128
type assertion succeeded for unreferenced type