| // Copyright 2019 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 runtime | |
| import "unsafe" | |
| type ptrAlign struct { | |
| ptr unsafe.Pointer | |
| elem *_type | |
| } | |
| func checkptrAlignment(p unsafe.Pointer, elem *_type) { | |
| // Check that (*T)(p) is appropriately aligned. | |
| // TODO(mdempsky): What about fieldAlign? | |
| if uintptr(p)&(uintptr(elem.align)-1) != 0 { | |
| panic(ptrAlign{p, elem}) | |
| } | |
| // Check that (*T)(p) doesn't straddle multiple heap objects. | |
| if elem.size != 1 && checkptrBase(p) != checkptrBase(add(p, elem.size-1)) { | |
| panic(ptrAlign{p, elem}) | |
| } | |
| } | |
| type ptrArith struct { | |
| ptr unsafe.Pointer | |
| originals []unsafe.Pointer | |
| } | |
| func checkptrArithmetic(p unsafe.Pointer, originals []unsafe.Pointer) { | |
| if 0 < uintptr(p) && uintptr(p) < minLegalPointer { | |
| panic(ptrArith{p, originals}) | |
| } | |
| base := checkptrBase(p) | |
| if base == 0 { | |
| return | |
| } | |
| for _, original := range originals { | |
| if base == checkptrBase(original) { | |
| return | |
| } | |
| } | |
| panic(ptrArith{p, originals}) | |
| } | |
| func checkptrBase(p unsafe.Pointer) uintptr { | |
| base, _, _ := findObject(uintptr(p), 0, 0) | |
| // TODO(mdempsky): If base == 0, then check if p points to the | |
| // stack or a global variable. | |
| return base | |
| } |