aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitriy Vyukov <dvyukov@google.com>2011-10-17 15:14:07 -0400
committerRuss Cox <rsc@golang.org>2011-10-17 15:14:07 -0400
commitb0c674b65d4e90684d8481b8004e12f1374ad23e (patch)
treec5681d50dce3e5438077925a80ff5570873e00bd
parentbdf66114c7ad02b41b83522d7e9073cf0957d836 (diff)
downloadgo-b0c674b65d4e90684d8481b8004e12f1374ad23e.tar.gz
go-b0c674b65d4e90684d8481b8004e12f1374ad23e.zip
gc: treat uintptr as potentially containing a pointer
Fixes #2376 R=golang-dev, lvd, rsc CC=golang-dev https://golang.org/cl/5278048
-rw-r--r--src/cmd/gc/reflect.c2
-rw-r--r--src/pkg/runtime/gc_test.go71
2 files changed, 72 insertions, 1 deletions
diff --git a/src/cmd/gc/reflect.c b/src/cmd/gc/reflect.c
index ca7d08e511..4ce1695792 100644
--- a/src/cmd/gc/reflect.c
+++ b/src/cmd/gc/reflect.c
@@ -516,7 +516,6 @@ haspointers(Type *t)
case TUINT32:
case TINT64:
case TUINT64:
- case TUINTPTR:
case TFLOAT32:
case TFLOAT64:
case TBOOL:
@@ -534,6 +533,7 @@ haspointers(Type *t)
case TPTR32:
case TPTR64:
case TUNSAFEPTR:
+ case TUINTPTR:
case TINTER:
case TCHAN:
case TMAP:
diff --git a/src/pkg/runtime/gc_test.go b/src/pkg/runtime/gc_test.go
index fad60a3680..c299ba20e7 100644
--- a/src/pkg/runtime/gc_test.go
+++ b/src/pkg/runtime/gc_test.go
@@ -3,6 +3,7 @@ package runtime_test
import (
"runtime"
"testing"
+ "unsafe"
)
func TestGcSys(t *testing.T) {
@@ -22,3 +23,73 @@ func TestGcSys(t *testing.T) {
func workthegc() []byte {
return make([]byte, 1029)
}
+
+func TestGcUintptr(t *testing.T) {
+ p1 := unsafe.Pointer(new(int))
+ *(*int)(unsafe.Pointer(p1)) = 42
+ p2 := uintptr(unsafe.Pointer(new(int)))
+ *(*int)(unsafe.Pointer(p2)) = 42
+ var a1 [1]unsafe.Pointer
+ a1[0] = unsafe.Pointer(new(int))
+ *(*int)(unsafe.Pointer(a1[0])) = 42
+ var a2 [1]uintptr
+ a2[0] = uintptr(unsafe.Pointer(new(int)))
+ *(*int)(unsafe.Pointer(a2[0])) = 42
+ s1 := make([]unsafe.Pointer, 1)
+ s1[0] = unsafe.Pointer(new(int))
+ *(*int)(unsafe.Pointer(s1[0])) = 42
+ s2 := make([]uintptr, 1)
+ s2[0] = uintptr(unsafe.Pointer(new(int)))
+ *(*int)(unsafe.Pointer(s2[0])) = 42
+ m1 := make(map[int]unsafe.Pointer)
+ m1[0] = unsafe.Pointer(new(int))
+ *(*int)(unsafe.Pointer(m1[0])) = 42
+ m2 := make(map[int]uintptr)
+ m2[0] = uintptr(unsafe.Pointer(new(int)))
+ *(*int)(unsafe.Pointer(m2[0])) = 42
+ c1 := make(chan unsafe.Pointer, 1)
+ func() {
+ p := new(int)
+ *p = 42
+ c1 <- unsafe.Pointer(p)
+ }()
+ c2 := make(chan uintptr, 1)
+ func() {
+ p := new(int)
+ *p = 42
+ c2 <- uintptr(unsafe.Pointer(p))
+ }()
+
+ runtime.GC()
+
+ if p, _ := runtime.Lookup((*byte)(unsafe.Pointer(p1))); p == nil || *(*int)(unsafe.Pointer(p)) != 42 {
+ t.Fatalf("p1 is freed")
+ }
+ if p, _ := runtime.Lookup((*byte)(unsafe.Pointer(p2))); p == nil || *(*int)(unsafe.Pointer(p)) != 42 {
+ t.Fatalf("p2 is freed")
+ }
+ if p, _ := runtime.Lookup((*byte)(unsafe.Pointer(a1[0]))); p == nil || *(*int)(unsafe.Pointer(p)) != 42 {
+ t.Fatalf("a1[0] is freed")
+ }
+ if p, _ := runtime.Lookup((*byte)(unsafe.Pointer(a2[0]))); p == nil || *(*int)(unsafe.Pointer(p)) != 42 {
+ t.Fatalf("a2[0] is freed")
+ }
+ if p, _ := runtime.Lookup((*byte)(unsafe.Pointer(s1[0]))); p == nil || *(*int)(unsafe.Pointer(p)) != 42 {
+ t.Fatalf("s1[0] is freed")
+ }
+ if p, _ := runtime.Lookup((*byte)(unsafe.Pointer(s2[0]))); p == nil || *(*int)(unsafe.Pointer(p)) != 42 {
+ t.Fatalf("s2[0] is freed")
+ }
+ if p, _ := runtime.Lookup((*byte)(unsafe.Pointer(m1[0]))); p == nil || *(*int)(unsafe.Pointer(p)) != 42 {
+ t.Fatalf("m1[0] is freed")
+ }
+ if p, _ := runtime.Lookup((*byte)(unsafe.Pointer(m2[0]))); p == nil || *(*int)(unsafe.Pointer(p)) != 42 {
+ t.Fatalf("m2[0] is freed")
+ }
+ if p, _ := runtime.Lookup((*byte)(unsafe.Pointer(<-c1))); p == nil || *(*int)(unsafe.Pointer(p)) != 42 {
+ t.Fatalf("<-c1 is freed")
+ }
+ if p, _ := runtime.Lookup((*byte)(unsafe.Pointer(<-c2))); p == nil || *(*int)(unsafe.Pointer(p)) != 42 {
+ t.Fatalf("<-c2 is freed")
+ }
+}