go issue15329 源码

  • 2022-07-15
  • 浏览 (840)

golang issue15329 代码

文件路径:/test/fixedbugs/issue15329.go

// run

// Copyright 2016 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.

// Previously, cmd/compile would rewrite
//
//     check(unsafe.Pointer(testMeth(1).Pointer()), unsafe.Pointer(testMeth(2).Pointer()))
//
// to
//
//     var autotmp_1 uintptr = testMeth(1).Pointer()
//     var autotmp_2 uintptr = testMeth(2).Pointer()
//     check(unsafe.Pointer(autotmp_1), unsafe.Pointer(autotmp_2))
//
// However, that means autotmp_1 is the only reference to the int
// variable containing the value "1", but it's not a pointer type,
// so it was at risk of being garbage collected by the evaluation of
// testMeth(2).Pointer(), even though package unsafe's documentation
// says the original code was allowed.
//
// Now cmd/compile rewrites it to
//
//     var autotmp_1 unsafe.Pointer = unsafe.Pointer(testMeth(1).Pointer())
//     var autotmp_2 unsafe.Pointer = unsafe.Pointer(testMeth(2).Pointer())
//     check(autotmp_1, autotmp_2)
//
// to ensure the pointed-to variables are visible to the GC.

package main

import (
	"fmt"
	"reflect"
	"runtime"
	"unsafe"
)

func main() {
	// Test all the different ways we can invoke reflect.Value.Pointer.

	// Direct method invocation.
	check(unsafe.Pointer(testMeth(1).Pointer()), unsafe.Pointer(testMeth(2).Pointer()))

	// Invocation via method expression.
	check(unsafe.Pointer(reflect.Value.Pointer(testMeth(1))), unsafe.Pointer(reflect.Value.Pointer(testMeth(2))))

	// Invocation via interface.
	check(unsafe.Pointer(testInter(1).Pointer()), unsafe.Pointer(testInter(2).Pointer()))

	// Invocation via method value.
	check(unsafe.Pointer(testFunc(1)()), unsafe.Pointer(testFunc(2)()))
}

func check(p, q unsafe.Pointer) {
	a, b := *(*int)(p), *(*int)(q)
	if a != 1 || b != 2 {
		fmt.Printf("got %v, %v; expected 1, 2\n", a, b)
	}
}

func testMeth(x int) reflect.Value {
	// Force GC to run.
	runtime.GC()
	return reflect.ValueOf(&x)
}

type Pointerer interface {
	Pointer() uintptr
}

func testInter(x int) Pointerer {
	return testMeth(x)
}

func testFunc(x int) func() uintptr {
	return testMeth(x).Pointer
}

相关信息

go 源码目录

相关文章

go bug000 源码

go bug002 源码

go bug003 源码

go bug004 源码

go bug005 源码

go bug006 源码

go bug007 源码

go bug008 源码

go bug009 源码

go bug010 源码

0  赞