Skip to content

Commit

Permalink
cmd/compile: assume unsafe pointer arithmetic generates non-nil results
Browse files Browse the repository at this point in the history
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 <austin@google.com>
  • Loading branch information
randall77 committed Nov 14, 2018
1 parent a063a22 commit 0c7762c
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/cmd/compile/internal/ssa/nilcheck.go
Expand Up @@ -47,7 +47,8 @@ func nilcheckelim(f *Func) {
// a value resulting from taking the address of a
// value, or a value constructed from an offset of a
// non-nil ptr (OpAddPtr) implies it is non-nil
if v.Op == OpAddr || v.Op == OpLocalAddr || v.Op == OpAddPtr || v.Op == OpOffPtr {
// We also assume unsafe pointer arithmetic generates non-nil pointers. See #27180.
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 {
nonNilValues[v.ID] = true
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/unsafe/unsafe.go
Expand Up @@ -99,6 +99,12 @@ type ArbitraryType int
// u := uintptr(p)
// p = unsafe.Pointer(u + offset)
//
// Note that the pointer must point into an allocated object, so it may not be nil.
//
// // INVALID: conversion of nil pointer
// u := unsafe.Pointer(nil)
// p := unsafe.Pointer(uintptr(u) + offset)
//
// (4) Conversion of a Pointer to a uintptr when calling syscall.Syscall.
//
// The Syscall functions in package syscall pass their uintptr arguments directly
Expand Down

0 comments on commit 0c7762c

Please sign in to comment.