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