Skip to content

compiler: interface typecodes are not passed through defer frames #1033

@asdine

Description

@asdine

I encountered a really weird compilation error, I tried to simplify the code to find the root cause and this is the best I could do:

package main

func main() {
	foo(nil)
}

type Bar struct {
	empty bool
}

func (b *Bar) Close() error {
	return nil
}

type Closer interface {
	Close() error
}

func foo(bar *Bar) error {
	var a int
	// replacing this condition with something simpler (i.e. nb > 10)
	// works fine
	if !bar.empty {
		a = 10
		// this inner branching is important
		if a != 5 {
			return nil
		}
	}

	var c Closer = bar
	// calling defer on an interface method + the branching above causes the bug
	// Replacing this line by func() { b.Close() }() works though
	defer c.Close()

	return nil
}

This causes the following compilation error:

Instruction does not dominate all uses!
  %3 = insertvalue %runtime._interface { i32 ptrtoint (%runtime.typeInInterface* @"typeInInterface:reflect/types.type:pointer:named:exp.Bar" to i32), i8* undef }, i8* %pack.ptr, 1
  %invoke.typecode16 = extractvalue %runtime._interface %3, 0
Instruction does not dominate all uses!
  %3 = insertvalue %runtime._interface { i32 ptrtoint (%runtime.typeInInterface* @"typeInInterface:reflect/types.type:pointer:named:exp.Bar" to i32), i8* undef }, i8* %pack.ptr, 1
  %invoke.func.receiver19 = extractvalue %runtime._interface %3, 1
error: verification error after IR construction

I compiled to wasm using the 0.12.0 docker image with the following params:

docker run ... \
    tinygo/tinygo:0.12.0 tinygo build -o /dist/exp.wasm -target wasm --no-debug exp

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions