Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
23 changes: 23 additions & 0 deletions gnovm/cmd/gno/testdata/test/issue_5776.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
gno run .

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit on placement: this txtar runs gno run . but lives in testdata/test/, where every other script exercises the gno test subcommand (the testdata subdirs are grouped per subcommand). Since this is a VM-behavior regression rather than a CLI one, the canonical home would be a filetest in gnovm/tests/files/ with an // Output: comment — lighter weight (runs under TestFiles instead of spinning up the CLI), and the issue body is already written in that format, so it converts directly.

Optional while you're at it: only the []MyRune line actually reaches the buggy branch ([]MyByte never enters the Int32Kind gas path). Adding a plain var r []rune; _ = string(r) would document that the bug wasn't specific to declared types.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Changed here 8bec3e7

For the change on the type I could do it but this file references Golang tests so I don't know if a good idea to modify it let me know if you still want to do the change and I'll do it


-- main.gno --
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Test case where a slice of a user-defined byte type (not uint8 or byte) is
// converted to a string. Same for slice of runes.

package main

type MyByte byte

type MyRune rune

func main() {
var y []MyByte
_ = string(y)

var z []MyRune
_ = string(z)
}
6 changes: 4 additions & 2 deletions gnovm/pkg/gnolang/op_expressions.go
Original file line number Diff line number Diff line change
Expand Up @@ -787,8 +787,10 @@ func (m *Machine) doOpConvert() {
} else if t.Kind() == StringKind {
// runes ([]int32) → string
if st, ok := baseOf(xv.T).(*SliceType); ok && st.Elt.Kind() == Int32Kind {
sv := xv.V.(*SliceValue)
m.incrCPU(OpCPUSlopeConvertRunesStr * int64(sv.GetLength()))
if xv.V != nil {
sv := xv.V.(*SliceValue)
m.incrCPU(OpCPUSlopeConvertRunesStr * int64(sv.GetLength()))
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Maybe a philosophical question but should we increment the CPU for converting an empty string (0 length) ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggestion: TypedValue.GetLength() already handles V == nil (returns 0 for slices), so this can be a one-liner without the assertion:

m.incrCPU(OpCPUSlopeConvertRunesStr * int64(xv.GetLength()))

This also mirrors the string→runes branch above, which is nil-safe for the same reason (xv.GetString() returns "" on nil V). Behavior is identical: a nil slice has length 0, so it charges 0 gas either way.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done here thanks for the review: 8bec3e7

}
}
}
Expand Down
Loading