Source file src/runtime/testdata/testprogcgo/issue63739.go

     1  // Copyright 2020 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package main
     6  
     7  // This is for issue #63739.
     8  // Ensure that parameters are kept alive until the end of the C call. If not,
     9  // then a stack copy at just the right time while calling into C might think
    10  // that any stack pointers are not alive and fail to update them, causing the C
    11  // function to see the old, no longer correct, pointer values.
    12  
    13  /*
    14  int add_from_multiple_pointers(int *a, int *b, int *c) {
    15  	*a = *a + 1;
    16  	*b = *b + 1;
    17  	*c = *c + 1;
    18  	return *a + *b + *c;
    19  }
    20  #cgo noescape add_from_multiple_pointers
    21  #cgo nocallback add_from_multiple_pointers
    22  */
    23  import "C"
    24  
    25  import (
    26  	"fmt"
    27  )
    28  
    29  const (
    30  	maxStack = 1024
    31  )
    32  
    33  func init() {
    34  	register("CgoEscapeWithMultiplePointers", CgoEscapeWithMultiplePointers)
    35  }
    36  
    37  func CgoEscapeWithMultiplePointers() {
    38  	stackGrow(maxStack)
    39  	fmt.Println("OK")
    40  }
    41  
    42  //go:noinline
    43  func testCWithMultiplePointers() {
    44  	var a C.int = 1
    45  	var b C.int = 2
    46  	var c C.int = 3
    47  	v := C.add_from_multiple_pointers(&a, &b, &c)
    48  	if v != 9 || a != 2 || b != 3 || c != 4 {
    49  		fmt.Printf("%d + %d + %d != %d\n", a, b, c, v)
    50  	}
    51  }
    52  
    53  func stackGrow(n int) {
    54  	if n == 0 {
    55  		return
    56  	}
    57  	testCWithMultiplePointers()
    58  	stackGrow(n - 1)
    59  }
    60  

View as plain text