compiler: fix assertion on empty interface

This fixes issue #453.
Этот коммит содержится в:
Ayke van Laethem 2019-12-26 01:32:58 +01:00 коммит произвёл Ron Evans
родитель 3656ac2fc9
коммит 14474e7099
2 изменённых файлов: 9 добавлений и 3 удалений

Просмотреть файл

@ -279,14 +279,14 @@ func (c *Compiler) getInterfaceMethodSet(typ *types.Named) llvm.Value {
return llvm.ConstGEP(global, []llvm.Value{zero, zero}) return llvm.ConstGEP(global, []llvm.Value{zero, zero})
} }
// Every method is a *i16 reference indicating the signature of this method. // Every method is a *i8 reference indicating the signature of this method.
methods := make([]llvm.Value, typ.Underlying().(*types.Interface).NumMethods()) methods := make([]llvm.Value, typ.Underlying().(*types.Interface).NumMethods())
for i := range methods { for i := range methods {
method := typ.Underlying().(*types.Interface).Method(i) method := typ.Underlying().(*types.Interface).Method(i)
methods[i] = c.getMethodSignature(method) methods[i] = c.getMethodSignature(method)
} }
value := llvm.ConstArray(methods[0].Type(), methods) value := llvm.ConstArray(c.i8ptrType, methods)
global = llvm.AddGlobal(c.mod, value.Type(), typ.String()+"$interface") global = llvm.AddGlobal(c.mod, value.Type(), typ.String()+"$interface")
global.SetInitializer(value) global.SetInitializer(value)
global.SetGlobalConstant(true) global.SetGlobalConstant(true)
@ -295,7 +295,7 @@ func (c *Compiler) getInterfaceMethodSet(typ *types.Named) llvm.Value {
} }
// getMethodSignature returns a global variable which is a reference to an // getMethodSignature returns a global variable which is a reference to an
// external *i16 indicating the indicating the signature of this method. It is // external *i8 indicating the indicating the signature of this method. It is
// used during the interface lowering pass. // used during the interface lowering pass.
func (c *Compiler) getMethodSignature(method *types.Func) llvm.Value { func (c *Compiler) getMethodSignature(method *types.Func) llvm.Value {
signature := ir.MethodSignature(method) signature := ir.MethodSignature(method)

6
testdata/interface.go предоставленный
Просмотреть файл

@ -33,6 +33,10 @@ func main() {
// https://github.com/tinygo-org/tinygo/issues/309 // https://github.com/tinygo-org/tinygo/issues/309
itf = linkedList{} itf = linkedList{}
// Test bugfix for assertion on named empty interface:
// https://github.com/tinygo-org/tinygo/issues/453
_, _ = itf.(Empty)
var n int var n int
var f float32 var f float32
var interfaceEqualTests = []struct { var interfaceEqualTests = []struct {
@ -251,3 +255,5 @@ func (s SleepBlocker) Sleep() {
type StaticBlocker interface { type StaticBlocker interface {
Sleep() Sleep()
} }
type Empty interface{}