yaegi
yaegi copied to clipboard
segfault while compiling code which initializes slice from struct field
The following program sample.go triggers an unexpected result
package main
import (
"fmt"
"os"
"reflect"
"github.com/traefik/yaegi/interp"
)
type Actor struct {
Age int
}
type Play struct {
Actors []Actor
}
var Symbols = map[string]map[string]reflect.Value{
"x/play/play": {
"Actor": reflect.ValueOf((*Actor)(nil)),
"Play": reflect.ValueOf((*Play)(nil)),
},
}
var code = `
import (
"x/play"
)
func Action() {
p := play.Play{}
ages := []int{p.Actors[0].Age}
}
`
func main() {
vm := interp.New(interp.Options{})
err := vm.Use(Symbols)
if err != nil {
fmt.Println("import error: ", err)
os.Exit(1)
}
_, err = vm.Compile(code)
if err != nil {
fmt.Println("compile error: ", err)
os.Exit(2)
}
}
Expected result
// no output expected
Got
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x128 pc=0x649bb4]
goroutine 1 [running]:
github.com/traefik/yaegi/interp.nodeType2(0xc00014c008, 0xc000138240, 0xc0001543c0, {0xc000076118, 0x0, 0x1})
/home/runsisi/working/go/yaegi/interp/type.go:978 +0x2594
github.com/traefik/yaegi/interp.nodeType(...)
/home/runsisi/working/go/yaegi/interp/type.go:400
github.com/traefik/yaegi/interp.(*Interpreter).cfg.func1(0xc000154000)
/home/runsisi/working/go/yaegi/interp/cfg.go:414 +0x3e47
github.com/traefik/yaegi/interp.(*node).Walk(0xc000154000, 0xc0000a7cf8, 0xc0000a7ca0)
/home/runsisi/working/go/yaegi/interp/interp.go:282 +0x2e
github.com/traefik/yaegi/interp.(*node).Walk(0xc000151cc0, 0xc0000a7cf8, 0xc0000a7ca0)
/home/runsisi/working/go/yaegi/interp/interp.go:286 +0x6b
github.com/traefik/yaegi/interp.(*node).Walk(0xc000151400, 0xc0000a7cf8, 0xc0000a7ca0)
/home/runsisi/working/go/yaegi/interp/interp.go:286 +0x6b
github.com/traefik/yaegi/interp.(*node).Walk(0xc000150c80, 0xc0000a7cf8, 0xc0000a7ca0)
/home/runsisi/working/go/yaegi/interp/interp.go:286 +0x6b
github.com/traefik/yaegi/interp.(*node).Walk(0xc000150640, 0xc0000a7cf8, 0xc0000a7ca0)
/home/runsisi/working/go/yaegi/interp/interp.go:286 +0x6b
github.com/traefik/yaegi/interp.(*Interpreter).cfg(0xc00014c008, 0xc000150640, 0xc000138240, {0xc000012410, 0x4}, {0xc000012410, 0x4})
/home/runsisi/working/go/yaegi/interp/cfg.go:69 +0x29a
github.com/traefik/yaegi/interp.(*Interpreter).CompileAST(0xc00014c008, {0x73f5b0?, 0xc000034320?})
/home/runsisi/working/go/yaegi/interp/program.go:97 +0x14d
github.com/traefik/yaegi/interp.(*Interpreter).compileSrc(0xc00014c008, {0x6e9e47?, 0x0?}, {0x0?, 0x0?}, 0x0?)
/home/runsisi/working/go/yaegi/interp/program.go:64 +0xaa
github.com/traefik/yaegi/interp.(*Interpreter).Compile(...)
/home/runsisi/working/go/yaegi/interp/program.go:33
main.main()
/home/runsisi/working/test/go/work/xp.go:44 +0xea
exit status 2
Yaegi Version
c828692c0b
Additional Notes
No response
the patch below fixes the segfault, but i am not sure if it's the right fix.
diff --git a/interp/type.go b/interp/type.go
index b322045..b533636 100644
--- a/interp/type.go
+++ b/interp/type.go
@@ -829,6 +829,8 @@ func nodeType2(interp *Interpreter, sc *scope, n *node, seen []*node) (t *itype,
switch lt.cat {
case arrayT, mapT, sliceT, variadicT:
t = lt.val
+ case valueT:
+ t = valueTOf(lt.rtype.Elem())
case genericT:
t1, err := nodeType2(interp, sc, n.child[1], seen)
if err != nil {