From 190dade469c230267b5966cc3c367ac1e90c7599 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Wed, 14 Oct 2020 17:30:04 +0200 Subject: [PATCH] fix: detect a wrong number of arguments at return Also fix error ouptut in the run command to avoid displaying twice the same error. Fixes #819. --- _test/fun23.go | 10 ++++++++++ cmd/yaegi/run.go | 5 +---- cmd/yaegi/yaegi.go | 8 ++++++-- interp/cfg.go | 4 ++++ interp/interp_consistent_test.go | 6 ++++++ 5 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 _test/fun23.go diff --git a/_test/fun23.go b/_test/fun23.go new file mode 100644 index 00000000..c1abba3b --- /dev/null +++ b/_test/fun23.go @@ -0,0 +1,10 @@ +package main + +func f(x int) { return x } + +func main() { + print("hello") +} + +// Error: +// 3:17: too many arguments to return diff --git a/cmd/yaegi/run.go b/cmd/yaegi/run.go index 0ebc69a2..4118c3fa 100644 --- a/cmd/yaegi/run.go +++ b/cmd/yaegi/run.go @@ -70,13 +70,12 @@ func run(arg []string) error { if cmd != "" { _, err = i.Eval(cmd) - showError(err) } if len(args) == 0 { if interactive || cmd == "" { - _, err = i.REPL() showError(err) + _, err = i.REPL() } return err } @@ -91,7 +90,6 @@ func run(arg []string) error { } else { _, err = i.EvalPath(path) } - showError(err) if err != nil { return err @@ -99,7 +97,6 @@ func run(arg []string) error { if interactive { _, err = i.REPL() - showError(err) } return err } diff --git a/cmd/yaegi/yaegi.go b/cmd/yaegi/yaegi.go index 6d9bfd23..79c2f7a8 100644 --- a/cmd/yaegi/yaegi.go +++ b/cmd/yaegi/yaegi.go @@ -99,6 +99,8 @@ import ( "fmt" "log" "os" + + "github.com/traefik/yaegi/interp" ) const ( @@ -143,8 +145,10 @@ func main() { } if err != nil && !errors.Is(err, flag.ErrHelp) { - err = fmt.Errorf("%s: %w", cmd, err) - fmt.Fprintln(os.Stderr, err) + fmt.Fprintln(os.Stderr, fmt.Errorf("%s: %w", cmd, err)) + if p, ok := err.(interp.Panic); ok { + fmt.Fprintln(os.Stderr, string(p.Stack)) + } exitCode = 1 } os.Exit(exitCode) diff --git a/interp/cfg.go b/interp/cfg.go index 71b86eda..fac5cb43 100644 --- a/interp/cfg.go +++ b/interp/cfg.go @@ -1298,6 +1298,10 @@ func (interp *Interpreter) cfg(root *node, importPath string) ([]*node, error) { } case returnStmt: + if len(n.child) > sc.def.typ.numOut() { + err = n.cfgErrorf("too many arguments to return") + break + } if mustReturnValue(sc.def.child[2]) { nret := len(n.child) if nret == 1 && isCall(n.child[0]) { diff --git a/interp/interp_consistent_test.go b/interp/interp_consistent_test.go index 7f24ef4c..c0fe41d0 100644 --- a/interp/interp_consistent_test.go +++ b/interp/interp_consistent_test.go @@ -43,6 +43,7 @@ func TestInterpConsistencyBuild(t *testing.T) { file.Name() == "for7.go" || // expect error file.Name() == "fun21.go" || // expect error file.Name() == "fun22.go" || // expect error + file.Name() == "fun23.go" || // expect error file.Name() == "if2.go" || // expect error file.Name() == "import6.go" || // expect error file.Name() == "init1.go" || // expect error @@ -201,6 +202,11 @@ func TestInterpErrorConsistency(t *testing.T) { expectedInterp: "6:2: not enough arguments in call to time.Date", expectedExec: "6:11: not enough arguments in call to time.Date", }, + { + fileName: "fun23.go", + expectedInterp: "3:17: too many arguments to return", + expectedExec: "3:17: too many arguments to return", + }, { fileName: "op1.go", expectedInterp: "5:2: invalid operation: mismatched types int and float64",