Skip to content

Commit 3071e33

Browse files
jakebaileydeadprogram
authored andcommitted
compiler: key deferInvokeFuncs on distinct name
1 parent b536dd6 commit 3071e33

3 files changed

Lines changed: 51 additions & 6 deletions

File tree

compiler/defer.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -372,12 +372,12 @@ func (b *builder) createDefer(instr *ssa.Defer) {
372372
// Method call on an interface.
373373

374374
// Get callback type number.
375-
methodName := instr.Call.Method.FullName()
376-
if _, ok := b.deferInvokeFuncs[methodName]; !ok {
377-
b.deferInvokeFuncs[methodName] = len(b.allDeferFuncs)
375+
key := b.getInvokeFunctionName(&instr.Call)
376+
if _, ok := b.deferInvokeFuncs[key]; !ok {
377+
b.deferInvokeFuncs[key] = len(b.allDeferFuncs)
378378
b.allDeferFuncs = append(b.allDeferFuncs, &instr.Call)
379379
}
380-
callback := llvm.ConstInt(b.uintptrType, uint64(b.deferInvokeFuncs[methodName]), false)
380+
callback := llvm.ConstInt(b.uintptrType, uint64(b.deferInvokeFuncs[key]), false)
381381

382382
// Collect all values to be put in the struct (starting with
383383
// runtime._defer fields, followed by the call parameters).

compiler/interface.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1193,8 +1193,7 @@ func (c *compilerContext) getMethodSetValue(methods []*types.Func) llvm.Value {
11931193
// thunk is declared, not defined: it will be defined by the interface lowering
11941194
// pass.
11951195
func (c *compilerContext) getInvokeFunction(instr *ssa.CallCommon) llvm.Value {
1196-
s, _ := c.getTypeCodeName(instr.Value.Type().Underlying())
1197-
fnName := s + "." + instr.Method.Name() + "$invoke"
1196+
fnName := c.getInvokeFunctionName(instr)
11981197
llvmFn := c.mod.NamedFunction(fnName)
11991198
if llvmFn.IsNil() {
12001199
sig := instr.Method.Type().(*types.Signature)
@@ -1213,6 +1212,11 @@ func (c *compilerContext) getInvokeFunction(instr *ssa.CallCommon) llvm.Value {
12131212
return llvmFn
12141213
}
12151214

1215+
func (c *compilerContext) getInvokeFunctionName(instr *ssa.CallCommon) string {
1216+
s, _ := c.getTypeCodeName(instr.Value.Type().Underlying())
1217+
return s + "." + instr.Method.Name() + "$invoke"
1218+
}
1219+
12161220
// createInterfaceTypeAssert creates a call to a declared-but-not-defined
12171221
// $typeassert function for the given interface. This function will be defined
12181222
// by the interface lowering pass as a type-ID comparison chain, avoiding the

testdata/calls.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ func main() {
7070

7171
// regression testing
7272
regression1033()
73+
regression5541()
7374

7475
//Test deferred builtins
7576
testDeferBuiltinClose()
@@ -224,6 +225,46 @@ func foo(bar *Bar) error {
224225
return nil
225226
}
226227

228+
var regression5541RuntimeClosed, regression5541ModuleClosed int
229+
230+
type regression5541Closer interface {
231+
Close()
232+
}
233+
234+
type regression5541Runtime interface {
235+
Foo()
236+
regression5541Closer
237+
}
238+
239+
type regression5541RuntimeImpl struct{}
240+
241+
func (*regression5541RuntimeImpl) Foo() {
242+
}
243+
244+
func (*regression5541RuntimeImpl) Close() {
245+
regression5541RuntimeClosed++
246+
}
247+
248+
type regression5541Module struct{}
249+
250+
func (*regression5541Module) Close() {
251+
regression5541ModuleClosed++
252+
}
253+
254+
func regression5541() {
255+
func() {
256+
var runtime regression5541Runtime = &regression5541RuntimeImpl{}
257+
defer runtime.Close()
258+
259+
var module regression5541Closer = &regression5541Module{}
260+
defer module.Close()
261+
}()
262+
263+
if regression5541RuntimeClosed != 1 || regression5541ModuleClosed != 1 {
264+
println("deferred interface methods were not both called")
265+
}
266+
}
267+
227268
type issue1304 struct {
228269
a [0]int // zero-length field
229270
b int // field 'b' covers entire struct

0 commit comments

Comments
 (0)