Skip to content

cmd/compile: defer of embedded method resolves pointer too early #52025

@ianlancetaylor

Description

@ianlancetaylor

Consider this test case:

package main

type CloseSetter interface {
	Set()
	Close() error
}

type S1 struct {
	f int
}

func (p *S1) Close() error {
	if p.f != 0 {
		panic(p.f)
	}
	return nil
}

type S2 struct {
	*S1
}

func (p *S2) Set() {
	p.S1 = &S1{0}
}

func F1(p CloseSetter) {
	p.Set()
	p.Close()
}

func F2() {
	s2 := &S2{}
	defer s2.Close()
	F1(s2)
}

func main() {
	F2()
}

When run with the gc compiler, this crashes:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x455534]

goroutine 1 [running]:
main.(*S1).Close(0xc000096000?)
	/home/iant/foo10.go:13 +0x14
main.F2()
	/home/iant/foo10.go:36 +0x7c
main.main()
	/home/iant/foo10.go:39 +0x17
exit status 2

When run with the gccgo compiler it exits successfully without printing anything.

I think the difference is that with the gc compiler the defer statement is resolving the embedded pointer at the point of the defer, and thus deferred a call to a nil pointer. If that is correct, then that seems wrong. A defer statement resolves all the arguments, but it shouldn't resolve s2 into s2.S1.

Or maybe gccgo is incorrectly not crashing, but I don't yet see it.

CC @randall77 @griesemer @mdempsky

Metadata

Metadata

Assignees

No one assigned

    Labels

    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.compiler/runtimeIssues related to the Go compiler and/or runtime.

    Type

    No type

    Projects

    Status

    Todo

    Status

    No status

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions