Skip to content

Commit 90df377

Browse files
cmd/cgo: rewrite pointer checking to use more function literals
Fixes #14210 Fixes #25941 Change-Id: Idde2d032290da3edb742b5b4f6ffeb625f05b494 Reviewed-on: https://go-review.googlesource.com/c/142884 Reviewed-by: Brad Fitzpatrick <[email protected]>
1 parent 02aa1ae commit 90df377

File tree

3 files changed

+248
-98
lines changed

3 files changed

+248
-98
lines changed

misc/cgo/errors/ptr_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,55 @@ var ptrTests = []ptrTest{
357357
body: `r, _, _ := os.Pipe(); r.SetDeadline(time.Now().Add(C.US * time.Microsecond))`,
358358
fail: false,
359359
},
360+
{
361+
// Test for double evaluation of channel receive.
362+
name: "chan-recv",
363+
c: `void f(char** p) {}`,
364+
imports: []string{"time"},
365+
body: `c := make(chan []*C.char, 2); c <- make([]*C.char, 1); go func() { time.Sleep(10 * time.Second); panic("received twice from chan") }(); C.f(&(<-c)[0]);`,
366+
fail: false,
367+
},
368+
{
369+
// Test that converting the address of a struct field
370+
// to unsafe.Pointer still just checks that field.
371+
// Issue #25941.
372+
name: "struct-field",
373+
c: `void f(void* p) {}`,
374+
imports: []string{"unsafe"},
375+
support: `type S struct { p *int; a [8]byte; u uintptr }`,
376+
body: `s := &S{p: new(int)}; C.f(unsafe.Pointer(&s.a))`,
377+
fail: false,
378+
},
379+
{
380+
// Test that converting multiple struct field
381+
// addresses to unsafe.Pointer still just checks those
382+
// fields. Issue #25941.
383+
name: "struct-field-2",
384+
c: `void f(void* p, int r, void* s) {}`,
385+
imports: []string{"unsafe"},
386+
support: `type S struct { a [8]byte; p *int; b int64; }`,
387+
body: `s := &S{p: new(int)}; C.f(unsafe.Pointer(&s.a), 32, unsafe.Pointer(&s.b))`,
388+
fail: false,
389+
},
390+
{
391+
// Test that second argument to cgoCheckPointer is
392+
// evaluated when a deferred function is deferred, not
393+
// when it is run.
394+
name: "defer2",
395+
c: `void f(char **pc) {}`,
396+
support: `type S1 struct { s []*C.char }; type S2 struct { ps *S1 }`,
397+
body: `p := &S2{&S1{[]*C.char{nil}}}; defer C.f(&p.ps.s[0]); p.ps = nil`,
398+
fail: false,
399+
},
400+
{
401+
// Test that indexing into a function call still
402+
// examines only the slice being indexed.
403+
name: "buffer",
404+
c: `void f(void *p) {}`,
405+
imports: []string{"bytes", "unsafe"},
406+
body: `var b bytes.Buffer; b.WriteString("a"); C.f(unsafe.Pointer(&b.Bytes()[0]))`,
407+
fail: false,
408+
},
360409
}
361410

362411
func TestPointerChecks(t *testing.T) {

0 commit comments

Comments
 (0)