0
1
mirror of https://github.com/golang/go synced 2025-04-12 00:29:42 +00:00
Files
.github
api
doc
lib
misc
src
test
abi
alias3.dir
asmhdr.dir
bench
chan
closure3.dir
closure5.dir
codegen
ddd2.dir
dwarf
fixedbugs
import2.dir
import4.dir
interface
intrinsic.dir
ken
linkname.dir
method4.dir
retjmp.dir
runtime
stress
syntax
typeparam
uintptrescapes.dir
235.go
64bit.go
README.md
alg.go
alias.go
alias1.go
alias2.go
alias3.go
align.go
append.go
append1.go
args.go
armimm.go
asmhdr.go
assign.go
assign1.go
atomicload.go
bigalg.go
bigmap.go
blank.go
blank1.go
bom.go
bombad.go
bounds.go
cannotassign.go
chancap.go
chanlinear.go
char_lit.go
char_lit1.go
checkbce.go
clearfat.go
closedchan.go
closure.go
closure1.go
closure2.go
closure3.go
closure4.go
closure5.go
closure6.go
closure7.go
cmp.go
cmp6.go
cmplx.go
cmplxdivide.c
cmplxdivide.go
cmplxdivide1.go
complit.go
complit1.go
compos.go
const.go
const1.go
const2.go
const3.go
const4.go
const5.go
const6.go
const7.go
const8.go
convT2X.go
convert.go
convert1.go
convert2.go
convert3.go
convert4.go
convinline.go
convlit.go
convlit1.go
copy.go
copy1.go
crlf.go
ddd.go
ddd1.go
ddd2.go
decl.go
declbad.go
defer.go
defererrcheck.go
deferfin.go
defernil.go
deferprint.go
deferprint.out
devirt.go
directive.go
directive2.go
divide.go
divmod.go
embedfunc.go
embedvers.go
empty.go
env.go
eof.go
eof1.go
escape.go
escape2.go
escape2n.go
escape3.go
escape4.go
escape5.go
escape_array.go
escape_calls.go
escape_closure.go
escape_field.go
escape_goto.go
escape_hash_maphash.go
escape_iface.go
escape_iface_nounified.go
escape_iface_unified.go
escape_indir.go
escape_level.go
escape_map.go
escape_param.go
escape_runtime_atomic.go
escape_selfassign.go
escape_slice.go
escape_struct_param1.go
escape_struct_param2.go
escape_struct_return.go
escape_sync_atomic.go
escape_unsafe.go
fibo.go
finprofiled.go
float_lit.go
float_lit2.go
float_lit3.go
floatcmp.go
for.go
func.go
func1.go
func2.go
func3.go
func4.go
func5.go
func6.go
func7.go
func8.go
funcdup.go
funcdup2.go
fuse.go
gc.go
gc1.go
gc2.go
gcgort.go
gcstring.go
goprint.go
goprint.out
goto.go
heapsampling.go
helloworld.go
helloworld.out
if.go
import.go
import1.go
import2.go
import4.go
import5.go
import6.go
index.go
index0.go
index1.go
index2.go
indirect.go
indirect1.go
init.go
init1.go
initcomma.go
initexp.go
initialize.go
initializerr.go
initloop.go
inline.go
inline_big.go
inline_caller.go
inline_callers.go
inline_endian.go
inline_literal.go
inline_math_bits_rotate.go
inline_nounified.go
inline_sync.go
inline_unified.go
inline_variadic.go
int_lit.go
intcvt.go
intrinsic.go
intrinsic_atomic.go
iota.go
label.go
label1.go
linkmain.go
linkmain_run.go
linkname.go
linkname3.go
linkobj.go
linkx.go
linkx_run.go
literal.go
literal2.go
live.go
live1.go
live2.go
live_regabi.go
live_uintptrkeepalive.go
loopbce.go
mainsig.go
makechan.go
makemap.go
makenew.go
makeslice.go
mallocfin.go
map.go
map1.go
mapclear.go
maplinear.go
maymorestack.go
mergemul.go
method.go
method1.go
method2.go
method3.go
method4.go
method5.go
method6.go
method7.go
named.go
named1.go
nil.go
nilcheck.go
nilptr.go
nilptr2.go
nilptr3.go
nilptr4.go
nilptr5.go
nilptr5_aix.go
nilptr5_wasm.go
nilptr_aix.go
noinit.go
nosplit.go
nowritebarrier.go
nul1.go
opt_branchlikely.go
parentype.go
peano.go
phiopt.go
print.go
print.out
printbig.go
printbig.out
prove.go
prove_constant_folding.go
range.go
recover.go
recover1.go
recover2.go
recover3.go
recover4.go
recover5.go
reflectmethod1.go
reflectmethod2.go
reflectmethod3.go
reflectmethod4.go
reflectmethod5.go
reflectmethod6.go
reflectmethod7.go
reflectmethod8.go
rename.go
rename1.go
reorder.go
reorder2.go
retjmp.go
return.go
rotate.go
rotate0.go
rotate1.go
rotate2.go
rotate3.go
run.go
rune.go
runtime.go
shift1.go
shift2.go
shift3.go
sieve.go
sigchld.go
sigchld.out
simassign.go
sizeof.go
slice3.go
slice3err.go
slicecap.go
sliceopt.go
solitaire.go
stack.go
stackobj.go
stackobj2.go
stackobj3.go
strcopy.go
strength.go
string_lit.go
stringrange.go
struct0.go
switch.go
switch2.go
switch3.go
switch4.go
switch5.go
switch6.go
switch7.go
tinyfin.go
torture.go
turing.go
typecheck.go
typecheckloop.go
typeswitch.go
typeswitch1.go
typeswitch2.go
typeswitch2b.go
typeswitch3.go
uintptrescapes.go
uintptrescapes2.go
uintptrescapes3.go
uintptrkeepalive.go
undef.go
unsafe_slice_data.go
unsafe_string.go
unsafe_string_data.go
unsafebuiltins.go
used.go
utf.go
varerr.go
varinit.go
winbatch.go
writebarrier.go
zerodivide.go
.gitattributes
.gitignore
CONTRIBUTING.md
LICENSE
PATENTS
README.md
SECURITY.md
VERSION
codereview.cfg
go/test/unsafebuiltins.go
cuiweixie c708532936 cmd/compile: add support for unsafe.{String,StringData,SliceData}
For 

