mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +00:00
cmd/compile: casts from slices to array pointers are known to be non-nil
The cast is proceeded by a bounds check. If the bounds check passes then we know the pointer in the slice is non-nil. ... except casts to pointers of 0-sized arrays. They are strange, as the bounds check can pass for a nil input. Change-Id: Ic01cf4a82d59fbe3071d4b271c94efca9cafaec1 Reviewed-on: https://go-review.googlesource.com/c/go/+/479335 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Auto-Submit: Keith Randall <khr@google.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
9c75c4b6d7
commit
0d9eb8bea2
@ -3277,10 +3277,15 @@ func (s *state) exprCheckPtr(n ir.Node, checkPtrOK bool) *ssa.Value {
|
||||
// slice.ptr
|
||||
n := n.(*ir.ConvExpr)
|
||||
v := s.expr(n.X)
|
||||
arrlen := s.constInt(types.Types[types.TINT], n.Type().Elem().NumElem())
|
||||
nelem := n.Type().Elem().NumElem()
|
||||
arrlen := s.constInt(types.Types[types.TINT], nelem)
|
||||
cap := s.newValue1(ssa.OpSliceLen, types.Types[types.TINT], v)
|
||||
s.boundsCheck(arrlen, cap, ssa.BoundsConvert, false)
|
||||
return s.newValue1(ssa.OpSlicePtrUnchecked, n.Type(), v)
|
||||
op := ssa.OpSlicePtr
|
||||
if nelem == 0 {
|
||||
op = ssa.OpSlicePtrUnchecked
|
||||
}
|
||||
return s.newValue1(op, n.Type(), v)
|
||||
|
||||
case ir.OCALLFUNC:
|
||||
n := n.(*ir.CallExpr)
|
||||
|
@ -248,3 +248,10 @@ func f10(p **int) int {
|
||||
/* */
|
||||
*p // ERROR "removed nil check"
|
||||
}
|
||||
|
||||
func f11(x []byte) {
|
||||
p := (*[0]byte)(x)
|
||||
_ = *p // ERROR "generated nil check"
|
||||
q := (*[4]byte)(x)
|
||||
_ = *q // ERROR "removed nil check"
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user