github.com/goplus/igop@v0.25.0/interp_go117_test.go (about) 1 //go:build go1.17 2 // +build go1.17 3 4 /* 5 * Copyright (c) 2022 The GoPlus Authors (goplus.org). All rights reserved. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20 package igop_test 21 22 import ( 23 "runtime" 24 "strings" 25 "testing" 26 27 "github.com/goplus/igop" 28 ) 29 30 func TestUnsafeBuiltins(t *testing.T) { 31 src := `// run 32 33 // Copyright 2021 The Go Authors. All rights reserved. 34 // Use of this source code is governed by a BSD-style 35 // license that can be found in the LICENSE file. 36 37 package main 38 39 import ( 40 "math" 41 "unsafe" 42 ) 43 44 const maxUintptr = 1 << (8 * unsafe.Sizeof(uintptr(0))) 45 46 func main() { 47 var p [10]byte 48 49 // unsafe.Add 50 { 51 p1 := unsafe.Pointer(&p[1]) 52 assert(unsafe.Add(p1, 1) == unsafe.Pointer(&p[2])) 53 assert(unsafe.Add(p1, -1) == unsafe.Pointer(&p[0])) 54 } 55 56 // unsafe.Slice 57 { 58 s := unsafe.Slice(&p[0], len(p)) 59 assert(&s[0] == &p[0]) 60 assert(len(s) == len(p)) 61 assert(cap(s) == len(p)) 62 63 // nil pointer with zero length returns nil 64 assert(unsafe.Slice((*int)(nil), 0) == nil) 65 66 // nil pointer with positive length panics 67 mustPanic(func() { _ = unsafe.Slice((*int)(nil), 1) }) 68 69 // negative length 70 var neg int = -1 71 mustPanic(func() { _ = unsafe.Slice(new(byte), neg) }) 72 73 // length too large 74 var tooBig uint64 = math.MaxUint64 75 mustPanic(func() { _ = unsafe.Slice(new(byte), tooBig) }) 76 77 // size overflows address space 78 mustPanic(func() { _ = unsafe.Slice(new(uint64), maxUintptr/8) }) 79 mustPanic(func() { _ = unsafe.Slice(new(uint64), maxUintptr/8+1) }) 80 } 81 } 82 83 func assert(ok bool) { 84 if !ok { 85 panic("FAIL") 86 } 87 } 88 89 func mustPanic(f func()) { 90 defer func() { 91 assert(recover() != nil) 92 }() 93 f() 94 } 95 ` 96 _, err := igop.RunFile("main.go", src, nil, 0) 97 if err != nil { 98 t.Fatal(err) 99 } 100 } 101 102 func TestSliceToArrayPointer(t *testing.T) { 103 src := `// run 104 105 // Copyright 2020 The Go Authors. All rights reserved. 106 // Use of this source code is governed by a BSD-style 107 // license that can be found in the LICENSE file. 108 109 // Test conversion from slice to array pointer. 110 111 package main 112 113 func wantPanic(fn func(), s string) { 114 defer func() { 115 err := recover() 116 if err == nil { 117 panic("expected panic") 118 } 119 if got := err.(error).Error(); got != s { 120 panic("expected panic " + s + " got " + got) 121 } 122 }() 123 fn() 124 } 125 126 func main() { 127 s := make([]byte, 8, 10) 128 if p := (*[8]byte)(s); &p[0] != &s[0] { 129 panic("*[8]byte conversion failed") 130 } 131 wantPanic( 132 func() { 133 _ = (*[9]byte)(s) 134 }, 135 "runtime error: cannot convert slice with length 8 to pointer to array with length 9", 136 ) 137 138 var n []byte 139 if p := (*[0]byte)(n); p != nil { 140 panic("nil slice converted to *[0]byte should be nil") 141 } 142 143 z := make([]byte, 0) 144 if p := (*[0]byte)(z); p == nil { 145 panic("empty slice converted to *[0]byte should be non-nil") 146 } 147 148 // Test with named types 149 type Slice []int 150 type Int4 [4]int 151 type PInt4 *[4]int 152 ii := make(Slice, 4) 153 if p := (*Int4)(ii); &p[0] != &ii[0] { 154 panic("*Int4 conversion failed") 155 } 156 if p := PInt4(ii); &p[0] != &ii[0] { 157 panic("PInt4 conversion failed") 158 } 159 } 160 161 // test static variable conversion 162 163 var ( 164 ss = make([]string, 10) 165 s5 = (*[5]string)(ss) 166 s10 = (*[10]string)(ss) 167 168 ns []string 169 ns0 = (*[0]string)(ns) 170 171 zs = make([]string, 0) 172 zs0 = (*[0]string)(zs) 173 ) 174 175 func init() { 176 if &ss[0] != &s5[0] { 177 panic("s5 conversion failed") 178 } 179 if &ss[0] != &s10[0] { 180 panic("s5 conversion failed") 181 } 182 if ns0 != nil { 183 panic("ns0 should be nil") 184 } 185 if zs0 == nil { 186 panic("zs0 should not be nil") 187 } 188 } 189 ` 190 if strings.HasPrefix(runtime.Version(), "go1.2") { 191 src = strings.ReplaceAll(src, "to pointer to array", "to array or pointer to array") 192 } 193 _, err := igop.RunFile("main.go", src, nil, 0) 194 if err != nil { 195 t.Fatal(err) 196 } 197 }