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
4 changes: 2 additions & 2 deletions examples/gno.land/r/gnoland/faucet/z2_filetest.gno
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ func main() {
)
std.TestSetOrigCaller(adminaddr)
err := faucet.AdminAddController(controlleraddr1)
if err != nil {
if err != "" {
panic(err)
}
err = faucet.AdminAddController(controlleraddr2)
if err != nil {
if err != "" {
panic(err)
}
println(faucet.Render(""))
Expand Down
8 changes: 4 additions & 4 deletions examples/gno.land/r/gnoland/faucet/z3_filetest.gno
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,21 @@ func main() {
)
std.TestSetOrigCaller(adminaddr)
err := faucet.AdminAddController(controlleraddr1)
if err != nil {
if err != "" {
panic(err)
}
err = faucet.AdminAddController(controlleraddr2)
if err != nil {
if err != "" {
panic(err)
}
std.TestSetOrigCaller(controlleraddr1)
err = faucet.Transfer(testaddr1, 1000000)
if err != nil {
if err != "" {
panic(err)
}
std.TestSetOrigCaller(controlleraddr2)
err = faucet.Transfer(testaddr1, 2000000)
if err != nil {
if err != "" {
panic(err)
}
println(faucet.Render(""))
Expand Down
23 changes: 23 additions & 0 deletions gnovm/pkg/gnolang/preprocess.go
Original file line number Diff line number Diff line change
Expand Up @@ -1012,6 +1012,29 @@
args1 = Preprocess(nil, last, args1).(Expr)
n.Args[1] = args1
}
} else {
var tx *constTypeExpr // array type expr, lazily initialized
// 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 1026 in gnovm/pkg/gnolang/preprocess.go

View check run for this annotation

Codecov / codecov/patch

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

Added lines #L1025 - L1026 were not covered by tests
}

if tx == nil {
// Get the array type from the first argument.
s0 := evalStaticTypeOf(store, last, n.Args[0])
tx = constType(arg, s0.Elem())
}
// Convert to the array type.
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 {
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