compiler: emit code for unnamed global var decls more careful

In case if global var is unnamed (and, as a consequence, unused) and
contains a function call inside its value specification, we need to emit
code for this var to be able to call the function as it can have
side-effects. See the example:
```
package foo

import "github.com/nspcc-dev/neo-go/pkg/interop/runtime"

var A = f()

func Main() int {
   return 3
}

func f() int {
   runtime.Notify("Valuable notification", 1)
   return 2
}
```
This commit is contained in:
Anna Shaleva 2022-08-15 13:15:24 +03:00
parent 4531f79a4b
commit 1dcbdb011a
2 changed files with 80 additions and 15 deletions

View file

@ -13,15 +13,46 @@ import (
)
func TestUnusedGlobal(t *testing.T) {
src := `package foo
const (
_ int = iota
a
)
func Main() int {
return 1
}`
eval(t, src, big.NewInt(1))
t.Run("simple unused", func(t *testing.T) {
src := `package foo
const (
_ int = iota
a
)
func Main() int {
return 1
}`
prog := eval(t, src, big.NewInt(1))
require.Equal(t, 2, len(prog)) // PUSH1 + RET
})
t.Run("unused with function call inside", func(t *testing.T) {
t.Run("specification names count matches values count", func(t *testing.T) {
src := `package foo
var control int
var _ = f()
func Main() int {
return control
}
func f() int {
control = 1
return 5
}`
eval(t, src, big.NewInt(1))
})
t.Run("specification names count differs from values count", func(t *testing.T) {
src := `package foo
var control int
var _, _ = f()
func Main() int {
return control
}
func f() (int, int) {
control = 1
return 5, 6
}`
eval(t, src, big.NewInt(1))
})
})
}
func TestChangeGlobal(t *testing.T) {