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(gnovm): correct comparison between different types #1890

Merged
merged 134 commits into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
134 commits
Select commit Hold shift + click to select a range
e22a43c
outOfGas log clearly
ltzmaxwell Nov 17, 2023
b9aa15e
patch up
ltzmaxwell Nov 20, 2023
9f57ef7
more test, cover more cases
ltzmaxwell Nov 21, 2023
55e3af8
fix assign type check
ltzmaxwell Nov 21, 2023
af75c9e
fixup
ltzmaxwell Nov 27, 2023
2603f34
more test
ltzmaxwell Nov 28, 2023
1275f9d
fixup
ltzmaxwell Nov 29, 2023
814354b
make test work
ltzmaxwell Nov 30, 2023
0f53121
fixup
ltzmaxwell Dec 1, 2023
ddd2c71
refactor
ltzmaxwell Dec 3, 2023
7acaec6
fixup
ltzmaxwell Dec 4, 2023
e291e56
comparable
ltzmaxwell Dec 5, 2023
ad87127
compare
ltzmaxwell Dec 5, 2023
7d21ff8
unary
ltzmaxwell Dec 5, 2023
9b0ace9
fixup
ltzmaxwell Dec 6, 2023
eed16b7
optimize
ltzmaxwell Dec 7, 2023
1c93d2c
inc,dec
ltzmaxwell Dec 7, 2023
5f0ac87
fixup
ltzmaxwell Dec 7, 2023
d6000c5
fixup
ltzmaxwell Dec 7, 2023
812e64d
fixup
ltzmaxwell Dec 7, 2023
fe948bb
doc
ltzmaxwell Dec 7, 2023
52d8221
more test
ltzmaxwell Dec 8, 2023
ec6fd0e
readme
ltzmaxwell Dec 8, 2023
cde9ed5
fixup
ltzmaxwell Dec 8, 2023
80508da
fixup
ltzmaxwell Dec 8, 2023
7af6623
restore unwanted
ltzmaxwell Dec 8, 2023
55e6cc0
restore
ltzmaxwell Dec 8, 2023
6d56167
Merge remote-tracking branch 'upstream/master' into ltzmaxwell/fix/in…
ltzmaxwell Dec 8, 2023
fa7f8d4
restore
ltzmaxwell Dec 8, 2023
6a31cb8
restore
ltzmaxwell Dec 8, 2023
0b095c3
restore
ltzmaxwell Dec 8, 2023
34588a1
restore
ltzmaxwell Dec 8, 2023
edc8c5b
restore
ltzmaxwell Dec 8, 2023
1513d78
restore
ltzmaxwell Dec 8, 2023
5dbf7f4
sync
ltzmaxwell Dec 8, 2023
9656056
fix inc float
ltzmaxwell Dec 8, 2023
fa3acd0
fixup
ltzmaxwell Dec 8, 2023
068e368
fixup
ltzmaxwell Dec 8, 2023
2f4136f
fmt
ltzmaxwell Dec 8, 2023
1497c4a
lint
ltzmaxwell Dec 8, 2023
709e13a
lint
ltzmaxwell Dec 8, 2023
8fd16fc
fix map comparable
ltzmaxwell Dec 8, 2023
8a63e0c
fixup
ltzmaxwell Dec 10, 2023
ad8768b
fix slice type
ltzmaxwell Dec 11, 2023
0f828f5
fix comparable
ltzmaxwell Dec 11, 2023
937723e
fixup
ltzmaxwell Dec 11, 2023
218c834
fixup
ltzmaxwell Dec 11, 2023
8c5ce24
fixup
ltzmaxwell Dec 12, 2023
abff073
fixup
ltzmaxwell Dec 12, 2023
af0de11
fixup
ltzmaxwell Dec 12, 2023
e673dac
fixup
ltzmaxwell Dec 12, 2023
cfcbdda
restore
ltzmaxwell Dec 12, 2023
268e849
fix shift
ltzmaxwell Dec 12, 2023
097244e
fixup
ltzmaxwell Dec 12, 2023
6858e80
fixup
ltzmaxwell Dec 13, 2023
db12d88
tidy
ltzmaxwell Dec 13, 2023
fe2cb7d
fixup
ltzmaxwell Dec 14, 2023
5f58979
fixup
ltzmaxwell Dec 14, 2023
c936fea
fix special case relate to nil type
ltzmaxwell Dec 18, 2023
ee408c2
fixup
ltzmaxwell Dec 19, 2023
2771649
fixup
ltzmaxwell Dec 20, 2023
005b370
fixup
ltzmaxwell Dec 22, 2023
c1f4dda
fixup
ltzmaxwell Dec 22, 2023
f94e4fd
add test
ltzmaxwell Dec 22, 2023
635decd
fixup
ltzmaxwell Dec 24, 2023
95214af
add new test
ltzmaxwell Jan 9, 2024
7464ac9
fixup
ltzmaxwell Jan 11, 2024
4f370a2
clean
ltzmaxwell Jan 11, 2024
54b255d
add comments
ltzmaxwell Jan 11, 2024
184f526
add comment
ltzmaxwell Jan 11, 2024
6aa1c04
add comments
ltzmaxwell Jan 11, 2024
46ced47
add test
ltzmaxwell Jan 11, 2024
5e9c783
add test
ltzmaxwell Jan 11, 2024
9e47ced
fixup
ltzmaxwell Jan 11, 2024
937a725
update
ltzmaxwell Jan 12, 2024
57bd724
update
ltzmaxwell Jan 13, 2024
e9a3a0a
fixup
ltzmaxwell Jan 13, 2024
ef21103
fixup
ltzmaxwell Jan 13, 2024
37f00df
improve name
ltzmaxwell Jan 13, 2024
1791a34
fixup
ltzmaxwell Jan 14, 2024
073bd48
fixup
ltzmaxwell Jan 14, 2024
df4d4c7
fixup
ltzmaxwell Jan 15, 2024
ef25c1f
fixup
ltzmaxwell Jan 15, 2024
6f59149
fixup
ltzmaxwell Jan 15, 2024
33ec34f
fixup
ltzmaxwell Jan 16, 2024
836941d
sync and test
ltzmaxwell Jan 16, 2024
8d3d855
fixup
ltzmaxwell Jan 17, 2024
e4e5e2a
check nil
ltzmaxwell Jan 17, 2024
8ee9724
fixup
ltzmaxwell Jan 17, 2024
292b038
clear
ltzmaxwell Jan 18, 2024
cd8caa9
fixup
ltzmaxwell Jan 18, 2024
87f3a8e
fixup
ltzmaxwell Jan 18, 2024
792a368
fixup
ltzmaxwell Jan 18, 2024
7a9b8a4
add check
ltzmaxwell Jan 20, 2024
94262aa
clean most debug log, can be revert here
ltzmaxwell Jan 31, 2024
afde8b0
escape op on render side
ltzmaxwell Feb 8, 2024
40ec493
migrate logic to type_check.go; move compatibility check as method of…
ltzmaxwell Mar 1, 2024
5f0cf8b
make test pass
ltzmaxwell Mar 1, 2024
cbdc979
done refactor to type_checker
ltzmaxwell Mar 4, 2024
118598d
clean
ltzmaxwell Mar 5, 2024
33a3c9d
prepared for split
ltzmaxwell Mar 5, 2024
6d6590a
mv some check logic to type_check
ltzmaxwell Mar 5, 2024
218fff0
fix binary non-const native handling
ltzmaxwell Mar 7, 2024
a6838b6
fix compatible check for assign in type_check
ltzmaxwell Mar 7, 2024
4744d09
make rhs native type check in type_check
ltzmaxwell Mar 8, 2024
5631d3a
try handle checking declared type against native interface, temp her…
ltzmaxwell Mar 11, 2024
a2862ba
consolidate delay handling for untyped shift expr logic
ltzmaxwell Mar 13, 2024
7bd03e1
cache better; clear unused logic
ltzmaxwell Mar 14, 2024
f9517eb
#cherry-pick. rm logic of check declared type against native interfac…
ltzmaxwell Mar 14, 2024
88f20ea
#no cherry pick for shift_expr_typecheck branch! rm most logic for ha…
ltzmaxwell Mar 14, 2024
5da2910
cherry pick this. rm remained logic for check against native interfac…
ltzmaxwell Mar 14, 2024
723aa3b
default cherry pick commit this branch if not marked as not. fixup
ltzmaxwell Mar 14, 2024
c93111f
restore typecheck, rm redundant checkAssignableTo, leave it to checkO…
ltzmaxwell Apr 4, 2024
64dc20d
clean
ltzmaxwell Apr 4, 2024
a65be41
clean
ltzmaxwell Apr 4, 2024
953765c
clean
ltzmaxwell Apr 4, 2024
05849f0
split type(nil)
ltzmaxwell Apr 4, 2024
9b42a90
merge master
ltzmaxwell Jun 30, 2024
2f43e88
fixup
ltzmaxwell Jul 22, 2024
a09cf85
Merge remote-tracking branch 'upstream/master' into fix/maxwell/type_…
ltzmaxwell Jul 22, 2024
4a5abe0
fixup
ltzmaxwell Jul 22, 2024
9302237
add test
ltzmaxwell Jul 24, 2024
9f71345
fixup
ltzmaxwell Jul 30, 2024
2f9fe22
clean
ltzmaxwell Jul 30, 2024
699c022
clean
ltzmaxwell Jul 30, 2024
de5ef00
add test
ltzmaxwell Jul 30, 2024
12bd817
correct fix uassert
ltzmaxwell Jul 31, 2024
9120bb3
tune uassert
ltzmaxwell Jul 31, 2024
1aa573e
Update gnovm/tests/files/types/cmp_iface_0_stdlibs.gno
ltzmaxwell Aug 2, 2024
f4459c8
Update gnovm/tests/files/types/cmp_iface_1.gno
ltzmaxwell Aug 2, 2024
5df3df6
add test and comment
ltzmaxwell Aug 5, 2024
ea8fdb7
tune uassert
ltzmaxwell Aug 5, 2024
f555c4b
Merge branch 'fix/maxwell/type_comparison' of github.com:ltzmaxwell/g…
ltzmaxwell Aug 5, 2024
e2eba49
typo
ltzmaxwell Aug 5, 2024
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
97 changes: 68 additions & 29 deletions examples/gno.land/p/demo/uassert/uassert.gno
Original file line number Diff line number Diff line change
Expand Up @@ -373,46 +373,85 @@ func NotEqual(t TestingT, expected, actual interface{}, msgs ...string) bool {
return true
}

