blob: dbe37b6d0e732c69bb16910f647b0f8f0ad17f59 [file] [log] [blame]
// Copyright 2020 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 main
// This is for issue #63739.
// Ensure that parameters are kept alive until the end of the C call. If not,
// then a stack copy at just the right time while calling into C might think
// that any stack pointers are not alive and fail to update them, causing the C
// function to see the old, no longer correct, pointer values.
/*
int add_from_multiple_pointers(int *a, int *b, int *c) {
*a = *a + 1;
*b = *b + 1;
*c = *c + 1;
return *a + *b + *c;
}
#cgo noescape add_from_multiple_pointers
#cgo nocallback add_from_multiple_pointers
*/
import "C"
import (
"fmt"
)
const (
maxStack = 1024
)
func init() {
register("CgoEscapeWithMultiplePointers", CgoEscapeWithMultiplePointers)
}
func CgoEscapeWithMultiplePointers() {
stackGrow(maxStack)
fmt.Println("OK")
}
//go:noinline
func testCWithMultiplePointers() {
var a C.int = 1
var b C.int = 2
var c C.int = 3
v := C.add_from_multiple_pointers(&a, &b, &c)
if v != 9 || a != 2 || b != 3 || c != 4 {
fmt.Printf("%d + %d + %d != %d\n", a, b, c, v)
}
}
func stackGrow(n int) {
if n == 0 {
return
}
testCWithMultiplePointers()
stackGrow(n - 1)
}