Skip to content

Commit 0c7762c

Browse files
committed
cmd/compile: assume unsafe pointer arithmetic generates non-nil results
I've never seen a case where unsafe arithmetic is used to generate a nil. (Something like var x uintptr; unsafe.Pointer(x - x).) We can assume that if someone is doing arithmetic with pointers, the result will be non-nil. Our unsafe rules already forbid this, although we should be more explicit. RELNOTE=It is invalid to convert a nil unsafe.Pointer to uintptr and back, with arithmetic. (This was already invalid, but this statement has been added for clarification.) Fixes #27180 Change-Id: I1880b7725a9fd99e4613799930fdad9aaa99e8f0 Reviewed-on: https://go-review.googlesource.com/c/146058 Reviewed-by: Austin Clements <[email protected]>
1 parent a063a22 commit 0c7762c

File tree

2 files changed

+8
-1
lines changed

2 files changed

+8
-1
lines changed

src/cmd/compile/internal/ssa/nilcheck.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ func nilcheckelim(f *Func) {
4747
// a value resulting from taking the address of a
4848
// value, or a value constructed from an offset of a
4949
// non-nil ptr (OpAddPtr) implies it is non-nil
50-
if v.Op == OpAddr || v.Op == OpLocalAddr || v.Op == OpAddPtr || v.Op == OpOffPtr {
50+
// We also assume unsafe pointer arithmetic generates non-nil pointers. See #27180.
51+
if v.Op == OpAddr || v.Op == OpLocalAddr || v.Op == OpAddPtr || v.Op == OpOffPtr || v.Op == OpAdd32 || v.Op == OpAdd64 || v.Op == OpSub32 || v.Op == OpSub64 {
5152
nonNilValues[v.ID] = true
5253
}
5354
}

src/unsafe/unsafe.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,12 @@ type ArbitraryType int
9999
// u := uintptr(p)
100100
// p = unsafe.Pointer(u + offset)
101101
//
102+
// Note that the pointer must point into an allocated object, so it may not be nil.
103+
//
104+
// // INVALID: conversion of nil pointer
105+
// u := unsafe.Pointer(nil)
106+
// p := unsafe.Pointer(uintptr(u) + offset)
107+
//
102108
// (4) Conversion of a Pointer to a uintptr when calling syscall.Syscall.
103109
//
104110
// The Syscall functions in package syscall pass their uintptr arguments directly

0 commit comments

Comments
 (0)