name = "msanwrite"
}
f = mkcall(name, nil, init, uintptraddr(n), nodintconst(w))
- } else if flag_race && t.NumComponents() > 1 {
+ } else if flag_race && t.NumComponents(types.CountBlankFields) > 1 {
// for composite objects we have to write every address
// because a write might happen to any subobject.
// composites with only one element don't have subobjects, though.
// We can compare several elements at once with 2/4/8 byte integer compares
inline = t.NumElem() <= 1 || (issimple[t.Elem().Etype] && (t.NumElem() <= 4 || t.Elem().Width*t.NumElem() <= maxcmpsize))
case TSTRUCT:
- inline = t.NumComponents() <= 4
+ inline = t.NumComponents(types.IgnoreBlankFields) <= 4
}
cmpl := n.Left
at.Bound = n
}
-func (t *Type) NumComponents() int64 {
+type componentsIncludeBlankFields bool
+
+const (
+ IgnoreBlankFields componentsIncludeBlankFields = false
+ CountBlankFields componentsIncludeBlankFields = true
+)
+
+// NumComponents returns the number of primitive elements that compose t.
+// Struct and array types are flattened for the purpose of counting.
+// All other types (including string, slice, and interface types) count as one element.
+// If countBlank is IgnoreBlankFields, then blank struct fields
+// (and their comprised elements) are excluded from the count.
+// struct { x, y [3]int } has six components; [10]struct{ x, y string } has twenty.
+func (t *Type) NumComponents(countBlank componentsIncludeBlankFields) int64 {
switch t.Etype {
case TSTRUCT:
if t.IsFuncArgStruct() {
}
var n int64
for _, f := range t.FieldSlice() {
- n += f.Type.NumComponents()
+ if countBlank == IgnoreBlankFields && f.Sym.IsBlank() {
+ continue
+ }
+ n += f.Type.NumComponents(countBlank)
}
return n
case TARRAY:
- return t.NumElem() * t.Elem().NumComponents()
+ return t.NumElem() * t.Elem().NumComponents(countBlank)
}
return 1
}