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: handle untyped constant expressions in append() #1177

Merged
merged 9 commits into from
Jan 10, 2024
17 changes: 17 additions & 0 deletions gnovm/pkg/gnolang/preprocess.go
Original file line number Diff line number Diff line change
Expand Up @@ -1013,6 +1013,23 @@
n.Args[1] = args1
}
}
mvertes marked this conversation as resolved.
Show resolved Hide resolved
// Another special case for append: adding untyped constants.
// They must be converted to the array type for consistency.
for i, arg := range n.Args[1:] {
if _, ok := arg.(*ConstExpr); !ok {
// Consider only constant expressions.
continue
}
if t1 := evalStaticTypeOf(store, last, arg); t1 != nil && !isUntyped(t1) {
// Consider only untyped values (including nil).
continue

Check warning on line 1025 in gnovm/pkg/gnolang/preprocess.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/preprocess.go#L1024-L1025

Added lines #L1024 - L1025 were not covered by tests
}
// Get the array type from the first argument and convert to it.
s0 := evalStaticTypeOf(store, last, n.Args[0])
tx := constType(arg, s0.Elem())
arg1 := Call(tx, arg)
n.Args[i+1] = Preprocess(nil, last, arg1).(Expr)
}
} else if fv.PkgPath == uversePkgPath && fv.Name == "copy" {
if len(n.Args) == 2 {
// If the second argument is a string,
Expand Down
4 changes: 4 additions & 0 deletions gnovm/pkg/gnolang/values_conversions.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@
}
// special case for undefined/nil source
if tv.IsUndefined() {
switch t.Kind() {
case BoolKind, StringKind, IntKind, Int8Kind, Int16Kind, Int32Kind, Int64Kind, UintKind, Uint8Kind, Uint16Kind, Uint32Kind, Uint64Kind, Float32Kind, Float64Kind, BigintKind, BigdecKind:
panic(fmt.Sprintf("cannot convert %v to %v", tv, t))

Check warning on line 82 in gnovm/pkg/gnolang/values_conversions.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/values_conversions.go#L81-L82

Added lines #L81 - L82 were not covered by tests
}
tv.T = t
return
}
Expand Down
2 changes: 1 addition & 1 deletion gnovm/tests/files/append5.gno
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ func main() {
}

// Output:
// X
// X
12 changes: 12 additions & 0 deletions gnovm/tests/files/append6.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package main

func main() {
const x = 118999
y := 11
p := []int{}
p = append(p, x, y)
println(p[0] + p[1])
}

// Output:
// 119010
10 changes: 10 additions & 0 deletions gnovm/tests/files/append7.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package main

func main() {
var errors []error
errors = append(errors, nil, nil)
println(len(errors))
}

// Output:
// 2
7 changes: 7 additions & 0 deletions gnovm/tests/files/convert4.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package main

func main() {
println(int(nil))
}

// error: cannot convert (undefined) to int
9 changes: 9 additions & 0 deletions gnovm/tests/files/convert5.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package main

func main() {
var ints []int
ints = append(ints, nil, nil)
println(ints)
}

// error: cannot convert (undefined) to int
Loading