Source file src/cmd/compile/internal/ir/expr.go

     1  // Copyright 2020 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package ir
     6  
     7  import (
     8  	"bytes"
     9  	"cmd/compile/internal/base"
    10  	"cmd/compile/internal/types"
    11  	"cmd/internal/obj"
    12  	"cmd/internal/src"
    13  	"fmt"
    14  	"go/constant"
    15  	"go/token"
    16  )
    17  
    18  // An Expr is a Node that can appear as an expression.
    19  type Expr interface {
    20  	Node
    21  	isExpr()
    22  }
    23  
    24  // A miniExpr is a miniNode with extra fields common to expressions.
    25  // TODO(rsc): Once we are sure about the contents, compact the bools
    26  // into a bit field and leave extra bits available for implementations
    27  // embedding miniExpr. Right now there are ~24 unused bits sitting here.
    28  type miniExpr struct {
    29  	miniNode
    30  	flags bitset8
    31  	typ   *types.Type
    32  	init  Nodes // TODO(rsc): Don't require every Node to have an init
    33  }
    34  
    35  const (
    36  	miniExprNonNil = 1 << iota
    37  	miniExprTransient
    38  	miniExprBounded
    39  	miniExprImplicit // for use by implementations; not supported by every Expr
    40  	miniExprCheckPtr
    41  )
    42  
    43  func (*miniExpr) isExpr() {}
    44  
    45  func (n *miniExpr) Type() *types.Type     { return n.typ }
    46  func (n *miniExpr) SetType(x *types.Type) { n.typ = x }
    47  func (n *miniExpr) NonNil() bool          { return n.flags&miniExprNonNil != 0 }
    48  func (n *miniExpr) MarkNonNil()           { n.flags |= miniExprNonNil }
    49  func (n *miniExpr) Transient() bool       { return n.flags&miniExprTransient != 0 }
    50  func (n *miniExpr) SetTransient(b bool)   { n.flags.set(miniExprTransient, b) }
    51  func (n *miniExpr) Bounded() bool         { return n.flags&miniExprBounded != 0 }
    52  func (n *miniExpr) SetBounded(b bool)     { n.flags.set(miniExprBounded, b) }
    53  func (n *miniExpr) Init() Nodes           { return n.init }
    54  func (n *miniExpr) PtrInit() *Nodes       { return &n.init }
    55  func (n *miniExpr) SetInit(x Nodes)       { n.init = x }
    56  
    57  // An AddStringExpr is a string concatenation List[0] + List[1] + ... + List[len(List)-1].
    58  type AddStringExpr struct {
    59  	miniExpr
    60  	List     Nodes
    61  	Prealloc *Name
    62  }
    63  
    64  func NewAddStringExpr(pos src.XPos, list []Node) *AddStringExpr {
    65  	n := &AddStringExpr{}
    66  	n.pos = pos
    67  	n.op = OADDSTR
    68  	n.List = list
    69  	return n
    70  }
    71  
    72  // An AddrExpr is an address-of expression &X.
    73  // It may end up being a normal address-of or an allocation of a composite literal.
    74  type AddrExpr struct {
    75  	miniExpr
    76  	X        Node
    77  	Prealloc *Name // preallocated storage if any
    78  }
    79  
    80  func NewAddrExpr(pos src.XPos, x Node) *AddrExpr {
    81  	if x == nil || x.Typecheck() != 1 {
    82  		base.FatalfAt(pos, "missed typecheck: %L", x)
    83  	}
    84  	n := &AddrExpr{X: x}
    85  	n.pos = pos
    86  
    87  	switch x.Op() {
    88  	case OARRAYLIT, OMAPLIT, OSLICELIT, OSTRUCTLIT:
    89  		n.op = OPTRLIT
    90  
    91  	default:
    92  		n.op = OADDR
    93  		if r, ok := OuterValue(x).(*Name); ok && r.Op() == ONAME {
    94  			r.SetAddrtaken(true)
    95  
    96  			// If r is a closure variable, we need to mark its canonical
    97  			// variable as addrtaken too, so that closure conversion
    98  			// captures it by reference.
    99  			//
   100  			// Exception: if we've already marked the variable as
   101  			// capture-by-value, then that means this variable isn't
   102  			// logically modified, and we must be taking its address to pass
   103  			// to a runtime function that won't mutate it. In that case, we
   104  			// only need to make sure our own copy is addressable.
   105  			if r.IsClosureVar() && !r.Byval() {
   106  				r.Canonical().SetAddrtaken(true)
   107  			}
   108  		}
   109  	}
   110  
   111  	n.SetType(types.NewPtr(x.Type()))
   112  	n.SetTypecheck(1)
   113  
   114  	return n
   115  }
   116  
   117  func (n *AddrExpr) Implicit() bool     { return n.flags&miniExprImplicit != 0 }
   118  func (n *AddrExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
   119  
   120  func (n *AddrExpr) SetOp(op Op) {
   121  	switch op {
   122  	default:
   123  		panic(n.no("SetOp " + op.String()))
   124  	case OADDR, OPTRLIT:
   125  		n.op = op
   126  	}
   127  }
   128  
   129  // A BasicLit is a literal of basic type.
   130  type BasicLit struct {
   131  	miniExpr
   132  	val constant.Value
   133  }
   134  
   135  // NewBasicLit returns an OLITERAL representing val with the given type.
   136  func NewBasicLit(pos src.XPos, typ *types.Type, val constant.Value) Node {
   137  	AssertValidTypeForConst(typ, val)
   138  
   139  	n := &BasicLit{val: val}
   140  	n.op = OLITERAL
   141  	n.pos = pos
   142  	n.SetType(typ)
   143  	n.SetTypecheck(1)
   144  	return n
   145  }
   146  
   147  func (n *BasicLit) Val() constant.Value       { return n.val }
   148  func (n *BasicLit) SetVal(val constant.Value) { n.val = val }
   149  
   150  // NewConstExpr returns an OLITERAL representing val, copying the
   151  // position and type from orig.
   152  func NewConstExpr(val constant.Value, orig Node) Node {
   153  	return NewBasicLit(orig.Pos(), orig.Type(), val)
   154  }
   155  
   156  // A BinaryExpr is a binary expression X Op Y,
   157  // or Op(X, Y) for builtin functions that do not become calls.
   158  type BinaryExpr struct {
   159  	miniExpr
   160  	X     Node
   161  	Y     Node
   162  	RType Node `mknode:"-"` // see reflectdata/helpers.go
   163  }
   164  
   165  func NewBinaryExpr(pos src.XPos, op Op, x, y Node) *BinaryExpr {
   166  	n := &BinaryExpr{X: x, Y: y}
   167  	n.pos = pos
   168  	n.SetOp(op)
   169  	return n
   170  }
   171  
   172  func (n *BinaryExpr) SetOp(op Op) {
   173  	switch op {
   174  	default:
   175  		panic(n.no("SetOp " + op.String()))
   176  	case OADD, OADDSTR, OAND, OANDNOT, ODIV, OEQ, OGE, OGT, OLE,
   177  		OLSH, OLT, OMOD, OMUL, ONE, OOR, ORSH, OSUB, OXOR,
   178  		OCOPY, OCOMPLEX, OUNSAFEADD, OUNSAFESLICE, OUNSAFESTRING,
   179  		OMAKEFACE:
   180  		n.op = op
   181  	}
   182  }
   183  
   184  // A CallExpr is a function call Fun(Args).
   185  type CallExpr struct {
   186  	miniExpr
   187  	Fun       Node
   188  	Args      Nodes
   189  	DeferAt   Node
   190  	RType     Node    `mknode:"-"` // see reflectdata/helpers.go
   191  	KeepAlive []*Name // vars to be kept alive until call returns
   192  	IsDDD     bool
   193  	GoDefer   bool // whether this call is part of a go or defer statement
   194  }
   195  
   196  func NewCallExpr(pos src.XPos, op Op, fun Node, args []Node) *CallExpr {
   197  	n := &CallExpr{Fun: fun}
   198  	n.pos = pos
   199  	n.SetOp(op)
   200  	n.Args = args
   201  	return n
   202  }
   203  
   204  func (*CallExpr) isStmt() {}
   205  
   206  func (n *CallExpr) SetOp(op Op) {
   207  	switch op {
   208  	default:
   209  		panic(n.no("SetOp " + op.String()))
   210  	case OAPPEND,
   211  		OCALL, OCALLFUNC, OCALLINTER, OCALLMETH,
   212  		ODELETE,
   213  		OGETG, OGETCALLERSP,
   214  		OMAKE, OMAX, OMIN, OPRINT, OPRINTLN,
   215  		ORECOVER, ORECOVERFP:
   216  		n.op = op
   217  	}
   218  }
   219  
   220  // A ClosureExpr is a function literal expression.
   221  type ClosureExpr struct {
   222  	miniExpr
   223  	Func     *Func `mknode:"-"`
   224  	Prealloc *Name
   225  	IsGoWrap bool // whether this is wrapper closure of a go statement
   226  }
   227  
   228  // A CompLitExpr is a composite literal Type{Vals}.
   229  // Before type-checking, the type is Ntype.
   230  type CompLitExpr struct {
   231  	miniExpr
   232  	List     Nodes // initialized values
   233  	RType    Node  `mknode:"-"` // *runtime._type for OMAPLIT map types
   234  	Prealloc *Name
   235  	// For OSLICELIT, Len is the backing array length.
   236  	// For OMAPLIT, Len is the number of entries that we've removed from List and
   237  	// generated explicit mapassign calls for. This is used to inform the map alloc hint.
   238  	Len int64
   239  }
   240  
   241  func NewCompLitExpr(pos src.XPos, op Op, typ *types.Type, list []Node) *CompLitExpr {
   242  	n := &CompLitExpr{List: list}
   243  	n.pos = pos
   244  	n.SetOp(op)
   245  	if typ != nil {
   246  		n.SetType(typ)
   247  	}
   248  	return n
   249  }
   250  
   251  func (n *CompLitExpr) Implicit() bool     { return n.flags&miniExprImplicit != 0 }
   252  func (n *CompLitExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
   253  
   254  func (n *CompLitExpr) SetOp(op Op) {
   255  	switch op {
   256  	default:
   257  		panic(n.no("SetOp " + op.String()))
   258  	case OARRAYLIT, OCOMPLIT, OMAPLIT, OSTRUCTLIT, OSLICELIT:
   259  		n.op = op
   260  	}
   261  }
   262  
   263  // A ConvExpr is a conversion Type(X).
   264  // It may end up being a value or a type.
   265  type ConvExpr struct {
   266  	miniExpr
   267  	X Node
   268  
   269  	// For implementing OCONVIFACE expressions.
   270  	//
   271  	// TypeWord is an expression yielding a *runtime._type or
   272  	// *runtime.itab value to go in the type word of the iface/eface
   273  	// result. See reflectdata.ConvIfaceTypeWord for further details.
   274  	//
   275  	// SrcRType is an expression yielding a *runtime._type value for X,
   276  	// if it's not pointer-shaped and needs to be heap allocated.
   277  	TypeWord Node `mknode:"-"`
   278  	SrcRType Node `mknode:"-"`
   279  
   280  	// For -d=checkptr instrumentation of conversions from
   281  	// unsafe.Pointer to *Elem or *[Len]Elem.
   282  	//
   283  	// TODO(mdempsky): We only ever need one of these, but currently we
   284  	// don't decide which one until walk. Longer term, it probably makes
   285  	// sense to have a dedicated IR op for `(*[Len]Elem)(ptr)[:n:m]`
   286  	// expressions.
   287  	ElemRType     Node `mknode:"-"`
   288  	ElemElemRType Node `mknode:"-"`
   289  }
   290  
   291  func NewConvExpr(pos src.XPos, op Op, typ *types.Type, x Node) *ConvExpr {
   292  	n := &ConvExpr{X: x}
   293  	n.pos = pos
   294  	n.typ = typ
   295  	n.SetOp(op)
   296  	return n
   297  }
   298  
   299  func (n *ConvExpr) Implicit() bool     { return n.flags&miniExprImplicit != 0 }
   300  func (n *ConvExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
   301  func (n *ConvExpr) CheckPtr() bool     { return n.flags&miniExprCheckPtr != 0 }
   302  func (n *ConvExpr) SetCheckPtr(b bool) { n.flags.set(miniExprCheckPtr, b) }
   303  
   304  func (n *ConvExpr) SetOp(op Op) {
   305  	switch op {
   306  	default:
   307  		panic(n.no("SetOp " + op.String()))
   308  	case OCONV, OCONVIFACE, OCONVNOP, OBYTES2STR, OBYTES2STRTMP, ORUNES2STR, OSTR2BYTES, OSTR2BYTESTMP, OSTR2RUNES, ORUNESTR, OSLICE2ARR, OSLICE2ARRPTR:
   309  		n.op = op
   310  	}
   311  }
   312  
   313  // An IndexExpr is an index expression X[Index].
   314  type IndexExpr struct {
   315  	miniExpr
   316  	X        Node
   317  	Index    Node
   318  	RType    Node `mknode:"-"` // see reflectdata/helpers.go
   319  	Assigned bool
   320  }
   321  
   322  func NewIndexExpr(pos src.XPos, x, index Node) *IndexExpr {
   323  	n := &IndexExpr{X: x, Index: index}
   324  	n.pos = pos
   325  	n.op = OINDEX
   326  	return n
   327  }
   328  
   329  func (n *IndexExpr) SetOp(op Op) {
   330  	switch op {
   331  	default:
   332  		panic(n.no("SetOp " + op.String()))
   333  	case OINDEX, OINDEXMAP:
   334  		n.op = op
   335  	}
   336  }
   337  
   338  // A KeyExpr is a Key: Value composite literal key.
   339  type KeyExpr struct {
   340  	miniExpr
   341  	Key   Node
   342  	Value Node
   343  }
   344  
   345  func NewKeyExpr(pos src.XPos, key, value Node) *KeyExpr {
   346  	n := &KeyExpr{Key: key, Value: value}
   347  	n.pos = pos
   348  	n.op = OKEY
   349  	return n
   350  }
   351  
   352  // A StructKeyExpr is a Field: Value composite literal key.
   353  type StructKeyExpr struct {
   354  	miniExpr
   355  	Field *types.Field
   356  	Value Node
   357  }
   358  
   359  func NewStructKeyExpr(pos src.XPos, field *types.Field, value Node) *StructKeyExpr {
   360  	n := &StructKeyExpr{Field: field, Value: value}
   361  	n.pos = pos
   362  	n.op = OSTRUCTKEY
   363  	return n
   364  }
   365  
   366  func (n *StructKeyExpr) Sym() *types.Sym { return n.Field.Sym }
   367  
   368  // An InlinedCallExpr is an inlined function call.
   369  type InlinedCallExpr struct {
   370  	miniExpr
   371  	Body       Nodes
   372  	ReturnVars Nodes // must be side-effect free
   373  }
   374  
   375  func NewInlinedCallExpr(pos src.XPos, body, retvars []Node) *InlinedCallExpr {
   376  	n := &InlinedCallExpr{}
   377  	n.pos = pos
   378  	n.op = OINLCALL
   379  	n.Body = body
   380  	n.ReturnVars = retvars
   381  	return n
   382  }
   383  
   384  func (n *InlinedCallExpr) SingleResult() Node {
   385  	if have := len(n.ReturnVars); have != 1 {
   386  		base.FatalfAt(n.Pos(), "inlined call has %v results, expected 1", have)
   387  	}
   388  	if !n.Type().HasShape() && n.ReturnVars[0].Type().HasShape() {
   389  		// If the type of the call is not a shape, but the type of the return value
   390  		// is a shape, we need to do an implicit conversion, so the real type
   391  		// of n is maintained.
   392  		r := NewConvExpr(n.Pos(), OCONVNOP, n.Type(), n.ReturnVars[0])
   393  		r.SetTypecheck(1)
   394  		return r
   395  	}
   396  	return n.ReturnVars[0]
   397  }
   398  
   399  // A LogicalExpr is an expression X Op Y where Op is && or ||.
   400  // It is separate from BinaryExpr to make room for statements
   401  // that must be executed before Y but after X.
   402  type LogicalExpr struct {
   403  	miniExpr
   404  	X Node
   405  	Y Node
   406  }
   407  
   408  func NewLogicalExpr(pos src.XPos, op Op, x, y Node) *LogicalExpr {
   409  	n := &LogicalExpr{X: x, Y: y}
   410  	n.pos = pos
   411  	n.SetOp(op)
   412  	return n
   413  }
   414  
   415  func (n *LogicalExpr) SetOp(op Op) {
   416  	switch op {
   417  	default:
   418  		panic(n.no("SetOp " + op.String()))
   419  	case OANDAND, OOROR:
   420  		n.op = op
   421  	}
   422  }
   423  
   424  // A MakeExpr is a make expression: make(Type[, Len[, Cap]]).
   425  // Op is OMAKECHAN, OMAKEMAP, OMAKESLICE, or OMAKESLICECOPY,
   426  // but *not* OMAKE (that's a pre-typechecking CallExpr).
   427  type MakeExpr struct {
   428  	miniExpr
   429  	RType Node `mknode:"-"` // see reflectdata/helpers.go
   430  	Len   Node
   431  	Cap   Node
   432  }
   433  
   434  func NewMakeExpr(pos src.XPos, op Op, len, cap Node) *MakeExpr {
   435  	n := &MakeExpr{Len: len, Cap: cap}
   436  	n.pos = pos
   437  	n.SetOp(op)
   438  	return n
   439  }
   440  
   441  func (n *MakeExpr) SetOp(op Op) {
   442  	switch op {
   443  	default:
   444  		panic(n.no("SetOp " + op.String()))
   445  	case OMAKECHAN, OMAKEMAP, OMAKESLICE, OMAKESLICECOPY:
   446  		n.op = op
   447  	}
   448  }
   449  
   450  // A NilExpr represents the predefined untyped constant nil.
   451  type NilExpr struct {
   452  	miniExpr
   453  }
   454  
   455  func NewNilExpr(pos src.XPos, typ *types.Type) *NilExpr {
   456  	if typ == nil {
   457  		base.FatalfAt(pos, "missing type")
   458  	}
   459  	n := &NilExpr{}
   460  	n.pos = pos
   461  	n.op = ONIL
   462  	n.SetType(typ)
   463  	n.SetTypecheck(1)
   464  	return n
   465  }
   466  
   467  // A ParenExpr is a parenthesized expression (X).
   468  // It may end up being a value or a type.
   469  type ParenExpr struct {
   470  	miniExpr
   471  	X Node
   472  }
   473  
   474  func NewParenExpr(pos src.XPos, x Node) *ParenExpr {
   475  	n := &ParenExpr{X: x}
   476  	n.op = OPAREN
   477  	n.pos = pos
   478  	return n
   479  }
   480  
   481  func (n *ParenExpr) Implicit() bool     { return n.flags&miniExprImplicit != 0 }
   482  func (n *ParenExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
   483  
   484  // A ResultExpr represents a direct access to a result.
   485  type ResultExpr struct {
   486  	miniExpr
   487  	Index int64 // index of the result expr.
   488  }
   489  
   490  func NewResultExpr(pos src.XPos, typ *types.Type, index int64) *ResultExpr {
   491  	n := &ResultExpr{Index: index}
   492  	n.pos = pos
   493  	n.op = ORESULT
   494  	n.typ = typ
   495  	return n
   496  }
   497  
   498  // A LinksymOffsetExpr refers to an offset within a global variable.
   499  // It is like a SelectorExpr but without the field name.
   500  type LinksymOffsetExpr struct {
   501  	miniExpr
   502  	Linksym *obj.LSym
   503  	Offset_ int64
   504  }
   505  
   506  func NewLinksymOffsetExpr(pos src.XPos, lsym *obj.LSym, offset int64, typ *types.Type) *LinksymOffsetExpr {
   507  	if typ == nil {
   508  		base.FatalfAt(pos, "nil type")
   509  	}
   510  	n := &LinksymOffsetExpr{Linksym: lsym, Offset_: offset}
   511  	n.typ = typ
   512  	n.op = OLINKSYMOFFSET
   513  	n.SetTypecheck(1)
   514  	return n
   515  }
   516  
   517  // NewLinksymExpr is NewLinksymOffsetExpr, but with offset fixed at 0.
   518  func NewLinksymExpr(pos src.XPos, lsym *obj.LSym, typ *types.Type) *LinksymOffsetExpr {
   519  	return NewLinksymOffsetExpr(pos, lsym, 0, typ)
   520  }
   521  
   522  // NewNameOffsetExpr is NewLinksymOffsetExpr, but taking a *Name
   523  // representing a global variable instead of an *obj.LSym directly.
   524  func NewNameOffsetExpr(pos src.XPos, name *Name, offset int64, typ *types.Type) *LinksymOffsetExpr {
   525  	if name == nil || IsBlank(name) || !(name.Op() == ONAME && name.Class == PEXTERN) {
   526  		base.FatalfAt(pos, "cannot take offset of nil, blank name or non-global variable: %v", name)
   527  	}
   528  	return NewLinksymOffsetExpr(pos, name.Linksym(), offset, typ)
   529  }
   530  
   531  // A SelectorExpr is a selector expression X.Sel.
   532  type SelectorExpr struct {
   533  	miniExpr
   534  	X Node
   535  	// Sel is the name of the field or method being selected, without (in the
   536  	// case of methods) any preceding type specifier. If the field/method is
   537  	// exported, than the Sym uses the local package regardless of the package
   538  	// of the containing type.
   539  	Sel *types.Sym
   540  	// The actual selected field - may not be filled in until typechecking.
   541  	Selection *types.Field
   542  	Prealloc  *Name // preallocated storage for OMETHVALUE, if any
   543  }
   544  
   545  func NewSelectorExpr(pos src.XPos, op Op, x Node, sel *types.Sym) *SelectorExpr {
   546  	n := &SelectorExpr{X: x, Sel: sel}
   547  	n.pos = pos
   548  	n.SetOp(op)
   549  	return n
   550  }
   551  
   552  func (n *SelectorExpr) SetOp(op Op) {
   553  	switch op {
   554  	default:
   555  		panic(n.no("SetOp " + op.String()))
   556  	case OXDOT, ODOT, ODOTPTR, ODOTMETH, ODOTINTER, OMETHVALUE, OMETHEXPR:
   557  		n.op = op
   558  	}
   559  }
   560  
   561  func (n *SelectorExpr) Sym() *types.Sym    { return n.Sel }
   562  func (n *SelectorExpr) Implicit() bool     { return n.flags&miniExprImplicit != 0 }
   563  func (n *SelectorExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
   564  func (n *SelectorExpr) Offset() int64      { return n.Selection.Offset }
   565  
   566  func (n *SelectorExpr) FuncName() *Name {
   567  	if n.Op() != OMETHEXPR {
   568  		panic(n.no("FuncName"))
   569  	}
   570  	fn := NewNameAt(n.Selection.Pos, MethodSym(n.X.Type(), n.Sel), n.Type())
   571  	fn.Class = PFUNC
   572  	if n.Selection.Nname != nil {
   573  		// TODO(austin): Nname is nil for interface method
   574  		// expressions (I.M), so we can't attach a Func to
   575  		// those here.
   576  		fn.Func = n.Selection.Nname.(*Name).Func
   577  	}
   578  	return fn
   579  }
   580  
   581  // A SliceExpr is a slice expression X[Low:High] or X[Low:High:Max].
   582  type SliceExpr struct {
   583  	miniExpr
   584  	X    Node
   585  	Low  Node
   586  	High Node
   587  	Max  Node
   588  }
   589  
   590  func NewSliceExpr(pos src.XPos, op Op, x, low, high, max Node) *SliceExpr {
   591  	n := &SliceExpr{X: x, Low: low, High: high, Max: max}
   592  	n.pos = pos
   593  	n.op = op
   594  	return n
   595  }
   596  
   597  func (n *SliceExpr) SetOp(op Op) {
   598  	switch op {
   599  	default:
   600  		panic(n.no("SetOp " + op.String()))
   601  	case OSLICE, OSLICEARR, OSLICESTR, OSLICE3, OSLICE3ARR:
   602  		n.op = op
   603  	}
   604  }
   605  
   606  // IsSlice3 reports whether o is a slice3 op (OSLICE3, OSLICE3ARR).
   607  // o must be a slicing op.
   608  func (o Op) IsSlice3() bool {
   609  	switch o {
   610  	case OSLICE, OSLICEARR, OSLICESTR:
   611  		return false
   612  	case OSLICE3, OSLICE3ARR:
   613  		return true
   614  	}
   615  	base.Fatalf("IsSlice3 op %v", o)
   616  	return false
   617  }
   618  
   619  // A SliceHeader expression constructs a slice header from its parts.
   620  type SliceHeaderExpr struct {
   621  	miniExpr
   622  	Ptr Node
   623  	Len Node
   624  	Cap Node
   625  }
   626  
   627  func NewSliceHeaderExpr(pos src.XPos, typ *types.Type, ptr, len, cap Node) *SliceHeaderExpr {
   628  	n := &SliceHeaderExpr{Ptr: ptr, Len: len, Cap: cap}
   629  	n.pos = pos
   630  	n.op = OSLICEHEADER
   631  	n.typ = typ
   632  	return n
   633  }
   634  
   635  // A StringHeaderExpr expression constructs a string header from its parts.
   636  type StringHeaderExpr struct {
   637  	miniExpr
   638  	Ptr Node
   639  	Len Node
   640  }
   641  
   642  func NewStringHeaderExpr(pos src.XPos, ptr, len Node) *StringHeaderExpr {
   643  	n := &StringHeaderExpr{Ptr: ptr, Len: len}
   644  	n.pos = pos
   645  	n.op = OSTRINGHEADER
   646  	n.typ = types.Types[types.TSTRING]
   647  	return n
   648  }
   649  
   650  // A StarExpr is a dereference expression *X.
   651  // It may end up being a value or a type.
   652  type StarExpr struct {
   653  	miniExpr
   654  	X Node
   655  }
   656  
   657  func NewStarExpr(pos src.XPos, x Node) *StarExpr {
   658  	n := &StarExpr{X: x}
   659  	n.op = ODEREF
   660  	n.pos = pos
   661  	return n
   662  }
   663  
   664  func (n *StarExpr) Implicit() bool     { return n.flags&miniExprImplicit != 0 }
   665  func (n *StarExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
   666  
   667  // A TypeAssertionExpr is a selector expression X.(Type).
   668  // Before type-checking, the type is Ntype.
   669  type TypeAssertExpr struct {
   670  	miniExpr
   671  	X Node
   672  
   673  	// Runtime type information provided by walkDotType for
   674  	// assertions from non-empty interface to concrete type.
   675  	ITab Node `mknode:"-"` // *runtime.itab for Type implementing X's type
   676  
   677  	// An internal/abi.TypeAssert descriptor to pass to the runtime.
   678  	Descriptor *obj.LSym
   679  }
   680  
   681  func NewTypeAssertExpr(pos src.XPos, x Node, typ *types.Type) *TypeAssertExpr {
   682  	n := &TypeAssertExpr{X: x}
   683  	n.pos = pos
   684  	n.op = ODOTTYPE
   685  	if typ != nil {
   686  		n.SetType(typ)
   687  	}
   688  	return n
   689  }
   690  
   691  func (n *TypeAssertExpr) SetOp(op Op) {
   692  	switch op {
   693  	default:
   694  		panic(n.no("SetOp " + op.String()))
   695  	case ODOTTYPE, ODOTTYPE2:
   696  		n.op = op
   697  	}
   698  }
   699  
   700  // A DynamicTypeAssertExpr asserts that X is of dynamic type RType.
   701  type DynamicTypeAssertExpr struct {
   702  	miniExpr
   703  	X Node
   704  
   705  	// SrcRType is an expression that yields a *runtime._type value
   706  	// representing X's type. It's used in failed assertion panic
   707  	// messages.
   708  	SrcRType Node
   709  
   710  	// RType is an expression that yields a *runtime._type value
   711  	// representing the asserted type.
   712  	//
   713  	// BUG(mdempsky): If ITab is non-nil, RType may be nil.
   714  	RType Node
   715  
   716  	// ITab is an expression that yields a *runtime.itab value
   717  	// representing the asserted type within the assertee expression's
   718  	// original interface type.
   719  	//
   720  	// ITab is only used for assertions from non-empty interface type to
   721  	// a concrete (i.e., non-interface) type. For all other assertions,
   722  	// ITab is nil.
   723  	ITab Node
   724  }
   725  
   726  func NewDynamicTypeAssertExpr(pos src.XPos, op Op, x, rtype Node) *DynamicTypeAssertExpr {
   727  	n := &DynamicTypeAssertExpr{X: x, RType: rtype}
   728  	n.pos = pos
   729  	n.op = op
   730  	return n
   731  }
   732  
   733  func (n *DynamicTypeAssertExpr) SetOp(op Op) {
   734  	switch op {
   735  	default:
   736  		panic(n.no("SetOp " + op.String()))
   737  	case ODYNAMICDOTTYPE, ODYNAMICDOTTYPE2:
   738  		n.op = op
   739  	}
   740  }
   741  
   742  // A UnaryExpr is a unary expression Op X,
   743  // or Op(X) for a builtin function that does not end up being a call.
   744  type UnaryExpr struct {
   745  	miniExpr
   746  	X Node
   747  }
   748  
   749  func NewUnaryExpr(pos src.XPos, op Op, x Node) *UnaryExpr {
   750  	n := &UnaryExpr{X: x}
   751  	n.pos = pos
   752  	n.SetOp(op)
   753  	return n
   754  }
   755  
   756  func (n *UnaryExpr) SetOp(op Op) {
   757  	switch op {
   758  	default:
   759  		panic(n.no("SetOp " + op.String()))
   760  	case OBITNOT, ONEG, ONOT, OPLUS, ORECV,
   761  		OCAP, OCLEAR, OCLOSE, OIMAG, OLEN, ONEW, OPANIC, OREAL,
   762  		OCHECKNIL, OCFUNC, OIDATA, OITAB, OSPTR,
   763  		OUNSAFESTRINGDATA, OUNSAFESLICEDATA:
   764  		n.op = op
   765  	}
   766  }
   767  
   768  func IsZero(n Node) bool {
   769  	switch n.Op() {
   770  	case ONIL:
   771  		return true
   772  
   773  	case OLITERAL:
   774  		switch u := n.Val(); u.Kind() {
   775  		case constant.String:
   776  			return constant.StringVal(u) == ""
   777  		case constant.Bool:
   778  			return !constant.BoolVal(u)
   779  		default:
   780  			return constant.Sign(u) == 0
   781  		}
   782  
   783  	case OARRAYLIT:
   784  		n := n.(*CompLitExpr)
   785  		for _, n1 := range n.List {
   786  			if n1.Op() == OKEY {
   787  				n1 = n1.(*KeyExpr).Value
   788  			}
   789  			if !IsZero(n1) {
   790  				return false
   791  			}
   792  		}
   793  		return true
   794  
   795  	case OSTRUCTLIT:
   796  		n := n.(*CompLitExpr)
   797  		for _, n1 := range n.List {
   798  			n1 := n1.(*StructKeyExpr)
   799  			if !IsZero(n1.Value) {
   800  				return false
   801  			}
   802  		}
   803  		return true
   804  	}
   805  
   806  	return false
   807  }
   808  
   809  // lvalue etc
   810  func IsAddressable(n Node) bool {
   811  	switch n.Op() {
   812  	case OINDEX:
   813  		n := n.(*IndexExpr)
   814  		if n.X.Type() != nil && n.X.Type().IsArray() {
   815  			return IsAddressable(n.X)
   816  		}
   817  		if n.X.Type() != nil && n.X.Type().IsString() {
   818  			return false
   819  		}
   820  		fallthrough
   821  	case ODEREF, ODOTPTR:
   822  		return true
   823  
   824  	case ODOT:
   825  		n := n.(*SelectorExpr)
   826  		return IsAddressable(n.X)
   827  
   828  	case ONAME:
   829  		n := n.(*Name)
   830  		if n.Class == PFUNC {
   831  			return false
   832  		}
   833  		return true
   834  
   835  	case OLINKSYMOFFSET:
   836  		return true
   837  	}
   838  
   839  	return false
   840  }
   841  
   842  // StaticValue analyzes n to find the earliest expression that always
   843  // evaluates to the same value as n, which might be from an enclosing
   844  // function.
   845  //
   846  // For example, given:
   847  //
   848  //	var x int = g()
   849  //	func() {
   850  //		y := x
   851  //		*p = int(y)
   852  //	}
   853  //
   854  // calling StaticValue on the "int(y)" expression returns the outer
   855  // "g()" expression.
   856  func StaticValue(n Node) Node {
   857  	for {
   858  		switch n1 := n.(type) {
   859  		case *ConvExpr:
   860  			if n1.Op() == OCONVNOP {
   861  				n = n1.X
   862  				continue
   863  			}
   864  		case *InlinedCallExpr:
   865  			if n1.Op() == OINLCALL {
   866  				n = n1.SingleResult()
   867  				continue
   868  			}
   869  		case *ParenExpr:
   870  			n = n1.X
   871  			continue
   872  		}
   873  
   874  		n1 := staticValue1(n)
   875  		if n1 == nil {
   876  			return n
   877  		}
   878  		n = n1
   879  	}
   880  }
   881  
   882  func staticValue1(nn Node) Node {
   883  	if nn.Op() != ONAME {
   884  		return nil
   885  	}
   886  	n := nn.(*Name).Canonical()
   887  	if n.Class != PAUTO {
   888  		return nil
   889  	}
   890  
   891  	defn := n.Defn
   892  	if defn == nil {
   893  		return nil
   894  	}
   895  
   896  	var rhs Node
   897  FindRHS:
   898  	switch defn.Op() {
   899  	case OAS:
   900  		defn := defn.(*AssignStmt)
   901  		rhs = defn.Y
   902  	case OAS2:
   903  		defn := defn.(*AssignListStmt)
   904  		for i, lhs := range defn.Lhs {
   905  			if lhs == n {
   906  				rhs = defn.Rhs[i]
   907  				break FindRHS
   908  			}
   909  		}
   910  		base.Fatalf("%v missing from LHS of %v", n, defn)
   911  	default:
   912  		return nil
   913  	}
   914  	if rhs == nil {
   915  		base.Fatalf("RHS is nil: %v", defn)
   916  	}
   917  
   918  	if Reassigned(n) {
   919  		return nil
   920  	}
   921  
   922  	return rhs
   923  }
   924  
   925  // Reassigned takes an ONAME node, walks the function in which it is
   926  // defined, and returns a boolean indicating whether the name has any
   927  // assignments other than its declaration.
   928  // NB: global variables are always considered to be re-assigned.
   929  // TODO: handle initial declaration not including an assignment and
   930  // followed by a single assignment?
   931  // NOTE: any changes made here should also be made in the corresponding
   932  // code in the ReassignOracle.Init method.
   933  func Reassigned(name *Name) bool {
   934  	if name.Op() != ONAME {
   935  		base.Fatalf("reassigned %v", name)
   936  	}
   937  	// no way to reliably check for no-reassignment of globals, assume it can be
   938  	if name.Curfn == nil {
   939  		return true
   940  	}
   941  
   942  	if name.Addrtaken() {
   943  		return true // conservatively assume it's reassigned indirectly
   944  	}
   945  
   946  	// TODO(mdempsky): This is inefficient and becoming increasingly
   947  	// unwieldy. Figure out a way to generalize escape analysis's
   948  	// reassignment detection for use by inlining and devirtualization.
   949  
   950  	// isName reports whether n is a reference to name.
   951  	isName := func(x Node) bool {
   952  		if x == nil {
   953  			return false
   954  		}
   955  		n, ok := OuterValue(x).(*Name)
   956  		return ok && n.Canonical() == name
   957  	}
   958  
   959  	var do func(n Node) bool
   960  	do = func(n Node) bool {
   961  		switch n.Op() {
   962  		case OAS:
   963  			n := n.(*AssignStmt)
   964  			if isName(n.X) && n != name.Defn {
   965  				return true
   966  			}
   967  		case OAS2, OAS2FUNC, OAS2MAPR, OAS2DOTTYPE, OAS2RECV, OSELRECV2:
   968  			n := n.(*AssignListStmt)
   969  			for _, p := range n.Lhs {
   970  				if isName(p) && n != name.Defn {
   971  					return true
   972  				}
   973  			}
   974  		case OASOP:
   975  			n := n.(*AssignOpStmt)
   976  			if isName(n.X) {
   977  				return true
   978  			}
   979  		case OADDR:
   980  			n := n.(*AddrExpr)
   981  			if isName(n.X) {
   982  				base.FatalfAt(n.Pos(), "%v not marked addrtaken", name)
   983  			}
   984  		case ORANGE:
   985  			n := n.(*RangeStmt)
   986  			if isName(n.Key) || isName(n.Value) {
   987  				return true
   988  			}
   989  		case OCLOSURE:
   990  			n := n.(*ClosureExpr)
   991  			if Any(n.Func, do) {
   992  				return true
   993  			}
   994  		}
   995  		return false
   996  	}
   997  	return Any(name.Curfn, do)
   998  }
   999  
  1000  // StaticCalleeName returns the ONAME/PFUNC for n, if known.
  1001  func StaticCalleeName(n Node) *Name {
  1002  	switch n.Op() {
  1003  	case OMETHEXPR:
  1004  		n := n.(*SelectorExpr)
  1005  		return MethodExprName(n)
  1006  	case ONAME:
  1007  		n := n.(*Name)
  1008  		if n.Class == PFUNC {
  1009  			return n
  1010  		}
  1011  	case OCLOSURE:
  1012  		return n.(*ClosureExpr).Func.Nname
  1013  	}
  1014  	return nil
  1015  }
  1016  
  1017  // IsIntrinsicCall reports whether the compiler back end will treat the call as an intrinsic operation.
  1018  var IsIntrinsicCall = func(*CallExpr) bool { return false }
  1019  
  1020  // SameSafeExpr checks whether it is safe to reuse one of l and r
  1021  // instead of computing both. SameSafeExpr assumes that l and r are
  1022  // used in the same statement or expression. In order for it to be
  1023  // safe to reuse l or r, they must:
  1024  //   - be the same expression
  1025  //   - not have side-effects (no function calls, no channel ops);
  1026  //     however, panics are ok
  1027  //   - not cause inappropriate aliasing; e.g. two string to []byte
  1028  //     conversions, must result in two distinct slices
  1029  //
  1030  // The handling of OINDEXMAP is subtle. OINDEXMAP can occur both
  1031  // as an lvalue (map assignment) and an rvalue (map access). This is
  1032  // currently OK, since the only place SameSafeExpr gets used on an
  1033  // lvalue expression is for OSLICE and OAPPEND optimizations, and it
  1034  // is correct in those settings.
  1035  func SameSafeExpr(l Node, r Node) bool {
  1036  	for l.Op() == OCONVNOP {
  1037  		l = l.(*ConvExpr).X
  1038  	}
  1039  	for r.Op() == OCONVNOP {
  1040  		r = r.(*ConvExpr).X
  1041  	}
  1042  	if l.Op() != r.Op() || !types.Identical(l.Type(), r.Type()) {
  1043  		return false
  1044  	}
  1045  
  1046  	switch l.Op() {
  1047  	case ONAME:
  1048  		return l == r
  1049  
  1050  	case ODOT, ODOTPTR:
  1051  		l := l.(*SelectorExpr)
  1052  		r := r.(*SelectorExpr)
  1053  		return l.Sel != nil && r.Sel != nil && l.Sel == r.Sel && SameSafeExpr(l.X, r.X)
  1054  
  1055  	case ODEREF:
  1056  		l := l.(*StarExpr)
  1057  		r := r.(*StarExpr)
  1058  		return SameSafeExpr(l.X, r.X)
  1059  
  1060  	case ONOT, OBITNOT, OPLUS, ONEG:
  1061  		l := l.(*UnaryExpr)
  1062  		r := r.(*UnaryExpr)
  1063  		return SameSafeExpr(l.X, r.X)
  1064  
  1065  	case OCONV:
  1066  		l := l.(*ConvExpr)
  1067  		r := r.(*ConvExpr)
  1068  		// Some conversions can't be reused, such as []byte(str).
  1069  		// Allow only numeric-ish types. This is a bit conservative.
  1070  		return types.IsSimple[l.Type().Kind()] && SameSafeExpr(l.X, r.X)
  1071  
  1072  	case OINDEX, OINDEXMAP:
  1073  		l := l.(*IndexExpr)
  1074  		r := r.(*IndexExpr)
  1075  		return SameSafeExpr(l.X, r.X) && SameSafeExpr(l.Index, r.Index)
  1076  
  1077  	case OADD, OSUB, OOR, OXOR, OMUL, OLSH, ORSH, OAND, OANDNOT, ODIV, OMOD:
  1078  		l := l.(*BinaryExpr)
  1079  		r := r.(*BinaryExpr)
  1080  		return SameSafeExpr(l.X, r.X) && SameSafeExpr(l.Y, r.Y)
  1081  
  1082  	case OLITERAL:
  1083  		return constant.Compare(l.Val(), token.EQL, r.Val())
  1084  
  1085  	case ONIL:
  1086  		return true
  1087  	}
  1088  
  1089  	return false
  1090  }
  1091  
  1092  // ShouldCheckPtr reports whether pointer checking should be enabled for
  1093  // function fn at a given level. See debugHelpFooter for defined
  1094  // levels.
  1095  func ShouldCheckPtr(fn *Func, level int) bool {
  1096  	return base.Debug.Checkptr >= level && fn.Pragma&NoCheckPtr == 0
  1097  }
  1098  
  1099  // ShouldAsanCheckPtr reports whether pointer checking should be enabled for
  1100  // function fn when -asan is enabled.
  1101  func ShouldAsanCheckPtr(fn *Func) bool {
  1102  	return base.Flag.ASan && fn.Pragma&NoCheckPtr == 0
  1103  }
  1104  
  1105  // IsReflectHeaderDataField reports whether l is an expression p.Data
  1106  // where p has type reflect.SliceHeader or reflect.StringHeader.
  1107  func IsReflectHeaderDataField(l Node) bool {
  1108  	if l.Type() != types.Types[types.TUINTPTR] {
  1109  		return false
  1110  	}
  1111  
  1112  	var tsym *types.Sym
  1113  	switch l.Op() {
  1114  	case ODOT:
  1115  		l := l.(*SelectorExpr)
  1116  		tsym = l.X.Type().Sym()
  1117  	case ODOTPTR:
  1118  		l := l.(*SelectorExpr)
  1119  		tsym = l.X.Type().Elem().Sym()
  1120  	default:
  1121  		return false
  1122  	}
  1123  
  1124  	if tsym == nil || l.Sym().Name != "Data" || tsym.Pkg.Path != "reflect" {
  1125  		return false
  1126  	}
  1127  	return tsym.Name == "SliceHeader" || tsym.Name == "StringHeader"
  1128  }
  1129  
  1130  func ParamNames(ft *types.Type) []Node {
  1131  	args := make([]Node, ft.NumParams())
  1132  	for i, f := range ft.Params() {
  1133  		args[i] = f.Nname.(*Name)
  1134  	}
  1135  	return args
  1136  }
  1137  
  1138  // MethodSym returns the method symbol representing a method name
  1139  // associated with a specific receiver type.
  1140  //
  1141  // Method symbols can be used to distinguish the same method appearing
  1142  // in different method sets. For example, T.M and (*T).M have distinct
  1143  // method symbols.
  1144  //
  1145  // The returned symbol will be marked as a function.
  1146  func MethodSym(recv *types.Type, msym *types.Sym) *types.Sym {
  1147  	sym := MethodSymSuffix(recv, msym, "")
  1148  	sym.SetFunc(true)
  1149  	return sym
  1150  }
  1151  
  1152  // MethodSymSuffix is like MethodSym, but allows attaching a
  1153  // distinguisher suffix. To avoid collisions, the suffix must not
  1154  // start with a letter, number, or period.
  1155  func MethodSymSuffix(recv *types.Type, msym *types.Sym, suffix string) *types.Sym {
  1156  	if msym.IsBlank() {
  1157  		base.Fatalf("blank method name")
  1158  	}
  1159  
  1160  	rsym := recv.Sym()
  1161  	if recv.IsPtr() {
  1162  		if rsym != nil {
  1163  			base.Fatalf("declared pointer receiver type: %v", recv)
  1164  		}
  1165  		rsym = recv.Elem().Sym()
  1166  	}
  1167  
  1168  	// Find the package the receiver type appeared in. For
  1169  	// anonymous receiver types (i.e., anonymous structs with
  1170  	// embedded fields), use the "go" pseudo-package instead.
  1171  	rpkg := Pkgs.Go
  1172  	if rsym != nil {
  1173  		rpkg = rsym.Pkg
  1174  	}
  1175  
  1176  	var b bytes.Buffer
  1177  	if recv.IsPtr() {
  1178  		// The parentheses aren't really necessary, but
  1179  		// they're pretty traditional at this point.
  1180  		fmt.Fprintf(&b, "(%-S)", recv)
  1181  	} else {
  1182  		fmt.Fprintf(&b, "%-S", recv)
  1183  	}
  1184  
  1185  	// A particular receiver type may have multiple non-exported
  1186  	// methods with the same name. To disambiguate them, include a
  1187  	// package qualifier for names that came from a different
  1188  	// package than the receiver type.
  1189  	if !types.IsExported(msym.Name) && msym.Pkg != rpkg {
  1190  		b.WriteString(".")
  1191  		b.WriteString(msym.Pkg.Prefix)
  1192  	}
  1193  
  1194  	b.WriteString(".")
  1195  	b.WriteString(msym.Name)
  1196  	b.WriteString(suffix)
  1197  	return rpkg.LookupBytes(b.Bytes())
  1198  }
  1199  
  1200  // LookupMethodSelector returns the types.Sym of the selector for a method
  1201  // named in local symbol name, as well as the types.Sym of the receiver.
  1202  //
  1203  // TODO(prattmic): this does not attempt to handle method suffixes (wrappers).
  1204  func LookupMethodSelector(pkg *types.Pkg, name string) (typ, meth *types.Sym, err error) {
  1205  	typeName, methName := splitType(name)
  1206  	if typeName == "" {
  1207  		return nil, nil, fmt.Errorf("%s doesn't contain type split", name)
  1208  	}
  1209  
  1210  	if len(typeName) > 3 && typeName[:2] == "(*" && typeName[len(typeName)-1] == ')' {
  1211  		// Symbol name is for a pointer receiver method. We just want
  1212  		// the base type name.
  1213  		typeName = typeName[2 : len(typeName)-1]
  1214  	}
  1215  
  1216  	typ = pkg.Lookup(typeName)
  1217  	meth = pkg.Selector(methName)
  1218  	return typ, meth, nil
  1219  }
  1220  
  1221  // splitType splits a local symbol name into type and method (fn). If this a
  1222  // free function, typ == "".
  1223  //
  1224  // N.B. closures and methods can be ambiguous (e.g., bar.func1). These cases
  1225  // are returned as methods.
  1226  func splitType(name string) (typ, fn string) {
  1227  	// Types are split on the first dot, ignoring everything inside
  1228  	// brackets (instantiation of type parameter, usually including
  1229  	// "go.shape").
  1230  	bracket := 0
  1231  	for i, r := range name {
  1232  		if r == '.' && bracket == 0 {
  1233  			return name[:i], name[i+1:]
  1234  		}
  1235  		if r == '[' {
  1236  			bracket++
  1237  		}
  1238  		if r == ']' {
  1239  			bracket--
  1240  		}
  1241  	}
  1242  	return "", name
  1243  }
  1244  
  1245  // MethodExprName returns the ONAME representing the method
  1246  // referenced by expression n, which must be a method selector,
  1247  // method expression, or method value.
  1248  func MethodExprName(n Node) *Name {
  1249  	name, _ := MethodExprFunc(n).Nname.(*Name)
  1250  	return name
  1251  }
  1252  
  1253  // MethodExprFunc is like MethodExprName, but returns the types.Field instead.
  1254  func MethodExprFunc(n Node) *types.Field {
  1255  	switch n.Op() {
  1256  	case ODOTMETH, OMETHEXPR, OMETHVALUE:
  1257  		return n.(*SelectorExpr).Selection
  1258  	}
  1259  	base.Fatalf("unexpected node: %v (%v)", n, n.Op())
  1260  	panic("unreachable")
  1261  }
  1262  

View as plain text