unsafe: allow unsafe.Slice up to end of address space

Allow the user to construct slices that are larger than the Go heap as
long as they don't overflow the address space.

Updates #48798.

Change-Id: I659c8334d04676e1f253b9c3cd499eab9b9f989a
Reviewed-on: https://go-review.googlesource.com/c/go/+/355489
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/src/runtime/slice.go b/src/runtime/slice.go
index cfa862e..66bb7d9 100644
--- a/src/runtime/slice.go
+++ b/src/runtime/slice.go
@@ -124,7 +124,7 @@
 	}
 
 	mem, overflow := math.MulUintptr(et.size, uintptr(len))
-	if overflow || mem > maxAlloc || len < 0 {
+	if overflow || mem > -uintptr(ptr) || len < 0 {
 		panicunsafeslicelen()
 	}
 }
diff --git a/test/unsafebuiltins.go b/test/unsafebuiltins.go
index 4c940aa..d04bcbd 100644
--- a/test/unsafebuiltins.go
+++ b/test/unsafebuiltins.go
@@ -47,6 +47,11 @@
 		// size overflows address space
 		mustPanic(func() { _ = unsafe.Slice(new(uint64), maxUintptr/8) })
 		mustPanic(func() { _ = unsafe.Slice(new(uint64), maxUintptr/8+1) })
+
+		// sliced memory overflows address space
+		last := (*byte)(unsafe.Pointer(^uintptr(0)))
+		_ = unsafe.Slice(last, 1)
+		mustPanic(func() { _ = unsafe.Slice(last, 2) })
 	}
 }