Merge pull request #2232 from nspcc-dev/compiler-invalid-offset

Set proper context during analyzing func usage
This commit is contained in:
Roman Khimov 2021-10-25 20:57:34 +03:00 committed by GitHub
commit 354a54c91c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 3 deletions

View file

@ -301,7 +301,12 @@ func (c *codegen) analyzeFuncUsage() funcUsage {
}
usage[name] = true
old := c.importMap
pkg := c.mainPkg
if fd.path != "" {
pkg = c.buildInfo.program.Package(fd.path)
}
c.typeInfo = &pkg.Info
c.currPkg = pkg.Pkg
c.importMap = fd.importMap
ast.Inspect(fd.decl, func(node ast.Node) bool {
switch n := node.(type) {
@ -316,7 +321,6 @@ func (c *codegen) analyzeFuncUsage() funcUsage {
}
return true
})
c.importMap = old
}
diff = nextDiff
}

View file

@ -16,6 +16,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/util/bitfield"
"github.com/nspcc-dev/neo-go/pkg/vm"
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
@ -2073,7 +2074,13 @@ func CodeGen(info *buildInfo) ([]byte, *DebugInfo, error) {
if err != nil {
return nil, nil, err
}
return buf, c.emitDebugInfo(buf), nil
methods := bitfield.New(len(buf))
di := c.emitDebugInfo(buf)
for i := range di.Methods {
methods.Set(int(di.Methods[i].Range.Start))
}
return buf, di, vm.IsScriptCorrect(buf, methods)
}
func (c *codegen) resolveFuncDecls(f *ast.File, pkg *types.Package) {
@ -2168,6 +2175,9 @@ func (c *codegen) replaceLabelWithOffset(ip int, arg []byte) (int, error) {
if int(index) > len(c.l) {
return 0, fmt.Errorf("unexpected label number: %d (max %d)", index, len(c.l))
}
if c.l[index] < 0 {
return 0, fmt.Errorf("invalid label target: %d at %d", c.l[index], ip)
}
offset := c.l[index] - ip
if offset > math.MaxInt32 || offset < math.MinInt32 {
return 0, fmt.Errorf("label offset is too big at the instruction %d: %d (max %d, min %d)",

View file

@ -350,4 +350,17 @@ func TestUnusedFunctions(t *testing.T) {
require.NoError(t, err)
eval(t, src, big.NewInt(65))
})
t.Run("method inside of an imported package", func(t *testing.T) {
// Check that import map is set correctly during package traversal.
src := `package foo
import inner "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/nestedcall"
func Main() int {
var t inner.Token
return t.Method()
}`
_, err := compiler.Compile("foo", strings.NewReader(src))
require.NoError(t, err)
eval(t, src, big.NewInt(2231))
})
}

View file

@ -28,3 +28,16 @@ func y() int {
tmp := 10
return tmp
}
// Token is stateless token.
type Token struct{}
// Method is a method.
func (t Token) Method() int {
return t.Inner()
}
// Inner is a function to be called in Method.
func (t Token) Inner() int {
return 2231
}