github.com/goplus/gossa@v0.3.25/interp_go117_test.go (about)

     1  //go:build go1.17
     2  // +build go1.17
     3  
     4  package gossa_test
     5  
     6  import (
     7  	"testing"
     8  
     9  	"github.com/goplus/gossa"
    10  )
    11  
    12  func TestUnsafeBuiltins(t *testing.T) {
    13  	src := `// run
    14  
    15  // Copyright 2021 The Go Authors. All rights reserved.
    16  // Use of this source code is governed by a BSD-style
    17  // license that can be found in the LICENSE file.
    18  
    19  package main
    20  
    21  import (
    22  	"math"
    23  	"unsafe"
    24  )
    25  
    26  const maxUintptr = 1 << (8 * unsafe.Sizeof(uintptr(0)))
    27  
    28  func main() {
    29  	var p [10]byte
    30  
    31  	// unsafe.Add
    32  	{
    33  		p1 := unsafe.Pointer(&p[1])
    34  		assert(unsafe.Add(p1, 1) == unsafe.Pointer(&p[2]))
    35  		assert(unsafe.Add(p1, -1) == unsafe.Pointer(&p[0]))
    36  	}
    37  
    38  	// unsafe.Slice
    39  	{
    40  		s := unsafe.Slice(&p[0], len(p))
    41  		assert(&s[0] == &p[0])
    42  		assert(len(s) == len(p))
    43  		assert(cap(s) == len(p))
    44  
    45  		// nil pointer with zero length returns nil
    46  		assert(unsafe.Slice((*int)(nil), 0) == nil)
    47  
    48  		// nil pointer with positive length panics
    49  		mustPanic(func() { _ = unsafe.Slice((*int)(nil), 1) })
    50  
    51  		// negative length
    52  		var neg int = -1
    53  		mustPanic(func() { _ = unsafe.Slice(new(byte), neg) })
    54  
    55  		// length too large
    56  		var tooBig uint64 = math.MaxUint64
    57  		mustPanic(func() { _ = unsafe.Slice(new(byte), tooBig) })
    58  
    59  		// size overflows address space
    60  		mustPanic(func() { _ = unsafe.Slice(new(uint64), maxUintptr/8) })
    61  		mustPanic(func() { _ = unsafe.Slice(new(uint64), maxUintptr/8+1) })
    62  	}
    63  }
    64  
    65  func assert(ok bool) {
    66  	if !ok {
    67  		panic("FAIL")
    68  	}
    69  }
    70  
    71  func mustPanic(f func()) {
    72  	defer func() {
    73  		assert(recover() != nil)
    74  	}()
    75  	f()
    76  }
    77  `
    78  	_, err := gossa.RunFile("main.go", src, nil, 0)
    79  	if err != nil {
    80  		t.Fatal(err)
    81  	}
    82  }
    83  
    84  func TestSliceToArrayPointer(t *testing.T) {
    85  	src := `// run
    86  
    87  // Copyright 2020 The Go Authors. All rights reserved.
    88  // Use of this source code is governed by a BSD-style
    89  // license that can be found in the LICENSE file.
    90  
    91  // Test conversion from slice to array pointer.
    92  
    93  package main
    94  
    95  func wantPanic(fn func(), s string) {
    96  	defer func() {
    97  		err := recover()
    98  		if err == nil {
    99  			panic("expected panic")
   100  		}
   101  		if got := err.(error).Error(); got != s {
   102  			panic("expected panic " + s + " got " + got)
   103  		}
   104  	}()
   105  	fn()
   106  }
   107  
   108  func main() {
   109  	s := make([]byte, 8, 10)
   110  	if p := (*[8]byte)(s); &p[0] != &s[0] {
   111  		panic("*[8]byte conversion failed")
   112  	}
   113  	wantPanic(
   114  		func() {
   115  			_ = (*[9]byte)(s)
   116  		},
   117  		"runtime error: cannot convert slice with length 8 to pointer to array with length 9",
   118  	)
   119  
   120  	var n []byte
   121  	if p := (*[0]byte)(n); p != nil {
   122  		panic("nil slice converted to *[0]byte should be nil")
   123  	}
   124  
   125  	z := make([]byte, 0)
   126  	if p := (*[0]byte)(z); p == nil {
   127  		panic("empty slice converted to *[0]byte should be non-nil")
   128  	}
   129  
   130  	// Test with named types
   131  	type Slice []int
   132  	type Int4 [4]int
   133  	type PInt4 *[4]int
   134  	ii := make(Slice, 4)
   135  	if p := (*Int4)(ii); &p[0] != &ii[0] {
   136  		panic("*Int4 conversion failed")
   137  	}
   138  	if p := PInt4(ii); &p[0] != &ii[0] {
   139  		panic("PInt4 conversion failed")
   140  	}
   141  }
   142  
   143  // test static variable conversion
   144  
   145  var (
   146  	ss  = make([]string, 10)
   147  	s5  = (*[5]string)(ss)
   148  	s10 = (*[10]string)(ss)
   149  
   150  	ns  []string
   151  	ns0 = (*[0]string)(ns)
   152  
   153  	zs  = make([]string, 0)
   154  	zs0 = (*[0]string)(zs)
   155  )
   156  
   157  func init() {
   158  	if &ss[0] != &s5[0] {
   159  		panic("s5 conversion failed")
   160  	}
   161  	if &ss[0] != &s10[0] {
   162  		panic("s5 conversion failed")
   163  	}
   164  	if ns0 != nil {
   165  		panic("ns0 should be nil")
   166  	}
   167  	if zs0 == nil {
   168  		panic("zs0 should not be nil")
   169  	}
   170  }
   171  `
   172  	_, err := gossa.RunFile("main.go", src, nil, 0)
   173  	if err != nil {
   174  		t.Fatal(err)
   175  	}
   176  }