Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: typed const conversion validation #3117

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 130 additions & 0 deletions gnovm/pkg/gnolang/gno_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,136 @@ func TestBuiltinIdentifiersShadowing(t *testing.T) {
}
}

func TestConvertTo(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpicking: this function should be located in values_conversions_tests.go instead of gno_tests.go.

t.Parallel()

testFunc := func(source, msg string) {
defer func() {
if len(msg) == 0 {
return
}

r := recover()

if r == nil {
t.Fail()
}

err := r.(*PreprocessError)
c := strings.Contains(err.Error(), msg)
if !c {
t.Fatalf(`expected "%s", got "%s"`, msg, r)
}
}()

m := NewMachine("test", nil)

n := MustParseFile("main.go", source)
m.RunFiles(n)
m.RunMain()
}

type cases struct {
source string
msg string
}

tests := []cases{
{
`package test

func main() {
const a int = -1
println(uint(a))
}`,
`test/main.go:5:13: cannot convert constant of type IntKind to UintKind`,
},
{
`package test

func main() {
const a int = -1
println(uint8(a))
}`,
`test/main.go:5:13: cannot convert constant of type IntKind to Uint8Kind`,
},
{
`package test

func main() {
const a int = -1
println(uint16(a))
}`,
`test/main.go:5:13: cannot convert constant of type IntKind to Uint16Kind`,
},
{
`package test

func main() {
const a int = -1
println(uint32(a))
}`,
`test/main.go:5:13: cannot convert constant of type IntKind to Uint32Kind`,
},
{
`package test

func main() {
const a int = -1
println(uint64(a))
}`,
`test/main.go:5:13: cannot convert constant of type IntKind to Uint64Kind`,
},
{
`package test

func main() {
const a float32 = 1.5
println(int32(a))
}`,
`test/main.go:5:13: cannot convert constant of type Float32Kind to Int32Kind`,
},
{
`package test

func main() {
println(int32(1.5))
}`,
`test/main.go:4:13: cannot convert (const (1.5 <untyped> bigdec)) to integer type`,
},
{
`package test

func main() {
const a float64 = 1.5
println(int64(a))
}`,
`test/main.go:5:13: cannot convert constant of type Float64Kind to Int64Kind`,
},
{
`package test

func main() {
println(int64(1.5))
}`,
`test/main.go:4:13: cannot convert (const (1.5 <untyped> bigdec)) to integer type`,
},
{
`package test

func main() {
const f = float64(1.0)
println(int64(f))
}`,
``,
},
}

for _, tc := range tests {
testFunc(tc.source, tc.msg)
}
}

// run empty main().
func TestRunEmptyMain(t *testing.T) {
t.Parallel()
Expand Down
2 changes: 1 addition & 1 deletion gnovm/pkg/gnolang/op_expressions.go
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,6 @@ func (m *Machine) doOpFuncLit() {
func (m *Machine) doOpConvert() {
xv := m.PopValue()
t := m.PopValue().GetType()
ConvertTo(m.Alloc, m.Store, xv, t)
ConvertTo(m.Alloc, m.Store, xv, t, false)
Copy link
Contributor

@mvertes mvertes Nov 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, we don't know if xv is a constant or not. Forcing false for isConst parameter here is incorrect for constant expressions. For example, the following sample should fail but it doesn't:

println(int(float64(1 + 0.5)))

m.PushValue(*xv)
}
2 changes: 1 addition & 1 deletion gnovm/pkg/gnolang/preprocess.go
Original file line number Diff line number Diff line change
Expand Up @@ -3601,7 +3601,7 @@ func convertConst(store Store, last BlockNode, cx *ConstExpr, t Type) {
setConstAttrs(cx)
} else if t != nil {
// e.g. a named type or uint8 type to int for indexing.
ConvertTo(nilAllocator, store, &cx.TypedValue, t)
ConvertTo(nilAllocator, store, &cx.TypedValue, t, true)
setConstAttrs(cx)
}
}
Expand Down
2 changes: 1 addition & 1 deletion gnovm/pkg/gnolang/values.go
Original file line number Diff line number Diff line change
Expand Up @@ -1201,7 +1201,7 @@ func (tv *TypedValue) SetInt(n int) {

func (tv *TypedValue) ConvertGetInt() int {
var store Store = nil // not used
ConvertTo(nilAllocator, store, tv, IntType)
ConvertTo(nilAllocator, store, tv, IntType, false)
return tv.GetInt()
}

Expand Down
Loading
Loading