Change-Id: I13a761daca8b433b271a1feb711c103d9820772d
Reviewed-on: https://go-review.googlesource.com/c/go/+/423774
Reviewed-by: Heschi Kreinick <heschi@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: hopehook <hopehook@golangcn.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2022-08-31 17:15:15 +00:00

108 lines
2.3 KiB
Go

// run
// Copyright 2021 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
import (
"math"
"unsafe"
)
const maxUintptr = 1 << (8 * unsafe.Sizeof(uintptr(0)))
func main() {
var p [10]byte
// unsafe.Add
{
p1 := unsafe.Pointer(&p[1])
assert(unsafe.Add(p1, 1) == unsafe.Pointer(&p[2]))
assert(unsafe.Add(p1, -1) == unsafe.Pointer(&p[0]))
}
// unsafe.Slice
{
s := unsafe.Slice(&p[0], len(p))
assert(&s[0] == &p[0])
assert(len(s) == len(p))
assert(cap(s) == len(p))
// nil pointer with zero length returns nil
assert(unsafe.Slice((*int)(nil), 0) == nil)
// nil pointer with positive length panics
mustPanic(func() { _ = unsafe.Slice((*int)(nil), 1) })
// negative length
var neg int = -1
mustPanic(func() { _ = unsafe.Slice(new(byte), neg) })
// length too large
var tooBig uint64 = math.MaxUint64
mustPanic(func() { _ = unsafe.Slice(new(byte), tooBig) })
// size overflows address space
mustPanic(func() { _ = unsafe.Slice(new(uint64), maxUintptr/8) })
mustPanic(func() { _ = unsafe.Slice(new(uint64), maxUintptr/8+1) })
// sliced memory overflows address space
last := (*byte)(unsafe.Pointer(^uintptr(0)))
_ = unsafe.Slice(last, 1)
mustPanic(func() { _ = unsafe.Slice(last, 2) })
}
// unsafe.String
{
s := unsafe.String(&p[0], len(p))
assert(s == string(p[:]))
assert(len(s) == len(p))
// the empty string
assert(unsafe.String(nil, 0) == "")
// nil pointer with positive length panics
mustPanic(func() { _ = unsafe.String(nil, 1) })
// negative length
var neg int = -1
mustPanic(func() { _ = unsafe.String(new(byte), neg) })
// length too large
var tooBig uint64 = math.MaxUint64
mustPanic(func() { _ = unsafe.String(new(byte), tooBig) })
// string memory overflows address space
last := (*byte)(unsafe.Pointer(^uintptr(0)))
_ = unsafe.String(last, 1)
mustPanic(func() { _ = unsafe.String(last, 2) })
}
// unsafe.StringData
{
var s = "string"
assert(string(unsafe.Slice(unsafe.StringData(s), len(s))) == s)
}
//unsafe.SliceData
{
var s = []byte("slice")
assert(unsafe.String(unsafe.SliceData(s), len(s)) == string(s))
}
}
func assert(ok bool) {
if !ok {
panic("FAIL")
}
}
func mustPanic(f func()) {
defer func() {
assert(recover() != nil)
}()
f()
}