]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: support cgo index into pointer-to-array
authorIan Lance Taylor <iant@golang.org>
Thu, 24 Oct 2024 00:27:44 +0000 (17:27 -0700)
committerGopher Robot <gobot@golang.org>
Thu, 24 Oct 2024 14:34:01 +0000 (14:34 +0000)
We were missing a case for calling a C function with an index
into a pointer-to-array.

Fixes #70016

Change-Id: I9c74d629e58722813c1aaa0f0dc225a5a64d111b
Reviewed-on: https://go-review.googlesource.com/c/go/+/621576
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/cgo/internal/testerrors/ptr_test.go
src/runtime/cgocall.go

index 4f8a0ee583a7873d77b61b2036b78a96e55050c9..9a8187f55f20f18827b6c6c0a48d694e219ac9dc 100644 (file)
@@ -472,6 +472,23 @@ var ptrTests = []ptrTest{
                body:    `s := struct { a [4]byte; p *int }{p: new(int)}; C.f43(unsafe.Pointer(unsafe.SliceData(s.a[:])))`,
                fail:    false,
        },
+       {
+               // Passing the address of an element of a pointer-to-array.
+               name:    "arraypointer",
+               c:       `void f44(void* p) {}`,
+               imports: []string{"unsafe"},
+               body:    `a := new([10]byte); C.f44(unsafe.Pointer(&a[0]))`,
+               fail:    false,
+       },
+       {
+               // Passing the address of an element of a pointer-to-array
+               // that contains a Go pointer.
+               name:    "arraypointer2",
+               c:       `void f45(void** p) {}`,
+               imports: []string{"unsafe"},
+               body:    `i := 0; a := &[2]unsafe.Pointer{nil, unsafe.Pointer(&i)}; C.f45(&a[0])`,
+               fail:    true,
+       },
 }
 
 func TestPointerChecks(t *testing.T) {
index 54ce0e8dfca470f0f8c4b7c2240b114826434524..18a100411823569ce95e1b4566be4479ae4d83c3 100644 (file)
@@ -563,6 +563,17 @@ func cgoCheckPointer(ptr any, arg any) {
                        ep = aep
                        t = ep._type
                        top = false
+               case abi.Pointer:
+                       // The Go code is indexing into a pointer to an array,
+                       // and we have been passed the pointer-to-array.
+                       // Check the array rather than the pointer.
+                       pt := (*abi.PtrType)(unsafe.Pointer(aep._type))
+                       t = pt.Elem
+                       if t.Kind_&abi.KindMask != abi.Array {
+                               throw("can't happen")
+                       }
+                       ep = aep
+                       top = false
                default:
                        throw("can't happen")
                }