func isNumberEmpty(n interface{}) (isNumber, isEmpty bool) {
switch n := n.(type) {
// NOTE: the cases are split individually, so that n becomes of the
// asserted type; the type of '0' was correctly inferred and converted
// to the corresponding type, int, int8, etc.
case int:
return true, n == 0
case int8:
return true, n == 0
case int16:
return true, n == 0
case int32:
return true, n == 0
case int64:
return true, n == 0
case uint:
return true, n == 0
case uint8:
return true, n == 0
case uint16:
return true, n == 0
case uint32:
return true, n == 0
case uint64:
return true, n == 0
case float32:
return true, n == 0
case float64:
return true, n == 0
}
return false, false
}
func Empty(t TestingT, obj interface{}, msgs ...string) bool {
t.Helper()
switch val := obj.(type) {
case string:
if val != "" {
return fail(t, msgs, "uassert.Empty: not empty string: %s", val)
}
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
if val != 0 {
return fail(t, msgs, "uassert.Empty: not empty number: %d", val)

isNumber, isEmpty := isNumberEmpty(obj)
if isNumber {
if !isEmpty {
return fail(t, msgs, "uassert.Empty: not empty number: %d", obj)
}
case std.Address:
var zeroAddr std.Address
if val != zeroAddr {
return fail(t, msgs, "uassert.Empty: not empty std.Address: %s", string(val))
} else {
switch val := obj.(type) {
case string:
if val != "" {
return fail(t, msgs, "uassert.Empty: not empty string: %s", val)
}
case std.Address:
var zeroAddr std.Address
if val != zeroAddr {
return fail(t, msgs, "uassert.Empty: not empty std.Address: %s", string(val))
}
default:
return fail(t, msgs, "uassert.Empty: unsupported type")
}
default:
return fail(t, msgs, "uassert.Empty: unsupported type")
}
return true
}

func NotEmpty(t TestingT, obj interface{}, msgs ...string) bool {
t.Helper()
switch val := obj.(type) {
case string:
if val == "" {
return fail(t, msgs, "uassert.NotEmpty: empty string: %s", val)
}
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
if val == 0 {
return fail(t, msgs, "uassert.NotEmpty: empty number: %d", val)
}
case std.Address:
var zeroAddr std.Address
if val == zeroAddr {
return fail(t, msgs, "uassert.NotEmpty: empty std.Address: %s", string(val))
isNumber, isEmpty := isNumberEmpty(obj)
if isNumber {
if isEmpty {
return fail(t, msgs, "uassert.NotEmpty: empty number: %d", obj)
}
} else {
switch val := obj.(type) {
case string:
if val == "" {
return fail(t, msgs, "uassert.NotEmpty: empty string: %s", val)
}
case std.Address:
var zeroAddr std.Address
if val == zeroAddr {
return fail(t, msgs, "uassert.NotEmpty: empty std.Address: %s", string(val))
}
default:
return fail(t, msgs, "uassert.NotEmpty: unsupported type")
}
default:
return fail(t, msgs, "uassert.NotEmpty: unsupported type")
}
return true
}
2 changes: 2 additions & 0 deletions examples/gno.land/p/demo/uassert/uassert_test.gno
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ func TestEmpty(t *testing.T) {
{"", true},
{0, true},
{int(0), true},
{int32(0), true},
{int64(0), true},
{uint(0), true},
// XXX: continue
Expand Down Expand Up @@ -258,6 +259,7 @@ func TestNotEmpty(t *testing.T) {
{"", false},
{0, false},
{int(0), false},
{int32(0), false},
{int64(0), false},
{uint(0), false},
{std.Address(""), false},
Expand Down
4 changes: 3 additions & 1 deletion gnovm/pkg/gnolang/op_binary.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ func (m *Machine) doOpEql() {
if debug {
debugAssertEqualityTypes(lv.T, rv.T)
}

// set result in lv.
res := isEql(m.Store, lv, rv)
lv.T = UntypedBoolType
Expand Down Expand Up @@ -344,6 +343,9 @@ func isEql(store Store, lv, rv *TypedValue) bool {
} else if rvu {
return false
}
if err := checkSame(lv.T, rv.T, ""); err != nil {
return false
}
if lnt, ok := lv.T.(*NativeType); ok {
if rnt, ok := rv.T.(*NativeType); ok {
if lnt.Type != rnt.Type {
Expand Down
7 changes: 6 additions & 1 deletion gnovm/pkg/gnolang/op_expressions.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,13 @@ func (m *Machine) doOpRef() {
nv.Value = rv2
}
}
// when obtaining a pointer of the databyte type, use the ElemType of databyte
elt := xv.TV.T
if elt == DataByteType {
ltzmaxwell marked this conversation as resolved.
Show resolved Hide resolved
elt = xv.TV.V.(DataByteValue).ElemType
piux2 marked this conversation as resolved.
Show resolved Hide resolved
}
m.PushValue(TypedValue{
T: m.Alloc.NewType(&PointerType{Elt: xv.TV.T}),
T: m.Alloc.NewType(&PointerType{Elt: elt}),
V: xv,
})
}
Expand Down
13 changes: 11 additions & 2 deletions gnovm/pkg/gnolang/preprocess.go
Original file line number Diff line number Diff line change
Expand Up @@ -1498,6 +1498,13 @@ func Preprocess(store Store, ctx BlockNode, n Node) Node {
checkOrConvertIntegerKind(store, last, n.High)
checkOrConvertIntegerKind(store, last, n.Max)

// if n.X is untyped, convert to corresponding type
t := evalStaticTypeOf(store, last, n.X)
ltzmaxwell marked this conversation as resolved.
Show resolved Hide resolved
if isUntyped(t) {
dt := defaultTypeOf(t)
checkOrConvertType(store, last, &n.X, dt, false)
}

// TRANS_LEAVE -----------------------
case *TypeAssertExpr:
if n.Type == nil {
Expand Down Expand Up @@ -2781,8 +2788,10 @@ func checkOrConvertType(store Store, last BlockNode, x *Expr, t Type, autoNative
// push t into bx.Left
checkOrConvertType(store, last, &bx.Left, t, autoNative)
return
// case EQL, LSS, GTR, NEQ, LEQ, GEQ:
// default:
case EQL, LSS, GTR, NEQ, LEQ, GEQ:
deelawn marked this conversation as resolved.
Show resolved Hide resolved
// do nothing
default:
// do nothing
}
}
}
Expand Down
12 changes: 12 additions & 0 deletions gnovm/tests/files/types/cmp_databyte.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package main

import "bytes"

func main() {
cmp := bytes.Compare([]byte("hello"), []byte("hey"))
println(cmp)

}

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

import (
"errors"
"strconv"
)

type Error int64

func (e Error) Error() string {
return "error: " + strconv.Itoa(int(e))
}

var errCmp = errors.New("XXXX")

// special case:
// one is interface
func main() {
if Error(0) == errCmp {
println("what the firetruck?")
} else {
println("something else")
}
}

// Output:
// something else
29 changes: 29 additions & 0 deletions gnovm/tests/files/types/cmp_iface_1.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package main

import (
"errors"
"strconv"
)

type Error int64

func (e Error) Error() string {
return "error: " + strconv.Itoa(int(e))
}

// typed
var errCmp error = errors.New("XXXX")

// special case:
// one is interface
func main() {
const e Error = Error(0) // typed const
if e == errCmp {
println("what the firetruck?")
} else {
println("something else")
}
}

// Output:
// something else
32 changes: 32 additions & 0 deletions gnovm/tests/files/types/cmp_iface_2.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package main

import (
"fmt"
"strconv"
)

type E interface {
Error() string
}
type Error int64

func (e Error) Error() string {
return "error: " + strconv.Itoa(int(e))
}

// special case:
// one is interface
func main() {
var e0 E
e0 = Error(0)
fmt.Printf("%T \n", e0)
if e0 == Error(0) {
println("what the firetruck?")
} else {
println("something else")
}
}

// Output:
// int64
// what the firetruck?
27 changes: 27 additions & 0 deletions gnovm/tests/files/types/cmp_iface_3_stdlibs.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package main

import (
"errors"
"strconv"
)

type Error int64

func (e Error) Error() string {
return "error: " + strconv.Itoa(int(e))
}

var errCmp = errors.New("XXXX")

// special case:
// one is interface
func main() {
if Error(1) == errCmp {
println("what the firetruck?")
} else {
println("something else")
}
}

// Output:
// something else
24 changes: 24 additions & 0 deletions gnovm/tests/files/types/cmp_iface_4.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package main

import (
"strconv"
)

type Error int64

func (e Error) Error() string {
return "error: " + strconv.Itoa(int(e))
}

// both not const, and both interface
func main() {
var l interface{}
if l == Error(0) {
println("what the firetruck?")
} else {
println("something else")
}
}

// Output:
// something else
27 changes: 27 additions & 0 deletions gnovm/tests/files/types/cmp_iface_5_stdlibs.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package main

import (
"errors"
"strconv"
)

type Error int64

func (e Error) Error() string {
return "error: " + strconv.Itoa(int(e))
}

var errCmp = errors.New("XXXX")

// special case:
// one is interface
func main() {
if errCmp == int64(1) {
println("what the firetruck?")
} else {
println("something else")
}
}

// Error:
// main/files/types/cmp_iface_5_stdlibs.gno:19:5: int64 does not implement .uverse.error (missing method Error)
Loading
Loading