compiler: do not DROP unary expression value inside IF stmt
We dropped values from such calls because they where marked as unused (consequently, were followed by DROP instructions). Example: if !foo() { <--- panic here ... } This commit prevents the following runtime error during script execution: ``` "error encountered at instruction ** (NOT): runtime error: invalid memory address or nil pointer dereference" ```
This commit is contained in:
parent
fe1f0a7245
commit
dbce3c9a19
2 changed files with 34 additions and 0 deletions
|
@ -112,6 +112,11 @@ func (c *funcScope) analyzeVoidCalls(node ast.Node) bool {
|
||||||
if ok {
|
if ok {
|
||||||
c.voidCalls[ce] = false
|
c.voidCalls[ce] = false
|
||||||
}
|
}
|
||||||
|
case *ast.UnaryExpr:
|
||||||
|
ce, ok := n.X.(*ast.CallExpr)
|
||||||
|
if ok {
|
||||||
|
c.voidCalls[ce] = false
|
||||||
|
}
|
||||||
case *ast.IfStmt:
|
case *ast.IfStmt:
|
||||||
// we can't just return `false`, because we still need to process body
|
// we can't just return `false`, because we still need to process body
|
||||||
ce, ok := n.Cond.(*ast.CallExpr)
|
ce, ok := n.Cond.(*ast.CallExpr)
|
||||||
|
|
|
@ -121,3 +121,32 @@ func TestInitIF(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCallExpIF(t *testing.T) {
|
||||||
|
t.Run("Call", func(t *testing.T) {
|
||||||
|
src := `package foo
|
||||||
|
func someFunc() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
func Main() int {
|
||||||
|
if someFunc() {
|
||||||
|
return 5
|
||||||
|
}
|
||||||
|
return 6
|
||||||
|
}`
|
||||||
|
eval(t, src, big.NewInt(5))
|
||||||
|
})
|
||||||
|
t.Run("CallWithUnaryExpression", func(t *testing.T) {
|
||||||
|
src := `package foo
|
||||||
|
func someFunc() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
func Main() int {
|
||||||
|
if !someFunc() {
|
||||||
|
return 5
|
||||||
|
}
|
||||||
|
return 6
|
||||||
|
}`
|
||||||
|
eval(t, src, big.NewInt(5))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue