File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff 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).
Original file line number Diff line number Diff 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.
11951195func (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
Original file line number Diff line number Diff 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+
227268type issue1304 struct {
228269 a [0 ]int // zero-length field
229270 b int // field 'b' covers entire struct
You can’t perform that action at this time.
0 commit comments