Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/tools/go/ssa: wrapper function for embedded type has invalid variadic parameter #27453

Closed
aykevl opened this issue Sep 2, 2018 · 6 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@aykevl
Copy link

aykevl commented Sep 2, 2018

Go version: go1.11 linux/amd64
Package "x/tools/go/ssa" version: master (golang/tools@7ca1327)

See this code (play):

package main

type Foo int

type Bar struct {
	Foo
}

func (f Foo) Call(args ...interface{}) {
}

func main() {
	var f Foo
	var itf interface{} = f
	_ = itf
}

It produces the following SSA (shortened). I've also printed the actual parameters just before printing the SSA, for debugging.

arg: parameter f : Foo
arg: parameter args : []interface{}
# Name: (examples/varargbug.Foo).Call
# Package: examples/varargbug
# Location: src/examples/varargbug/main.go:9:14
func (f Foo) Call(args ...interface{}):
0:                                                                entry P:0 S:0
	return

arg: parameter f : *examples/varargbug.Foo
arg: parameter args : [][]interface{}
# Name: (*examples/varargbug.Foo).Call
# Synthetic: wrapper for func (examples/varargbug.Foo).Call(args ...interface{})
# Location: src/examples/varargbug/main.go:9:14
func (f *examples/varargbug.Foo) Call(args ...interface{}):
0:                                                                entry P:0 S:0
	t0 = ssa:wrapnilchk(f, "examples/varargbu...":string, "Call":string) *examples/varargbug.Foo
	t1 = *t0                                         examples/varargbug.Foo
	t2 = (examples/varargbug.Foo).Call(t1, args...)                      ()
	return

# Name: examples/varargbug.main
# Package: examples/varargbug
# Location: src/examples/varargbug/main.go:12:6
func main():
0:                                                                entry P:0 S:0
	; var f examples/varargbug.Foo @ 13:6 is 0:examples/varargbug.Foo
	; var f examples/varargbug.Foo @ 14:24 is 0:examples/varargbug.Foo
	t0 = make interface{} <- Foo (0:Foo)                        interface{}
	; var itf interface{} @ 14:6 is t0
	; var itf interface{} @ 15:6 is t0
	return

As you can see, (*examples/varargbug.Foo).Call somehow has type [][]interface{} for the variadic arguments, which I believe is incorrect. It should be []interface{}, as that's what is used in other places for variadic arguments. The result is that when the wrapper calls the underlying function, there is a type mismatch.

One place in the standard library where this happens is in "syscall/js". The Error type embeds the Value type so the SSA translation creates a wrapper function called (*syscall/js.Error).Call(), leading to this issue.

@gopherbot gopherbot added this to the Unreleased milestone Sep 2, 2018
@ianlancetaylor
Copy link
Contributor

CC @alandonovan

@ianlancetaylor ianlancetaylor added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Sep 7, 2018
@alandonovan
Copy link
Contributor

As you can see, (*examples/varargbug.Foo).Call somehow has type [][]interface{} for the variadic arguments, which I believe is incorrect. It should be []interface{}, as that's what is used in other places for variadic arguments.

The usual output from the SSA package looks correct to me. The part that is inconsistent is the arg: parameter args : [][]interface{} line, which came from the print statement you added, which I cannot see. I tried printing the types of the formal parameters [sic; not 'actual'] but nothing was amiss.

Could you send me the patch that added the print statement?

@aykevl
Copy link
Author

aykevl commented Sep 10, 2018

It is not a patch (to the ssa package), it is a program that prints the generated SSA form.

I will post a better sample soon, but it is something like:

    for _, fn := range package.Members {
        for _, param := fn.Params {
            println("arg:", param.String())
        }
        fn.WriteTo(os.Stdout)
    }

@alandonovan
Copy link
Contributor

Thanks, I can reproduce the problem now. Will send a fix.

@gopherbot
Copy link

Change https://golang.org/cl/134515 mentions this issue: go/ssa: use correct type for variadic parameter in wrapper methods

@aykevl
Copy link
Author

aykevl commented Sep 15, 2018

Thank you! This fixes my problem.

@golang golang locked and limited conversation to collaborators Sep 15, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

4 participants