Skip to content

Problem with accessing uint64 variable inside condition in a loop #157

@Skird

Description

@Skird

Hi! I think I found strange bug when trying to Sprintf uint64 variable

Here is minimal repro

package main

import (
	"fmt"

	"github.com/cosmos72/gomacro/fast"
)

var code = `

import (
	"errors"
	"fmt"
	"math/rand"
)

func GetNewBaz(baz uint64) (uint64, error) {
	if baz > 5 {
		return 3, nil
	}
	return baz, errors.New("fail: baz")
}

func Foo() error {
	var baz uint64 = 10
	q := fmt.Sprintf("starting at baz: %d", baz)
	fmt.Println(q)
	for it := 0; it < 2; it++ {
		newBaz, err := GetNewBaz(baz)
		if err != nil {
			fmt.Println("GetNewBaz errored")
			q := fmt.Sprintf("stopping at baz: %d", baz)
			fmt.Println(q)
			break
		} else {
			baz = newBaz
		}
	}
	return nil
}

`

func main() {
	interp := fast.New()
	interp.Eval(code)
	foo := interp.ValueOf("Foo").Interface().(func() error)
	fmt.Println(foo())
}

It panics like that

$ go run main.go
starting at baz: 10
GetNewBaz errored
panic: runtime error: index out of range [0] with length 0

goroutine 1 [running]:
github.com/cosmos72/gomacro/fast.(*Symbol).intExpr.func59(0xc000051720?)
        /home/divashchenko/go/pkg/mod/github.com/cosmos72/gomacro@v0.0.0-20240506194242-2ff796e3da10/fast/identifier.go:964 +0x65
github.com/cosmos72/gomacro/fast.funAsX1.func23(0xc000406198?)
        /home/divashchenko/go/pkg/mod/github.com/cosmos72/gomacro@v0.0.0-20240506194242-2ff796e3da10/fast/util.go:591 +0x17
github.com/cosmos72/gomacro/fast.call_variadic_ret1.func35(0xc000154460)
        /home/divashchenko/go/pkg/mod/github.com/cosmos72/gomacro@v0.0.0-20240506194242-2ff796e3da10/fast/call_variadic.go:423 +0x7d
github.com/cosmos72/gomacro/fast.funAsX1.func35(0xc0000517c8?)
        /home/divashchenko/go/pkg/mod/github.com/cosmos72/gomacro@v0.0.0-20240506194242-2ff796e3da10/fast/util.go:651 +0x17
github.com/cosmos72/gomacro/fast.(*Comp).DeclVar0.func5(0xc000154460)
        /home/divashchenko/go/pkg/mod/github.com/cosmos72/gomacro@v0.0.0-20240506194242-2ff796e3da10/fast/declaration.go:536 +0x35
github.com/cosmos72/gomacro/fast.(*Code).Exec.exec.func2(0xc000154000?)
        /home/divashchenko/go/pkg/mod/github.com/cosmos72/gomacro@v0.0.0-20240506194242-2ff796e3da10/fast/code.go:176 +0x25c
github.com/cosmos72/gomacro/fast.(*Comp).funcGeneric.func2.1({0x236d560, 0x0, 0x0?})
        /home/divashchenko/go/pkg/mod/github.com/cosmos72/gomacro@v0.0.0-20240506194242-2ff796e3da10/fast/function.go:438 +0xe9
github.com/cosmos72/gomacro/xreflect.MakeFunc.func1({0x236d560, 0x0, 0x0?})
        /home/divashchenko/go/pkg/mod/github.com/cosmos72/gomacro@v0.0.0-20240506194242-2ff796e3da10/xreflect/wrap.go:39 +0xa3
main.main()
        /home/divashchenko/workspace/goplay/main.go:48 +0x5e
exit status 2
  1. It seems to fail on fmt.Sprintf("stopping at baz: %d", baz), but only inside the loop
  2. It does not panic if I change uint64 to uint32 for example
  3. It panics in the same way on REPL too

It seems the line in fast/identifier.go:964 is the culprit
I'm not sure why, but uint64 is treated differently that other types

Hope that helps and thanks again for the cool package! :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions