// We don't want pointers accidentally classified
// as not-pointers or vice-versa because of copy
// elision.
- if to.IsPtr() != from.IsPtr() {
+ if to.IsPtrShaped() != from.IsPtrShaped() {
return s.newValue2(ssa.OpConvert, to, x, s.mem())
}
v := s.newValue1(ssa.OpCopy, to, x) // ensure that v has the right type
// CONVNOP closure
- if to.Etype == TFUNC && from.IsPtr() {
+ if to.Etype == TFUNC && from.IsPtrShaped() {
return v
}
// So here we ensure that we are selecting the underlying pointer
// when we build an eface.
// TODO: get rid of this now that structs can be SSA'd?
- for !data.Type.IsPtr() {
+ for !data.Type.IsPtrShaped() {
switch {
case data.Type.IsArray():
data = s.newValue1I(ssa.OpArrayIndex, data.Type.ElemType(), 0, data)
case t.IsString():
return s.constEmptyString(t)
- case t.IsPtr():
+ case t.IsPtrShaped():
return s.constNil(t)
case t.IsBoolean():
return s.constBool(false)
switch {
case t.IsBoolean() || t.IsInteger() || t.IsFloat() || t.IsComplex():
s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, t.Size(), left, right, s.mem())
- case t.IsPtr() || t.IsMap() || t.IsChan():
+ case t.IsPtrShaped():
// no scalar fields.
case t.IsString():
if skip&skipLen != 0 {
// do *left = right for all pointer parts of t.
func (s *state) storeTypePtrs(t *Type, left, right *ssa.Value) {
switch {
- case t.IsPtr() || t.IsMap() || t.IsChan():
+ case t.IsPtrShaped():
s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.PtrSize, left, right, s.mem())
case t.IsString():
ptr := s.newValue1(ssa.OpStringPtr, Ptrto(Types[TUINT8]), right)
// do *left = right with a write barrier for all pointer parts of t.
func (s *state) storeTypePtrsWB(t *Type, left, right *ssa.Value) {
switch {
- case t.IsPtr() || t.IsMap() || t.IsChan():
+ case t.IsPtrShaped():
s.rtcall(writebarrierptr, true, nil, left, right)
case t.IsString():
ptr := s.newValue1(ssa.OpStringPtr, Ptrto(Types[TUINT8]), right)
return t.Etype == TCOMPLEX64 || t.Etype == TCOMPLEX128
}
+// IsPtr reports whether t is a regular Go pointer type.
+// This does not include unsafe.Pointer.
func (t *Type) IsPtr() bool {
+ return t.Etype == TPTR32 || t.Etype == TPTR64
+}
+
+// IsPtrShaped reports whether t is represented by a single machine pointer.
+// In addition to regular Go pointer types, this includes map, channel, and
+// function types and unsafe.Pointer. It does not include array or struct types
+// that consist of a single pointer shaped type.
+// TODO(mdempsky): Should it? See golang.org/issue/15028.
+func (t *Type) IsPtrShaped() bool {
return t.Etype == TPTR32 || t.Etype == TPTR64 || t.Etype == TUNSAFEPTR ||
t.Etype == TMAP || t.Etype == TCHAN || t.Etype == TFUNC
}
IsSigned() bool
IsFloat() bool
IsComplex() bool
- IsPtr() bool
+ IsPtrShaped() bool
IsString() bool
IsSlice() bool
IsArray() bool
func (t *CompilerType) IsSigned() bool { return false }
func (t *CompilerType) IsFloat() bool { return false }
func (t *CompilerType) IsComplex() bool { return false }
-func (t *CompilerType) IsPtr() bool { return false }
+func (t *CompilerType) IsPtrShaped() bool { return false }
func (t *CompilerType) IsString() bool { return false }
func (t *CompilerType) IsSlice() bool { return false }
func (t *CompilerType) IsArray() bool { return false }