From 229247d33b717ce7729e43a8fde3a095e376cf3d Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Tue, 17 Mar 2020 13:27:11 -0700 Subject: [PATCH] [release-branch.go1.14] runtime: don't report a pointer alignment error for pointer-free base type Fixes #37905 Change-Id: I8ba9c8b106e16cea7dd25473c7390b0f2ba9a1a5 Reviewed-on: https://go-review.googlesource.com/c/go/+/223781 Run-TryBot: Keith Randall Reviewed-by: Ian Lance Taylor Reviewed-by: Matthew Dempsky TryBot-Result: Gobot Gobot Reviewed-on: https://go-review.googlesource.com/c/go/+/223749 --- src/runtime/checkptr.go | 4 +++- src/runtime/checkptr_test.go | 9 ++++++++- src/runtime/testdata/testprog/checkptr.go | 11 +++++++++-- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/runtime/checkptr.go b/src/runtime/checkptr.go index ddbc8168af..b6f2bc81bb 100644 --- a/src/runtime/checkptr.go +++ b/src/runtime/checkptr.go @@ -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: unsafe pointer conversion") } diff --git a/src/runtime/checkptr_test.go b/src/runtime/checkptr_test.go index c5f22cc101..624f1b62d2 100644 --- a/src/runtime/checkptr_test.go +++ b/src/runtime/checkptr_test.go @@ -24,7 +24,8 @@ func TestCheckPtr(t *testing.T) { cmd string want string }{ - {"CheckPtrAlignment", "fatal error: checkptr: unsafe pointer conversion\n"}, + {"CheckPtrAlignmentPtr", "fatal error: checkptr: unsafe pointer conversion\n"}, + {"CheckPtrAlignmentNoPtr", ""}, {"CheckPtrArithmetic", "fatal error: checkptr: unsafe pointer arithmetic\n"}, {"CheckPtrSize", "fatal error: checkptr: unsafe pointer conversion\n"}, {"CheckPtrSmall", "fatal error: checkptr: unsafe pointer arithmetic\n"}, @@ -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) } diff --git a/src/runtime/testdata/testprog/checkptr.go b/src/runtime/testdata/testprog/checkptr.go index 177db38e5a..45e6fb1aa5 100644 --- a/src/runtime/testdata/testprog/checkptr.go +++ b/src/runtime/testdata/testprog/checkptr.go @@ -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)) -- 2.48.1