aboutsummaryrefslogtreecommitdiff
path: root/go/ssa/interp/testdata
diff options
context:
space:
mode:
Diffstat (limited to 'go/ssa/interp/testdata')
-rw-r--r--go/ssa/interp/testdata/boundmeth.go3
-rw-r--r--go/ssa/interp/testdata/convert.go9
-rw-r--r--go/ssa/interp/testdata/deepequal.go93
-rw-r--r--go/ssa/interp/testdata/fixedbugs/issue52342.go17
-rw-r--r--go/ssa/interp/testdata/fixedbugs/issue52835.go27
-rw-r--r--go/ssa/interp/testdata/fixedbugs/issue55086.go132
-rw-r--r--go/ssa/interp/testdata/slice2array.go92
-rw-r--r--go/ssa/interp/testdata/slice2arrayptr.go2
-rw-r--r--go/ssa/interp/testdata/src/encoding/encoding.go15
-rw-r--r--go/ssa/interp/testdata/src/log/log.go8
-rw-r--r--go/ssa/interp/testdata/src/reflect/deepequal.go109
-rw-r--r--go/ssa/interp/testdata/src/reflect/reflect.go13
-rw-r--r--go/ssa/interp/testdata/typeassert.go32
-rw-r--r--go/ssa/interp/testdata/width32.go42
-rw-r--r--go/ssa/interp/testdata/zeros.go45
15 files changed, 637 insertions, 2 deletions
diff --git a/go/ssa/interp/testdata/boundmeth.go b/go/ssa/interp/testdata/boundmeth.go
index 69937f9d3..47b940685 100644
--- a/go/ssa/interp/testdata/boundmeth.go
+++ b/go/ssa/interp/testdata/boundmeth.go
@@ -123,7 +123,8 @@ func nilInterfaceMethodValue() {
r := fmt.Sprint(recover())
// runtime panic string varies across toolchains
if r != "interface conversion: interface is nil, not error" &&
- r != "runtime error: invalid memory address or nil pointer dereference" {
+ r != "runtime error: invalid memory address or nil pointer dereference" &&
+ r != "method value: interface is nil" {
panic("want runtime panic from nil interface method value, got " + r)
}
}()
diff --git a/go/ssa/interp/testdata/convert.go b/go/ssa/interp/testdata/convert.go
index 0dcf13bdd..76310405f 100644
--- a/go/ssa/interp/testdata/convert.go
+++ b/go/ssa/interp/testdata/convert.go
@@ -22,6 +22,15 @@ func main() {
},
"runtime error: negative shift amount",
)
+ wantPanic(
+ func() {
+ const maxInt32 = 1<<31 - 1
+ var idx int64 = maxInt32*2 + 8
+ x := make([]int, 16)
+ _ = x[idx]
+ },
+ "runtime error: runtime error: index out of range [4294967302] with length 16",
+ )
}
func wantPanic(fn func(), s string) {
diff --git a/go/ssa/interp/testdata/deepequal.go b/go/ssa/interp/testdata/deepequal.go
new file mode 100644
index 000000000..4fad2d657
--- /dev/null
+++ b/go/ssa/interp/testdata/deepequal.go
@@ -0,0 +1,93 @@
+// This interpreter test is designed to test the test copy of DeepEqual.
+//
+// Validate this file with 'go run' after editing.
+
+package main
+
+import "reflect"
+
+func assert(cond bool) {
+ if !cond {
+ panic("failed")
+ }
+}
+
+type X int
+type Y struct {
+ y *Y
+ z [3]int
+}
+
+var (
+ a = []int{0, 1, 2, 3}
+ b = []X{0, 1, 2, 3}
+ c = map[int]string{0: "zero", 1: "one"}
+ d = map[X]string{0: "zero", 1: "one"}
+ e = &Y{}
+ f = (*Y)(nil)
+ g = &Y{y: e}
+ h *Y
+)
+
+func init() {
+ h = &Y{} // h->h
+ h.y = h
+}
+
+func main() {
+ assert(reflect.DeepEqual(nil, nil))
+ assert(reflect.DeepEqual((*int)(nil), (*int)(nil)))
+ assert(!reflect.DeepEqual(nil, (*int)(nil)))
+
+ assert(reflect.DeepEqual(0, 0))
+ assert(!reflect.DeepEqual(0, int64(0)))
+
+ assert(!reflect.DeepEqual("", 0))
+
+ assert(reflect.DeepEqual(a, []int{0, 1, 2, 3}))
+ assert(!reflect.DeepEqual(a, []int{0, 1, 2}))
+ assert(!reflect.DeepEqual(a, []int{0, 1, 0, 3}))
+
+ assert(reflect.DeepEqual(b, []X{0, 1, 2, 3}))
+ assert(!reflect.DeepEqual(b, []X{0, 1, 0, 3}))
+
+ assert(reflect.DeepEqual(c, map[int]string{0: "zero", 1: "one"}))
+ assert(!reflect.DeepEqual(c, map[int]string{0: "zero", 1: "one", 2: "two"}))
+ assert(!reflect.DeepEqual(c, map[int]string{1: "one", 2: "two"}))
+ assert(!reflect.DeepEqual(c, map[int]string{1: "one"}))
+
+ assert(reflect.DeepEqual(d, map[X]string{0: "zero", 1: "one"}))
+ assert(!reflect.DeepEqual(d, map[int]string{0: "zero", 1: "one"}))
+
+ assert(reflect.DeepEqual(e, &Y{}))
+ assert(reflect.DeepEqual(e, &Y{z: [3]int{0, 0, 0}}))
+ assert(!reflect.DeepEqual(e, &Y{z: [3]int{0, 1, 0}}))
+
+ assert(reflect.DeepEqual(f, (*Y)(nil)))
+ assert(!reflect.DeepEqual(f, nil))
+
+ // eq_h -> eq_h. Pointer structure and elements are equal so DeepEqual.
+ eq_h := &Y{}
+ eq_h.y = eq_h
+ assert(reflect.DeepEqual(h, eq_h))
+
+ // deepeq_h->h->h. Pointed to elem of (deepeq_h, h) are (h,h). (h,h) are deep equal so h and deepeq_h are DeepEqual.
+ deepeq_h := &Y{}
+ deepeq_h.y = h
+ assert(reflect.DeepEqual(h, deepeq_h))
+
+ distinct := []interface{}{a, b, c, d, e, f, g, h}
+ for x := range distinct {
+ for y := range distinct {
+ assert((x == y) == reflect.DeepEqual(distinct[x], distinct[y]))
+ }
+ }
+
+ // anonymous struct types.
+ assert(reflect.DeepEqual(struct{}{}, struct{}{}))
+ assert(reflect.DeepEqual(struct{ x int }{1}, struct{ x int }{1}))
+ assert(!reflect.DeepEqual(struct{ x int }{}, struct{ x int }{5}))
+ assert(!reflect.DeepEqual(struct{ x, y int }{0, 1}, struct{ x int }{0}))
+ assert(reflect.DeepEqual(struct{ x, y int }{2, 3}, struct{ x, y int }{2, 3}))
+ assert(!reflect.DeepEqual(struct{ x, y int }{4, 5}, struct{ x, y int }{4, 6}))
+}
diff --git a/go/ssa/interp/testdata/fixedbugs/issue52342.go b/go/ssa/interp/testdata/fixedbugs/issue52342.go
new file mode 100644
index 000000000..2e1cc63cf
--- /dev/null
+++ b/go/ssa/interp/testdata/fixedbugs/issue52342.go
@@ -0,0 +1,17 @@
+package main
+
+func main() {
+ var d byte
+
+ d = 1
+ d <<= 256
+ if d != 0 {
+ panic(d)
+ }
+
+ d = 1
+ d >>= 256
+ if d != 0 {
+ panic(d)
+ }
+}
diff --git a/go/ssa/interp/testdata/fixedbugs/issue52835.go b/go/ssa/interp/testdata/fixedbugs/issue52835.go
new file mode 100644
index 000000000..f1d99abb7
--- /dev/null
+++ b/go/ssa/interp/testdata/fixedbugs/issue52835.go
@@ -0,0 +1,27 @@
+package main
+
+var called bool
+
+type I interface {
+ Foo()
+}
+
+type A struct{}
+
+func (a A) Foo() {
+ called = true
+}
+
+func lambda[X I]() func() func() {
+ return func() func() {
+ var x X
+ return x.Foo
+ }
+}
+
+func main() {
+ lambda[A]()()()
+ if !called {
+ panic(called)
+ }
+}
diff --git a/go/ssa/interp/testdata/fixedbugs/issue55086.go b/go/ssa/interp/testdata/fixedbugs/issue55086.go
new file mode 100644
index 000000000..84c81e91a
--- /dev/null
+++ b/go/ssa/interp/testdata/fixedbugs/issue55086.go
@@ -0,0 +1,132 @@
+// 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.
+
+package main
+
+func a() (r string) {
+ s := "initial"
+ var p *struct{ i int }
+ defer func() {
+ recover()
+ r = s
+ }()
+
+ s, p.i = "set", 2 // s must be set before p.i panics
+ return "unreachable"
+}
+
+func b() (r string) {
+ s := "initial"
+ fn := func() []int { panic("") }
+ defer func() {
+ recover()
+ r = s
+ }()
+
+ s, fn()[0] = "set", 2 // fn() panics before any assignment occurs
+ return "unreachable"
+}
+
+func c() (r string) {
+ s := "initial"
+ var p map[int]int
+ defer func() {
+ recover()
+ r = s
+ }()
+
+ s, p[0] = "set", 2 //s must be set before p[0] index panics"
+ return "unreachable"
+}
+
+func d() (r string) {
+ s := "initial"
+ var p map[int]int
+ defer func() {
+ recover()
+ r = s
+ }()
+ fn := func() int { panic("") }
+
+ s, p[0] = "set", fn() // fn() panics before s is set
+ return "unreachable"
+}
+
+func e() (r string) {
+ s := "initial"
+ p := map[int]int{}
+ defer func() {
+ recover()
+ r = s
+ }()
+ fn := func() int { panic("") }
+
+ s, p[fn()] = "set", 0 // fn() panics before any assignment occurs
+ return "unreachable"
+}
+
+func f() (r string) {
+ s := "initial"
+ p := []int{}
+ defer func() {
+ recover()
+ r = s
+ }()
+
+ s, p[1] = "set", 0 // p[1] panics after s is set
+ return "unreachable"
+}
+
+func g() (r string) {
+ s := "initial"
+ p := map[any]any{}
+ defer func() {
+ recover()
+ r = s
+ }()
+ var i any = func() {}
+ s, p[i] = "set", 0 // p[i] panics after s is set
+ return "unreachable"
+}
+
+func h() (r string) {
+ fail := false
+ defer func() {
+ recover()
+ if fail {
+ r = "fail"
+ } else {
+ r = "success"
+ }
+ }()
+
+ type T struct{ f int }
+ var p *struct{ *T }
+
+ // The implicit "p.T" operand should be evaluated in phase 1 (and panic),
+ // before the "fail = true" assignment in phase 2.
+ fail, p.f = true, 0
+ return "unreachable"
+}
+
+func main() {
+ for _, test := range []struct {
+ fn func() string
+ want string
+ desc string
+ }{
+ {a, "set", "s must be set before p.i panics"},
+ {b, "initial", "p() panics before s is set"},
+ {c, "set", "s must be set before p[0] index panics"},
+ {d, "initial", "fn() panics before s is set"},
+ {e, "initial", "fn() panics before s is set"},
+ {f, "set", "p[1] panics after s is set"},
+ {g, "set", "p[i] panics after s is set"},
+ {h, "success", "p.T panics before fail is set"},
+ } {
+ if test.fn() != test.want {
+ panic(test.desc)
+ }
+ }
+}
diff --git a/go/ssa/interp/testdata/slice2array.go b/go/ssa/interp/testdata/slice2array.go
new file mode 100644
index 000000000..84e6b7330
--- /dev/null
+++ b/go/ssa/interp/testdata/slice2array.go
@@ -0,0 +1,92 @@
+// 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 for slice to array conversion introduced in go1.20
+// See: https://tip.golang.org/ref/spec#Conversions_from_slice_to_array_pointer
+
+package main
+
+func main() {
+ s := make([]byte, 3, 4)
+ s[0], s[1], s[2] = 2, 3, 5
+ a := ([2]byte)(s)
+ s[0] = 7
+
+ if a != [2]byte{2, 3} {
+ panic("converted from non-nil slice to array")
+ }
+
+ {
+ var s []int
+ a := ([0]int)(s)
+ if a != [0]int{} {
+ panic("zero len array is not equal")
+ }
+ }
+
+ if emptyToEmptyDoesNotPanic() {
+ panic("no panic expected from emptyToEmptyDoesNotPanic()")
+ }
+ if !threeToFourDoesPanic() {
+ panic("panic expected from threeToFourDoesPanic()")
+ }
+
+ if !fourPanicsWhileOneDoesNot[[4]int]() {
+ panic("panic expected from fourPanicsWhileOneDoesNot[[4]int]()")
+ }
+ if fourPanicsWhileOneDoesNot[[1]int]() {
+ panic("no panic expected from fourPanicsWhileOneDoesNot[[1]int]()")
+ }
+
+ if !fourPanicsWhileZeroDoesNot[[4]int]() {
+ panic("panic expected from fourPanicsWhileZeroDoesNot[[4]int]()")
+ }
+ if fourPanicsWhileZeroDoesNot[[0]int]() {
+ panic("no panic expected from fourPanicsWhileZeroDoesNot[[0]int]()")
+ }
+}
+
+func emptyToEmptyDoesNotPanic() (raised bool) {
+ defer func() {
+ if e := recover(); e != nil {
+ raised = true
+ }
+ }()
+ var s []int
+ _ = ([0]int)(s)
+ return false
+}
+
+func threeToFourDoesPanic() (raised bool) {
+ defer func() {
+ if e := recover(); e != nil {
+ raised = true
+ }
+ }()
+ s := make([]int, 3, 5)
+ _ = ([4]int)(s)
+ return false
+}
+
+func fourPanicsWhileOneDoesNot[T [1]int | [4]int]() (raised bool) {
+ defer func() {
+ if e := recover(); e != nil {
+ raised = true
+ }
+ }()
+ s := make([]int, 3, 5)
+ _ = T(s)
+ return false
+}
+
+func fourPanicsWhileZeroDoesNot[T [0]int | [4]int]() (raised bool) {
+ defer func() {
+ if e := recover(); e != nil {
+ raised = true
+ }
+ }()
+ var s []int
+ _ = T(s)
+ return false
+}
diff --git a/go/ssa/interp/testdata/slice2arrayptr.go b/go/ssa/interp/testdata/slice2arrayptr.go
index ff2d9b55c..d9d8804d3 100644
--- a/go/ssa/interp/testdata/slice2arrayptr.go
+++ b/go/ssa/interp/testdata/slice2arrayptr.go
@@ -32,6 +32,8 @@ func main() {
},
"runtime error: array length is greater than slice length",
)
+
+ f()
}
type arr [2]int
diff --git a/go/ssa/interp/testdata/src/encoding/encoding.go b/go/ssa/interp/testdata/src/encoding/encoding.go
new file mode 100644
index 000000000..73e9de494
--- /dev/null
+++ b/go/ssa/interp/testdata/src/encoding/encoding.go
@@ -0,0 +1,15 @@
+package encoding
+
+type BinaryMarshaler interface {
+ MarshalBinary() (data []byte, err error)
+}
+type BinaryUnmarshaler interface {
+ UnmarshalBinary(data []byte) error
+}
+
+type TextMarshaler interface {
+ MarshalText() (text []byte, err error)
+}
+type TextUnmarshaler interface {
+ UnmarshalText(text []byte) error
+}
diff --git a/go/ssa/interp/testdata/src/log/log.go b/go/ssa/interp/testdata/src/log/log.go
index 8897c1d21..9a57e8c1c 100644
--- a/go/ssa/interp/testdata/src/log/log.go
+++ b/go/ssa/interp/testdata/src/log/log.go
@@ -8,8 +8,16 @@ import (
func Println(v ...interface{}) {
fmt.Println(v...)
}
+func Printf(format string, v ...interface{}) {
+ fmt.Printf(format, v...)
+}
func Fatalln(v ...interface{}) {
Println(v...)
os.Exit(1)
}
+
+func Fatalf(format string, v ...interface{}) {
+ Printf(format, v...)
+ os.Exit(1)
+}
diff --git a/go/ssa/interp/testdata/src/reflect/deepequal.go b/go/ssa/interp/testdata/src/reflect/deepequal.go
new file mode 100644
index 000000000..a48e4dafa
--- /dev/null
+++ b/go/ssa/interp/testdata/src/reflect/deepequal.go
@@ -0,0 +1,109 @@
+package reflect
+
+// Not an actual implementation of DeepEqual. This is a model that supports
+// the bare minimum needed to get through testing interp.
+//
+// Does not handle cycles.
+//
+// Note: unclear if reflect.go can support this.
+func DeepEqual(x, y interface{}) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ v1 := ValueOf(x)
+ v2 := ValueOf(y)
+
+ return deepValueEqual(v1, v2, make(map[visit]bool))
+}
+
+// Key for the visitedMap in deepValueEqual.
+type visit struct {
+ a1, a2 uintptr
+ typ Type
+}
+
+func deepValueEqual(v1, v2 Value, visited map[visit]bool) bool {
+ if !v1.IsValid() || !v2.IsValid() {
+ return v1.IsValid() == v2.IsValid()
+ }
+ if v1.Type() != v2.Type() {
+ return false
+ }
+
+ // Short circuit on reference types that can lead to cycles in comparison.
+ switch v1.Kind() {
+ case Pointer, Map, Slice, Interface:
+ k := visit{v1.Pointer(), v2.Pointer(), v1.Type()} // Not safe for moving GC.
+ if visited[k] {
+ // The comparison algorithm assumes that all checks in progress are true when it reencounters them.
+ return true
+ }
+ visited[k] = true
+ }
+
+ switch v1.Kind() {
+ case Array:
+ for i := 0; i < v1.Len(); i++ {
+ if !deepValueEqual(v1.Index(i), v2.Index(i), visited) {
+ return false
+ }
+ }
+ return true
+ case Slice:
+ if v1.IsNil() != v2.IsNil() {
+ return false
+ }
+ if v1.Len() != v2.Len() {
+ return false
+ }
+ if v1.Pointer() == v2.Pointer() {
+ return true
+ }
+ for i := 0; i < v1.Len(); i++ {
+ if !deepValueEqual(v1.Index(i), v2.Index(i), visited) {
+ return false
+ }
+ }
+ return true
+ case Interface:
+ if v1.IsNil() || v2.IsNil() {
+ return v1.IsNil() == v2.IsNil()
+ }
+ return deepValueEqual(v1.Elem(), v2.Elem(), visited)
+ case Ptr:
+ if v1.Pointer() == v2.Pointer() {
+ return true
+ }
+ return deepValueEqual(v1.Elem(), v2.Elem(), visited)
+ case Struct:
+ for i, n := 0, v1.NumField(); i < n; i++ {
+ if !deepValueEqual(v1.Field(i), v2.Field(i), visited) {
+ return false
+ }
+ }
+ return true
+ case Map:
+ if v1.IsNil() != v2.IsNil() {
+ return false
+ }
+ if v1.Len() != v2.Len() {
+ return false
+ }
+ if v1.Pointer() == v2.Pointer() {
+ return true
+ }
+ for _, k := range v1.MapKeys() {
+ val1 := v1.MapIndex(k)
+ val2 := v2.MapIndex(k)
+ if !val1.IsValid() || !val2.IsValid() || !deepValueEqual(val1, val2, visited) {
+ return false
+ }
+ }
+ return true
+ case Func:
+ return v1.IsNil() && v2.IsNil()
+ default:
+ // Normal equality suffices
+ return v1.Interface() == v2.Interface() // try interface comparison as a fallback.
+ }
+}
diff --git a/go/ssa/interp/testdata/src/reflect/reflect.go b/go/ssa/interp/testdata/src/reflect/reflect.go
index 8a23d272f..207e7dcfd 100644
--- a/go/ssa/interp/testdata/src/reflect/reflect.go
+++ b/go/ssa/interp/testdata/src/reflect/reflect.go
@@ -11,9 +11,20 @@ type Value struct {
func (Value) String() string
-func (Value) Elem() string
+func (Value) Elem() Value
func (Value) Kind() Kind
func (Value) Int() int64
+func (Value) IsValid() bool
+func (Value) IsNil() bool
+func (Value) Len() int
+func (Value) Pointer() uintptr
+func (Value) Index(i int) Value
+func (Value) Type() Type
+func (Value) Field(int) Value
+func (Value) MapIndex(Value) Value
+func (Value) MapKeys() []Value
+func (Value) NumField() int
+func (Value) Interface() interface{}
func SliceOf(Type) Type
diff --git a/go/ssa/interp/testdata/typeassert.go b/go/ssa/interp/testdata/typeassert.go
new file mode 100644
index 000000000..792a7558f
--- /dev/null
+++ b/go/ssa/interp/testdata/typeassert.go
@@ -0,0 +1,32 @@
+// Tests of type asserts.
+// Requires type parameters.
+package typeassert
+
+type fooer interface{ foo() string }
+
+type X int
+
+func (_ X) foo() string { return "x" }
+
+func f[T fooer](x T) func() string {
+ return x.foo
+}
+
+func main() {
+ if f[X](0)() != "x" {
+ panic("f[X]() != 'x'")
+ }
+
+ p := false
+ func() {
+ defer func() {
+ if recover() != nil {
+ p = true
+ }
+ }()
+ f[fooer](nil) // panics on x.foo when T is an interface and nil.
+ }()
+ if !p {
+ panic("f[fooer] did not panic")
+ }
+}
diff --git a/go/ssa/interp/testdata/width32.go b/go/ssa/interp/testdata/width32.go
new file mode 100644
index 000000000..a032ba44c
--- /dev/null
+++ b/go/ssa/interp/testdata/width32.go
@@ -0,0 +1,42 @@
+// 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 interpretation on 32 bit widths.
+
+package main
+
+func main() {
+ mapSize()
+}
+
+func mapSize() {
+ // Tests for the size argument of make on a map type.
+ const tooBigFor32 = 1<<33 - 1
+ wantPanic(
+ func() {
+ _ = make(map[int]int, int64(tooBigFor32))
+ },
+ "runtime error: ssa.MakeMap.Reserve value 8589934591 does not fit in int",
+ )
+
+ // TODO: Enable the following if sizeof(int) can be different for host and target.
+ // _ = make(map[int]int, tooBigFor32)
+ //
+ // Second arg to make in `make(map[int]int, tooBigFor32)` is an untyped int and
+ // is converted into an int explicitly in ssa.
+ // This has a different value on 32 and 64 bit systems.
+}
+
+func wantPanic(fn func(), s string) {
+ defer func() {
+ err := recover()
+ if err == nil {
+ panic("expected panic")
+ }
+ if got := err.(error).Error(); got != s {
+ panic("expected panic " + s + " got " + got)
+ }
+ }()
+ fn()
+}
diff --git a/go/ssa/interp/testdata/zeros.go b/go/ssa/interp/testdata/zeros.go
new file mode 100644
index 000000000..509c78a36
--- /dev/null
+++ b/go/ssa/interp/testdata/zeros.go
@@ -0,0 +1,45 @@
+// 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 interpretation on zero values with type params.
+package zeros
+
+func assert(cond bool, msg string) {
+ if !cond {
+ panic(msg)
+ }
+}
+
+func tp0[T int | string | float64]() T { return T(0) }
+
+func tpFalse[T ~bool]() T { return T(false) }
+
+func tpEmptyString[T string | []byte]() T { return T("") }
+
+func tpNil[T *int | []byte]() T { return T(nil) }
+
+func main() {
+ // zero values
+ var zi int
+ var zf float64
+ var zs string
+
+ assert(zi == int(0), "zero value of int is int(0)")
+ assert(zf == float64(0), "zero value of float64 is float64(0)")
+ assert(zs != string(0), "zero value of string is not string(0)")
+
+ assert(zi == tp0[int](), "zero value of int is int(0)")
+ assert(zf == tp0[float64](), "zero value of float64 is float64(0)")
+ assert(zs != tp0[string](), "zero value of string is not string(0)")
+
+ assert(zf == -0.0, "constant -0.0 is converted to 0.0")
+
+ assert(!tpFalse[bool](), "zero value of bool is false")
+
+ assert(tpEmptyString[string]() == zs, `zero value of string is string("")`)
+ assert(len(tpEmptyString[[]byte]()) == 0, `[]byte("") is empty`)
+
+ assert(tpNil[*int]() == nil, "nil is nil")
+ assert(tpNil[[]byte]() == nil, "nil is nil")
+}