From 99a41bec4e8c41c0179a56686bdeed896d6aa5a3 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Sun, 4 Apr 2021 16:33:53 +0200 Subject: [PATCH] transform: fix bug in interface lowering when signatures are renamed In rare cases the signature might change as a result of LLVM renaming some named struct types when multiple LLVM modules are merged. The easiest workaround is to detect such mismatched signatures and adding a bitcast: this should be safe as the underlying data is effectively of the same type. --- transform/interface-lowering.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/transform/interface-lowering.go b/transform/interface-lowering.go index 3da4f0f4..56956a39 100644 --- a/transform/interface-lowering.go +++ b/transform/interface-lowering.go @@ -703,6 +703,20 @@ func (p *lowerInterfacesPass) createInterfaceMethodFunc(itf *interfaceInfo, sign // function. receiver = p.builder.CreateBitCast(receiver, function.FirstParam().Type(), "") } + + // Check whether the called function has the same signature as would be + // expected from the parameters. This can happen in rare cases when + // named struct types are renamed after merging multiple LLVM modules. + paramTypes := []llvm.Type{receiver.Type()} + for _, param := range params { + paramTypes = append(paramTypes, param.Type()) + } + calledFunctionType := function.Type() + sig := llvm.PointerType(llvm.FunctionType(calledFunctionType.ElementType().ReturnType(), paramTypes, false), calledFunctionType.PointerAddressSpace()) + if sig != function.Type() { + function = p.builder.CreateBitCast(function, sig, "") + } + retval := p.builder.CreateCall(function, append([]llvm.Value{receiver}, params...), "") if retval.Type().TypeKind() == llvm.VoidTypeKind { p.builder.CreateRetVoid()