Commit 0c7762cd authored by Keith Randall's avatar Keith Randall Committed by Keith Randall

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/146058Reviewed-by: 's avatarAustin Clements <austin@google.com>
parent a063a228
......@@ -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
}
}
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment