Skip to content

Commit

Permalink
runtime: don't report a pointer alignment error for pointer-free base…
Browse files Browse the repository at this point in the history
… type

Fixes #37298

Change-Id: I8ba9c8b106e16cea7dd25473c7390b0f2ba9a1a5
Reviewed-on: https://go-review.googlesource.com/c/go/+/223781
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
  • Loading branch information
randall77 committed Mar 17, 2020
1 parent 14d20dc commit f4ddc00
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 4 deletions.
4 changes: 3 additions & 1 deletion src/runtime/checkptr.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import "unsafe"

func checkptrAlignment(p unsafe.Pointer, elem *_type, n uintptr) {
// Check that (*[n]elem)(p) is appropriately aligned.
// Note that we allow unaligned pointers if the types they point to contain
// no pointers themselves. See issue 37298.
// TODO(mdempsky): What about fieldAlign?
if uintptr(p)&(uintptr(elem.align)-1) != 0 {
if elem.ptrdata != 0 && uintptr(p)&(uintptr(elem.align)-1) != 0 {
throw("checkptr: misaligned pointer conversion")
}

Expand Down
9 changes: 8 additions & 1 deletion src/runtime/checkptr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ func TestCheckPtr(t *testing.T) {
cmd string
want string
}{
{"CheckPtrAlignment", "fatal error: checkptr: misaligned pointer conversion\n"},
{"CheckPtrAlignmentPtr", "fatal error: checkptr: misaligned pointer conversion\n"},
{"CheckPtrAlignmentNoPtr", ""},
{"CheckPtrArithmetic", "fatal error: checkptr: pointer arithmetic result points to invalid allocation\n"},
{"CheckPtrSize", "fatal error: checkptr: converted pointer straddles multiple allocations\n"},
{"CheckPtrSmall", "fatal error: checkptr: pointer arithmetic computed bad pointer value\n"},
Expand All @@ -38,6 +39,12 @@ func TestCheckPtr(t *testing.T) {
if err != nil {
t.Log(err)
}
if tc.want == "" {
if len(got) > 0 {
t.Errorf("output:\n%s\nwant no output", got)
}
return
}
if !strings.HasPrefix(string(got), tc.want) {
t.Errorf("output:\n%s\n\nwant output starting with: %s", got, tc.want)
}
Expand Down
11 changes: 9 additions & 2 deletions src/runtime/testdata/testprog/checkptr.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,25 @@ package main
import "unsafe"

func init() {
register("CheckPtrAlignment", CheckPtrAlignment)
register("CheckPtrAlignmentNoPtr", CheckPtrAlignmentNoPtr)
register("CheckPtrAlignmentPtr", CheckPtrAlignmentPtr)
register("CheckPtrArithmetic", CheckPtrArithmetic)
register("CheckPtrSize", CheckPtrSize)
register("CheckPtrSmall", CheckPtrSmall)
}

func CheckPtrAlignment() {
func CheckPtrAlignmentNoPtr() {
var x [2]int64
p := unsafe.Pointer(&x[0])
sink2 = (*int64)(unsafe.Pointer(uintptr(p) + 1))
}

func CheckPtrAlignmentPtr() {
var x [2]int64
p := unsafe.Pointer(&x[0])
sink2 = (**int64)(unsafe.Pointer(uintptr(p) + 1))
}

func CheckPtrArithmetic() {
var x int
i := uintptr(unsafe.Pointer(&x))
Expand Down

0 comments on commit f4ddc00

Please sign in to comment.