From bbfa601d27530c0adf38db446b510cd79a017ea2 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Wed, 25 Mar 2020 19:24:31 +0100 Subject: [PATCH] compiler: avoid nil pointer checks with unsafe.Pointer The unsafe.Pointer type is used for many low-level operations, especially in the runtime. It can for example be used to copy the contents of a slice (in the copy builtin) independent of the slice element type. --- compiler/asserts.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/compiler/asserts.go b/compiler/asserts.go index 7aeb0fe0..c7267163 100644 --- a/compiler/asserts.go +++ b/compiler/asserts.go @@ -158,12 +158,21 @@ func (b *builder) createNilCheck(inst ssa.Value, ptr llvm.Value, blockPrefix str return } - switch inst.(type) { + switch inst := inst.(type) { case *ssa.IndexAddr: // This pointer is the result of an index operation into a slice or // array. Such slices/arrays are already bounds checked so the pointer // must be a valid (non-nil) pointer. No nil checking is necessary. return + case *ssa.Convert: + // This is a pointer that comes from a conversion from unsafe.Pointer. + // Don't do nil checking because this is unsafe code and the code should + // know what it is doing. + // Note: all *ssa.Convert instructions that result in a pointer must + // come from unsafe.Pointer. Testing here for unsafe.Pointer to be sure. + if inst.X.Type() == types.Typ[types.UnsafePointer] { + return + } } // Compare against nil.