mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2025-05-07 23:10:32 +00:00
compiler: do not emit code for unnamed unused variables
If variable is unnamed and does not contain function call then it's treated as unused and code generation may be omitted for it initialization/declaration.
This commit is contained in:
parent
1dcbdb011a
commit
91b36657d6
8 changed files with 151 additions and 18 deletions
|
@ -3,6 +3,8 @@ package compiler_test
|
|||
import (
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
)
|
||||
|
||||
func TestGenDeclWithMultiRet(t *testing.T) {
|
||||
|
@ -29,3 +31,46 @@ func TestGenDeclWithMultiRet(t *testing.T) {
|
|||
eval(t, src, big.NewInt(3))
|
||||
})
|
||||
}
|
||||
|
||||
func TestUnderscoreLocalVarDontEmitCode(t *testing.T) {
|
||||
src := `package foo
|
||||
type Foo struct { Int int }
|
||||
func Main() int {
|
||||
var _ int
|
||||
var _ = 1
|
||||
var (
|
||||
A = 2
|
||||
_ = A + 3
|
||||
_, B, _ = 4, 5, 6
|
||||
_, _, _ = f(A, B) // unused, but has function call, so the code is expected
|
||||
_, C, _ = f(A, B)
|
||||
)
|
||||
var D = 7 // unused but named, so the code is expected
|
||||
_ = D
|
||||
var _ = Foo{ Int: 5 }
|
||||
var fo = Foo{ Int: 3 }
|
||||
var _ = 1 + A + fo.Int
|
||||
var _ = fo.GetInt() // unused, but has method call, so the code is expected
|
||||
return C
|
||||
}
|
||||
func f(a, b int) (int, int, int) {
|
||||
return 8, 9, 10
|
||||
}
|
||||
func (fo Foo) GetInt() int {
|
||||
return fo.Int
|
||||
}`
|
||||
eval(t, src, big.NewInt(9), []interface{}{opcode.INITSLOT, []byte{5, 0}}, // local slot for A, B, C, D, fo
|
||||
opcode.PUSH2, opcode.STLOC0, // store A
|
||||
opcode.PUSH5, opcode.STLOC1, // store B
|
||||
opcode.LDLOC0, opcode.LDLOC1, opcode.SWAP, []interface{}{opcode.CALL, []byte{27}}, // evaluate f() first time
|
||||
opcode.DROP, opcode.DROP, opcode.DROP, // drop all values from f
|
||||
opcode.LDLOC0, opcode.LDLOC1, opcode.SWAP, []interface{}{opcode.CALL, []byte{19}}, // evaluate f() second time
|
||||
opcode.DROP, opcode.STLOC2, opcode.DROP, // store C
|
||||
opcode.PUSH7, opcode.STLOC3, // store D
|
||||
opcode.LDLOC3, opcode.DROP, // empty assignment
|
||||
opcode.PUSH3, opcode.PUSH1, opcode.PACKSTRUCT, opcode.STLOC4, // fo decl
|
||||
opcode.LDLOC4, []interface{}{opcode.CALL, []byte{12}}, opcode.DROP, // fo.GetInt()
|
||||
opcode.LDLOC2, opcode.RET, // return C
|
||||
[]interface{}{opcode.INITSLOT, []byte{0, 2}}, opcode.PUSH10, opcode.PUSH9, opcode.PUSH8, opcode.RET, // f
|
||||
[]interface{}{opcode.INITSLOT, []byte{0, 1}}, opcode.LDARG0, opcode.PUSH0, opcode.PICKITEM, opcode.RET) // (fo Foo) GetInt() int
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue