]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/compile/internal/typecheck/func.go
[dev.typeparams] all: merge master (4711bf3) into dev.typeparams
[gostls13.git] / src / cmd / compile / internal / typecheck / func.go
1 // Copyright 2009 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 typecheck
6
7 import (
8         "cmd/compile/internal/base"
9         "cmd/compile/internal/ir"
10         "cmd/compile/internal/types"
11         "cmd/internal/src"
12
13         "fmt"
14         "go/constant"
15         "go/token"
16 )
17
18 // MakeDotArgs package all the arguments that match a ... T parameter into a []T.
19 func MakeDotArgs(pos src.XPos, typ *types.Type, args []ir.Node) ir.Node {
20         var n ir.Node
21         if len(args) == 0 {
22                 n = ir.NewNilExpr(pos)
23                 n.SetType(typ)
24         } else {
25                 args = append([]ir.Node(nil), args...)
26                 lit := ir.NewCompLitExpr(pos, ir.OCOMPLIT, ir.TypeNode(typ), args)
27                 lit.SetImplicit(true)
28                 n = lit
29         }
30
31         n = Expr(n)
32         if n.Type() == nil {
33                 base.FatalfAt(pos, "mkdotargslice: typecheck failed")
34         }
35         return n
36 }
37
38 // FixVariadicCall rewrites calls to variadic functions to use an
39 // explicit ... argument if one is not already present.
40 func FixVariadicCall(call *ir.CallExpr) {
41         fntype := call.X.Type()
42         if !fntype.IsVariadic() || call.IsDDD {
43                 return
44         }
45
46         vi := fntype.NumParams() - 1
47         vt := fntype.Params().Field(vi).Type
48
49         args := call.Args
50         extra := args[vi:]
51         slice := MakeDotArgs(call.Pos(), vt, extra)
52         for i := range extra {
53                 extra[i] = nil // allow GC
54         }
55
56         call.Args = append(args[:vi], slice)
57         call.IsDDD = true
58 }
59
60 // FixMethodCall rewrites a method call t.M(...) into a function call T.M(t, ...).
61 func FixMethodCall(call *ir.CallExpr) {
62         if call.X.Op() != ir.ODOTMETH {
63                 return
64         }
65
66         dot := call.X.(*ir.SelectorExpr)
67
68         fn := Expr(ir.NewSelectorExpr(dot.Pos(), ir.OXDOT, ir.TypeNode(dot.X.Type()), dot.Selection.Sym))
69
70         args := make([]ir.Node, 1+len(call.Args))
71         args[0] = dot.X
72         copy(args[1:], call.Args)
73
74         call.SetOp(ir.OCALLFUNC)
75         call.X = fn
76         call.Args = args
77 }
78
79 // ClosureType returns the struct type used to hold all the information
80 // needed in the closure for clo (clo must be a OCLOSURE node).
81 // The address of a variable of the returned type can be cast to a func.
82 func ClosureType(clo *ir.ClosureExpr) *types.Type {
83         // Create closure in the form of a composite literal.
84         // supposing the closure captures an int i and a string s
85         // and has one float64 argument and no results,
86         // the generated code looks like:
87         //
88         //      clos = &struct{.F uintptr; i *int; s *string}{func.1, &i, &s}
89         //
90         // The use of the struct provides type information to the garbage
91         // collector so that it can walk the closure. We could use (in this case)
92         // [3]unsafe.Pointer instead, but that would leave the gc in the dark.
93         // The information appears in the binary in the form of type descriptors;
94         // the struct is unnamed so that closures in multiple packages with the
95         // same struct type can share the descriptor.
96
97         // Make sure the .F field is in the same package as the rest of the
98         // fields. This deals with closures in instantiated functions, which are
99         // compiled as if from the source package of the generic function.
100         var pkg *types.Pkg
101         if len(clo.Func.ClosureVars) == 0 {
102                 pkg = types.LocalPkg
103         } else {
104                 for _, v := range clo.Func.ClosureVars {
105                         if pkg == nil {
106                                 pkg = v.Sym().Pkg
107                         } else if pkg != v.Sym().Pkg {
108                                 base.Fatalf("Closure variables from multiple packages")
109                         }
110                 }
111         }
112
113         fields := []*types.Field{
114                 types.NewField(base.Pos, pkg.Lookup(".F"), types.Types[types.TUINTPTR]),
115         }
116         for _, v := range clo.Func.ClosureVars {
117                 typ := v.Type()
118                 if !v.Byval() {
119                         typ = types.NewPtr(typ)
120                 }
121                 fields = append(fields, types.NewField(base.Pos, v.Sym(), typ))
122         }
123         typ := types.NewStruct(types.NoPkg, fields)
124         typ.SetNoalg(true)
125         return typ
126 }
127
128 // PartialCallType returns the struct type used to hold all the information
129 // needed in the closure for n (n must be a OMETHVALUE node).
130 // The address of a variable of the returned type can be cast to a func.
131 func PartialCallType(n *ir.SelectorExpr) *types.Type {
132         t := types.NewStruct(types.NoPkg, []*types.Field{
133                 types.NewField(base.Pos, Lookup("F"), types.Types[types.TUINTPTR]),
134                 types.NewField(base.Pos, Lookup("R"), n.X.Type()),
135         })
136         t.SetNoalg(true)
137         return t
138 }
139
140 // True if we are typechecking an inline body in ImportedBody below. We use this
141 // flag to not create a new closure function in tcClosure when we are just
142 // typechecking an inline body, as opposed to the body of a real function.
143 var inTypeCheckInl bool
144
145 // ImportedBody returns immediately if the inlining information for fn is
146 // populated. Otherwise, fn must be an imported function. If so, ImportedBody
147 // loads in the dcls and body for fn, and typechecks as needed.
148 func ImportedBody(fn *ir.Func) {
149         if fn.Inl.Body != nil {
150                 return
151         }
152         lno := ir.SetPos(fn.Nname)
153
154         // When we load an inlined body, we need to allow OADDR
155         // operations on untyped expressions. We will fix the
156         // addrtaken flags on all the arguments of the OADDR with the
157         // computeAddrtaken call below (after we typecheck the body).
158         // TODO: export/import types and addrtaken marks along with inlined bodies,
159         // so this will be unnecessary.
160         IncrementalAddrtaken = false
161         defer func() {
162                 if DirtyAddrtaken {
163                         ComputeAddrtaken(fn.Inl.Body) // compute addrtaken marks once types are available
164                         DirtyAddrtaken = false
165                 }
166                 IncrementalAddrtaken = true
167         }()
168
169         ImportBody(fn)
170
171         // Stmts(fn.Inl.Body) below is only for imported functions;
172         // their bodies may refer to unsafe as long as the package
173         // was marked safe during import (which was checked then).
174         // the ->inl of a local function has been typechecked before CanInline copied it.
175         pkg := fnpkg(fn.Nname)
176
177         if pkg == types.LocalPkg || pkg == nil {
178                 return // ImportedBody on local function
179         }
180
181         if base.Flag.LowerM > 2 || base.Debug.Export != 0 {
182                 fmt.Printf("typecheck import [%v] %L { %v }\n", fn.Sym(), fn, ir.Nodes(fn.Inl.Body))
183         }
184
185         if !go117ExportTypes {
186                 // If we didn't export & import types, typecheck the code here.
187                 savefn := ir.CurFunc
188                 ir.CurFunc = fn
189                 if inTypeCheckInl {
190                         base.Fatalf("inTypeCheckInl should not be set recursively")
191                 }
192                 inTypeCheckInl = true
193                 Stmts(fn.Inl.Body)
194                 inTypeCheckInl = false
195                 ir.CurFunc = savefn
196         }
197
198         base.Pos = lno
199 }
200
201 // Get the function's package. For ordinary functions it's on the ->sym, but for imported methods
202 // the ->sym can be re-used in the local package, so peel it off the receiver's type.
203 func fnpkg(fn *ir.Name) *types.Pkg {
204         if ir.IsMethod(fn) {
205                 // method
206                 rcvr := fn.Type().Recv().Type
207
208                 if rcvr.IsPtr() {
209                         rcvr = rcvr.Elem()
210                 }
211                 if rcvr.Sym() == nil {
212                         base.Fatalf("receiver with no sym: [%v] %L  (%v)", fn.Sym(), fn, rcvr)
213                 }
214                 return rcvr.Sym().Pkg
215         }
216
217         // non-method
218         return fn.Sym().Pkg
219 }
220
221 // tcClosure typechecks an OCLOSURE node. It also creates the named
222 // function associated with the closure.
223 // TODO: This creation of the named function should probably really be done in a
224 // separate pass from type-checking.
225 func tcClosure(clo *ir.ClosureExpr, top int) ir.Node {
226         fn := clo.Func
227
228         // We used to allow IR builders to typecheck the underlying Func
229         // themselves, but that led to too much variety and inconsistency
230         // around who's responsible for naming the function, typechecking
231         // it, or adding it to Target.Decls.
232         //
233         // It's now all or nothing. Callers are still allowed to do these
234         // themselves, but then they assume responsibility for all of them.
235         if fn.Typecheck() == 1 {
236                 base.FatalfAt(fn.Pos(), "underlying closure func already typechecked: %v", fn)
237         }
238
239         // Set current associated iota value, so iota can be used inside
240         // function in ConstSpec, see issue #22344
241         if x := getIotaValue(); x >= 0 {
242                 fn.Iota = x
243         }
244
245         fn.SetClosureCalled(top&ctxCallee != 0)
246
247         ir.NameClosure(clo, ir.CurFunc)
248         Func(fn)
249
250         // Type check the body now, but only if we're inside a function.
251         // At top level (in a variable initialization: curfn==nil) we're not
252         // ready to type check code yet; we'll check it later, because the
253         // underlying closure function we create is added to Target.Decls.
254         if ir.CurFunc != nil {
255                 oldfn := ir.CurFunc
256                 ir.CurFunc = fn
257                 Stmts(fn.Body)
258                 ir.CurFunc = oldfn
259         }
260
261         out := 0
262         for _, v := range fn.ClosureVars {
263                 if v.Type() == nil {
264                         // If v.Type is nil, it means v looked like it was going to be
265                         // used in the closure, but isn't. This happens in struct
266                         // literals like s{f: x} where we can't distinguish whether f is
267                         // a field identifier or expression until resolving s.
268                         continue
269                 }
270
271                 // type check closed variables outside the closure, so that the
272                 // outer frame also captures them.
273                 Expr(v.Outer)
274
275                 fn.ClosureVars[out] = v
276                 out++
277         }
278         fn.ClosureVars = fn.ClosureVars[:out]
279
280         clo.SetType(fn.Type())
281
282         target := Target
283         if inTypeCheckInl {
284                 // We're typechecking an imported function, so it's not actually
285                 // part of Target. Skip adding it to Target.Decls so we don't
286                 // compile it again.
287                 target = nil
288         }
289
290         return ir.UseClosure(clo, target)
291 }
292
293 // type check function definition
294 // To be called by typecheck, not directly.
295 // (Call typecheck.Func instead.)
296 func tcFunc(n *ir.Func) {
297         if base.EnableTrace && base.Flag.LowerT {
298                 defer tracePrint("tcFunc", n)(nil)
299         }
300
301         n.Nname = AssignExpr(n.Nname).(*ir.Name)
302         t := n.Nname.Type()
303         if t == nil {
304                 return
305         }
306         rcvr := t.Recv()
307         if rcvr != nil && n.Shortname != nil {
308                 m := addmethod(n, n.Shortname, t, true, n.Pragma&ir.Nointerface != 0)
309                 if m == nil {
310                         return
311                 }
312
313                 n.Nname.SetSym(ir.MethodSym(rcvr.Type, n.Shortname))
314                 Declare(n.Nname, ir.PFUNC)
315         }
316 }
317
318 // tcCall typechecks an OCALL node.
319 func tcCall(n *ir.CallExpr, top int) ir.Node {
320         n.Use = ir.CallUseExpr
321         if top == ctxStmt {
322                 n.Use = ir.CallUseStmt
323         }
324         Stmts(n.Init()) // imported rewritten f(g()) calls (#30907)
325         n.X = typecheck(n.X, ctxExpr|ctxType|ctxCallee)
326         if n.X.Diag() {
327                 n.SetDiag(true)
328         }
329
330         l := n.X
331
332         if l.Op() == ir.ONAME && l.(*ir.Name).BuiltinOp != 0 {
333                 l := l.(*ir.Name)
334                 if n.IsDDD && l.BuiltinOp != ir.OAPPEND {
335                         base.Errorf("invalid use of ... with builtin %v", l)
336                 }
337
338                 // builtin: OLEN, OCAP, etc.
339                 switch l.BuiltinOp {
340                 default:
341                         base.Fatalf("unknown builtin %v", l)
342
343                 case ir.OAPPEND, ir.ODELETE, ir.OMAKE, ir.OPRINT, ir.OPRINTN, ir.ORECOVER:
344                         n.SetOp(l.BuiltinOp)
345                         n.X = nil
346                         n.SetTypecheck(0) // re-typechecking new op is OK, not a loop
347                         return typecheck(n, top)
348
349                 case ir.OCAP, ir.OCLOSE, ir.OIMAG, ir.OLEN, ir.OPANIC, ir.OREAL:
350                         typecheckargs(n)
351                         fallthrough
352                 case ir.ONEW, ir.OALIGNOF, ir.OOFFSETOF, ir.OSIZEOF:
353                         arg, ok := needOneArg(n, "%v", n.Op())
354                         if !ok {
355                                 n.SetType(nil)
356                                 return n
357                         }
358                         u := ir.NewUnaryExpr(n.Pos(), l.BuiltinOp, arg)
359                         return typecheck(ir.InitExpr(n.Init(), u), top) // typecheckargs can add to old.Init
360
361                 case ir.OCOMPLEX, ir.OCOPY, ir.OUNSAFEADD, ir.OUNSAFESLICE:
362                         typecheckargs(n)
363                         arg1, arg2, ok := needTwoArgs(n)
364                         if !ok {
365                                 n.SetType(nil)
366                                 return n
367                         }
368                         b := ir.NewBinaryExpr(n.Pos(), l.BuiltinOp, arg1, arg2)
369                         return typecheck(ir.InitExpr(n.Init(), b), top) // typecheckargs can add to old.Init
370                 }
371                 panic("unreachable")
372         }
373
374         n.X = DefaultLit(n.X, nil)
375         l = n.X
376         if l.Op() == ir.OTYPE {
377                 if n.IsDDD {
378                         if !l.Type().Broke() {
379                                 base.Errorf("invalid use of ... in type conversion to %v", l.Type())
380                         }
381                         n.SetDiag(true)
382                 }
383
384                 // pick off before type-checking arguments
385                 arg, ok := needOneArg(n, "conversion to %v", l.Type())
386                 if !ok {
387                         n.SetType(nil)
388                         return n
389                 }
390
391                 n := ir.NewConvExpr(n.Pos(), ir.OCONV, nil, arg)
392                 n.SetType(l.Type())
393                 return tcConv(n)
394         }
395
396         typecheckargs(n)
397         t := l.Type()
398         if t == nil {
399                 n.SetType(nil)
400                 return n
401         }
402         types.CheckSize(t)
403
404         switch l.Op() {
405         case ir.ODOTINTER:
406                 n.SetOp(ir.OCALLINTER)
407
408         case ir.ODOTMETH:
409                 l := l.(*ir.SelectorExpr)
410                 n.SetOp(ir.OCALLMETH)
411
412                 // typecheckaste was used here but there wasn't enough
413                 // information further down the call chain to know if we
414                 // were testing a method receiver for unexported fields.
415                 // It isn't necessary, so just do a sanity check.
416                 tp := t.Recv().Type
417
418                 if l.X == nil || !types.Identical(l.X.Type(), tp) {
419                         base.Fatalf("method receiver")
420                 }
421
422         default:
423                 n.SetOp(ir.OCALLFUNC)
424                 if t.Kind() != types.TFUNC {
425                         if o := ir.Orig(l); o.Name() != nil && types.BuiltinPkg.Lookup(o.Sym().Name).Def != nil {
426                                 // be more specific when the non-function
427                                 // name matches a predeclared function
428                                 base.Errorf("cannot call non-function %L, declared at %s",
429                                         l, base.FmtPos(o.Name().Pos()))
430                         } else {
431                                 base.Errorf("cannot call non-function %L", l)
432                         }
433                         n.SetType(nil)
434                         return n
435                 }
436         }
437
438         typecheckaste(ir.OCALL, n.X, n.IsDDD, t.Params(), n.Args, func() string { return fmt.Sprintf("argument to %v", n.X) })
439         FixMethodCall(n)
440         if t.NumResults() == 0 {
441                 return n
442         }
443         if t.NumResults() == 1 {
444                 n.SetType(l.Type().Results().Field(0).Type)
445
446                 if n.Op() == ir.OCALLFUNC && n.X.Op() == ir.ONAME {
447                         if sym := n.X.(*ir.Name).Sym(); types.IsRuntimePkg(sym.Pkg) && sym.Name == "getg" {
448                                 // Emit code for runtime.getg() directly instead of calling function.
449                                 // Most such rewrites (for example the similar one for math.Sqrt) should be done in walk,
450                                 // so that the ordering pass can make sure to preserve the semantics of the original code
451                                 // (in particular, the exact time of the function call) by introducing temporaries.
452                                 // In this case, we know getg() always returns the same result within a given function
453                                 // and we want to avoid the temporaries, so we do the rewrite earlier than is typical.
454                                 n.SetOp(ir.OGETG)
455                         }
456                 }
457                 return n
458         }
459
460         // multiple return
461         if top&(ctxMultiOK|ctxStmt) == 0 {
462                 base.Errorf("multiple-value %v() in single-value context", l)
463                 return n
464         }
465
466         n.SetType(l.Type().Results())
467         return n
468 }
469
470 // tcAppend typechecks an OAPPEND node.
471 func tcAppend(n *ir.CallExpr) ir.Node {
472         typecheckargs(n)
473         args := n.Args
474         if len(args) == 0 {
475                 base.Errorf("missing arguments to append")
476                 n.SetType(nil)
477                 return n
478         }
479
480         t := args[0].Type()
481         if t == nil {
482                 n.SetType(nil)
483                 return n
484         }
485
486         n.SetType(t)
487         if !t.IsSlice() {
488                 if ir.IsNil(args[0]) {
489                         base.Errorf("first argument to append must be typed slice; have untyped nil")
490                         n.SetType(nil)
491                         return n
492                 }
493
494                 base.Errorf("first argument to append must be slice; have %L", t)
495                 n.SetType(nil)
496                 return n
497         }
498
499         if n.IsDDD {
500                 if len(args) == 1 {
501                         base.Errorf("cannot use ... on first argument to append")
502                         n.SetType(nil)
503                         return n
504                 }
505
506                 if len(args) != 2 {
507                         base.Errorf("too many arguments to append")
508                         n.SetType(nil)
509                         return n
510                 }
511
512                 if t.Elem().IsKind(types.TUINT8) && args[1].Type().IsString() {
513                         args[1] = DefaultLit(args[1], types.Types[types.TSTRING])
514                         return n
515                 }
516
517                 args[1] = AssignConv(args[1], t.Underlying(), "append")
518                 return n
519         }
520
521         as := args[1:]
522         for i, n := range as {
523                 if n.Type() == nil {
524                         continue
525                 }
526                 as[i] = AssignConv(n, t.Elem(), "append")
527                 types.CheckSize(as[i].Type()) // ensure width is calculated for backend
528         }
529         return n
530 }
531
532 // tcClose typechecks an OCLOSE node.
533 func tcClose(n *ir.UnaryExpr) ir.Node {
534         n.X = Expr(n.X)
535         n.X = DefaultLit(n.X, nil)
536         l := n.X
537         t := l.Type()
538         if t == nil {
539                 n.SetType(nil)
540                 return n
541         }
542         if !t.IsChan() {
543                 base.Errorf("invalid operation: %v (non-chan type %v)", n, t)
544                 n.SetType(nil)
545                 return n
546         }
547
548         if !t.ChanDir().CanSend() {
549                 base.Errorf("invalid operation: %v (cannot close receive-only channel)", n)
550                 n.SetType(nil)
551                 return n
552         }
553         return n
554 }
555
556 // tcComplex typechecks an OCOMPLEX node.
557 func tcComplex(n *ir.BinaryExpr) ir.Node {
558         l := Expr(n.X)
559         r := Expr(n.Y)
560         if l.Type() == nil || r.Type() == nil {
561                 n.SetType(nil)
562                 return n
563         }
564         l, r = defaultlit2(l, r, false)
565         if l.Type() == nil || r.Type() == nil {
566                 n.SetType(nil)
567                 return n
568         }
569         n.X = l
570         n.Y = r
571
572         if !types.Identical(l.Type(), r.Type()) {
573                 base.Errorf("invalid operation: %v (mismatched types %v and %v)", n, l.Type(), r.Type())
574                 n.SetType(nil)
575                 return n
576         }
577
578         var t *types.Type
579         switch l.Type().Kind() {
580         default:
581                 base.Errorf("invalid operation: %v (arguments have type %v, expected floating-point)", n, l.Type())
582                 n.SetType(nil)
583                 return n
584
585         case types.TIDEAL:
586                 t = types.UntypedComplex
587
588         case types.TFLOAT32:
589                 t = types.Types[types.TCOMPLEX64]
590
591         case types.TFLOAT64:
592                 t = types.Types[types.TCOMPLEX128]
593         }
594         n.SetType(t)
595         return n
596 }
597
598 // tcCopy typechecks an OCOPY node.
599 func tcCopy(n *ir.BinaryExpr) ir.Node {
600         n.SetType(types.Types[types.TINT])
601         n.X = Expr(n.X)
602         n.X = DefaultLit(n.X, nil)
603         n.Y = Expr(n.Y)
604         n.Y = DefaultLit(n.Y, nil)
605         if n.X.Type() == nil || n.Y.Type() == nil {
606                 n.SetType(nil)
607                 return n
608         }
609
610         // copy([]byte, string)
611         if n.X.Type().IsSlice() && n.Y.Type().IsString() {
612                 if types.Identical(n.X.Type().Elem(), types.ByteType) {
613                         return n
614                 }
615                 base.Errorf("arguments to copy have different element types: %L and string", n.X.Type())
616                 n.SetType(nil)
617                 return n
618         }
619
620         if !n.X.Type().IsSlice() || !n.Y.Type().IsSlice() {
621                 if !n.X.Type().IsSlice() && !n.Y.Type().IsSlice() {
622                         base.Errorf("arguments to copy must be slices; have %L, %L", n.X.Type(), n.Y.Type())
623                 } else if !n.X.Type().IsSlice() {
624                         base.Errorf("first argument to copy should be slice; have %L", n.X.Type())
625                 } else {
626                         base.Errorf("second argument to copy should be slice or string; have %L", n.Y.Type())
627                 }
628                 n.SetType(nil)
629                 return n
630         }
631
632         if !types.Identical(n.X.Type().Elem(), n.Y.Type().Elem()) {
633                 base.Errorf("arguments to copy have different element types: %L and %L", n.X.Type(), n.Y.Type())
634                 n.SetType(nil)
635                 return n
636         }
637         return n
638 }
639
640 // tcDelete typechecks an ODELETE node.
641 func tcDelete(n *ir.CallExpr) ir.Node {
642         typecheckargs(n)
643         args := n.Args
644         if len(args) == 0 {
645                 base.Errorf("missing arguments to delete")
646                 n.SetType(nil)
647                 return n
648         }
649
650         if len(args) == 1 {
651                 base.Errorf("missing second (key) argument to delete")
652                 n.SetType(nil)
653                 return n
654         }
655
656         if len(args) != 2 {
657                 base.Errorf("too many arguments to delete")
658                 n.SetType(nil)
659                 return n
660         }
661
662         l := args[0]
663         r := args[1]
664         if l.Type() != nil && !l.Type().IsMap() {
665                 base.Errorf("first argument to delete must be map; have %L", l.Type())
666                 n.SetType(nil)
667                 return n
668         }
669
670         args[1] = AssignConv(r, l.Type().Key(), "delete")
671         return n
672 }
673
674 // tcMake typechecks an OMAKE node.
675 func tcMake(n *ir.CallExpr) ir.Node {
676         args := n.Args
677         if len(args) == 0 {
678                 base.Errorf("missing argument to make")
679                 n.SetType(nil)
680                 return n
681         }
682
683         n.Args = nil
684         l := args[0]
685         l = typecheck(l, ctxType)
686         t := l.Type()
687         if t == nil {
688                 n.SetType(nil)
689                 return n
690         }
691
692         i := 1
693         var nn ir.Node
694         switch t.Kind() {
695         default:
696                 base.Errorf("cannot make type %v", t)
697                 n.SetType(nil)
698                 return n
699
700         case types.TSLICE:
701                 if i >= len(args) {
702                         base.Errorf("missing len argument to make(%v)", t)
703                         n.SetType(nil)
704                         return n
705                 }
706
707                 l = args[i]
708                 i++
709                 l = Expr(l)
710                 var r ir.Node
711                 if i < len(args) {
712                         r = args[i]
713                         i++
714                         r = Expr(r)
715                 }
716
717                 if l.Type() == nil || (r != nil && r.Type() == nil) {
718                         n.SetType(nil)
719                         return n
720                 }
721                 if !checkmake(t, "len", &l) || r != nil && !checkmake(t, "cap", &r) {
722                         n.SetType(nil)
723                         return n
724                 }
725                 if ir.IsConst(l, constant.Int) && r != nil && ir.IsConst(r, constant.Int) && constant.Compare(l.Val(), token.GTR, r.Val()) {
726                         base.Errorf("len larger than cap in make(%v)", t)
727                         n.SetType(nil)
728                         return n
729                 }
730                 nn = ir.NewMakeExpr(n.Pos(), ir.OMAKESLICE, l, r)
731
732         case types.TMAP:
733                 if i < len(args) {
734                         l = args[i]
735                         i++
736                         l = Expr(l)
737                         l = DefaultLit(l, types.Types[types.TINT])
738                         if l.Type() == nil {
739                                 n.SetType(nil)
740                                 return n
741                         }
742                         if !checkmake(t, "size", &l) {
743                                 n.SetType(nil)
744                                 return n
745                         }
746                 } else {
747                         l = ir.NewInt(0)
748                 }
749                 nn = ir.NewMakeExpr(n.Pos(), ir.OMAKEMAP, l, nil)
750                 nn.SetEsc(n.Esc())
751
752         case types.TCHAN:
753                 l = nil
754                 if i < len(args) {
755                         l = args[i]
756                         i++
757                         l = Expr(l)
758                         l = DefaultLit(l, types.Types[types.TINT])
759                         if l.Type() == nil {
760                                 n.SetType(nil)
761                                 return n
762                         }
763                         if !checkmake(t, "buffer", &l) {
764                                 n.SetType(nil)
765                                 return n
766                         }
767                 } else {
768                         l = ir.NewInt(0)
769                 }
770                 nn = ir.NewMakeExpr(n.Pos(), ir.OMAKECHAN, l, nil)
771         }
772
773         if i < len(args) {
774                 base.Errorf("too many arguments to make(%v)", t)
775                 n.SetType(nil)
776                 return n
777         }
778
779         nn.SetType(t)
780         return nn
781 }
782
783 // tcMakeSliceCopy typechecks an OMAKESLICECOPY node.
784 func tcMakeSliceCopy(n *ir.MakeExpr) ir.Node {
785         // Errors here are Fatalf instead of Errorf because only the compiler
786         // can construct an OMAKESLICECOPY node.
787         // Components used in OMAKESCLICECOPY that are supplied by parsed source code
788         // have already been typechecked in OMAKE and OCOPY earlier.
789         t := n.Type()
790
791         if t == nil {
792                 base.Fatalf("no type specified for OMAKESLICECOPY")
793         }
794
795         if !t.IsSlice() {
796                 base.Fatalf("invalid type %v for OMAKESLICECOPY", n.Type())
797         }
798
799         if n.Len == nil {
800                 base.Fatalf("missing len argument for OMAKESLICECOPY")
801         }
802
803         if n.Cap == nil {
804                 base.Fatalf("missing slice argument to copy for OMAKESLICECOPY")
805         }
806
807         n.Len = Expr(n.Len)
808         n.Cap = Expr(n.Cap)
809
810         n.Len = DefaultLit(n.Len, types.Types[types.TINT])
811
812         if !n.Len.Type().IsInteger() && n.Type().Kind() != types.TIDEAL {
813                 base.Errorf("non-integer len argument in OMAKESLICECOPY")
814         }
815
816         if ir.IsConst(n.Len, constant.Int) {
817                 if ir.ConstOverflow(n.Len.Val(), types.Types[types.TINT]) {
818                         base.Fatalf("len for OMAKESLICECOPY too large")
819                 }
820                 if constant.Sign(n.Len.Val()) < 0 {
821                         base.Fatalf("len for OMAKESLICECOPY must be non-negative")
822                 }
823         }
824         return n
825 }
826
827 // tcNew typechecks an ONEW node.
828 func tcNew(n *ir.UnaryExpr) ir.Node {
829         if n.X == nil {
830                 // Fatalf because the OCALL above checked for us,
831                 // so this must be an internally-generated mistake.
832                 base.Fatalf("missing argument to new")
833         }
834         l := n.X
835         l = typecheck(l, ctxType)
836         t := l.Type()
837         if t == nil {
838                 n.SetType(nil)
839                 return n
840         }
841         n.X = l
842         n.SetType(types.NewPtr(t))
843         return n
844 }
845
846 // tcPanic typechecks an OPANIC node.
847 func tcPanic(n *ir.UnaryExpr) ir.Node {
848         n.X = Expr(n.X)
849         n.X = AssignConv(n.X, types.Types[types.TINTER], "argument to panic")
850         if n.X.Type() == nil {
851                 n.SetType(nil)
852                 return n
853         }
854         return n
855 }
856
857 // tcPrint typechecks an OPRINT or OPRINTN node.
858 func tcPrint(n *ir.CallExpr) ir.Node {
859         typecheckargs(n)
860         ls := n.Args
861         for i1, n1 := range ls {
862                 // Special case for print: int constant is int64, not int.
863                 if ir.IsConst(n1, constant.Int) {
864                         ls[i1] = DefaultLit(ls[i1], types.Types[types.TINT64])
865                 } else {
866                         ls[i1] = DefaultLit(ls[i1], nil)
867                 }
868         }
869         return n
870 }
871
872 // tcRealImag typechecks an OREAL or OIMAG node.
873 func tcRealImag(n *ir.UnaryExpr) ir.Node {
874         n.X = Expr(n.X)
875         l := n.X
876         t := l.Type()
877         if t == nil {
878                 n.SetType(nil)
879                 return n
880         }
881
882         // Determine result type.
883         switch t.Kind() {
884         case types.TIDEAL:
885                 n.SetType(types.UntypedFloat)
886         case types.TCOMPLEX64:
887                 n.SetType(types.Types[types.TFLOAT32])
888         case types.TCOMPLEX128:
889                 n.SetType(types.Types[types.TFLOAT64])
890         default:
891                 base.Errorf("invalid argument %L for %v", l, n.Op())
892                 n.SetType(nil)
893                 return n
894         }
895         return n
896 }
897
898 // tcRecover typechecks an ORECOVER node.
899 func tcRecover(n *ir.CallExpr) ir.Node {
900         if len(n.Args) != 0 {
901                 base.Errorf("too many arguments to recover")
902                 n.SetType(nil)
903                 return n
904         }
905
906         n.SetType(types.Types[types.TINTER])
907         return n
908 }
909
910 // tcRecoverFP typechecks an ORECOVERFP node.
911 func tcRecoverFP(n *ir.CallExpr) ir.Node {
912         if len(n.Args) != 1 {
913                 base.FatalfAt(n.Pos(), "wrong number of arguments: %v", n)
914         }
915
916         n.Args[0] = Expr(n.Args[0])
917         if !n.Args[0].Type().IsPtrShaped() {
918                 base.FatalfAt(n.Pos(), "%L is not pointer shaped", n.Args[0])
919         }
920
921         n.SetType(types.Types[types.TINTER])
922         return n
923 }
924
925 // tcUnsafeAdd typechecks an OUNSAFEADD node.
926 func tcUnsafeAdd(n *ir.BinaryExpr) *ir.BinaryExpr {
927         if !types.AllowsGoVersion(curpkg(), 1, 17) {
928                 base.ErrorfVers("go1.17", "unsafe.Add")
929                 n.SetType(nil)
930                 return n
931         }
932
933         n.X = AssignConv(Expr(n.X), types.Types[types.TUNSAFEPTR], "argument to unsafe.Add")
934         n.Y = DefaultLit(Expr(n.Y), types.Types[types.TINT])
935         if n.X.Type() == nil || n.Y.Type() == nil {
936                 n.SetType(nil)
937                 return n
938         }
939         if !n.Y.Type().IsInteger() {
940                 n.SetType(nil)
941                 return n
942         }
943         n.SetType(n.X.Type())
944         return n
945 }
946
947 // tcUnsafeSlice typechecks an OUNSAFESLICE node.
948 func tcUnsafeSlice(n *ir.BinaryExpr) *ir.BinaryExpr {
949         if !types.AllowsGoVersion(curpkg(), 1, 17) {
950                 base.ErrorfVers("go1.17", "unsafe.Slice")
951                 n.SetType(nil)
952                 return n
953         }
954
955         n.X = Expr(n.X)
956         n.Y = Expr(n.Y)
957         if n.X.Type() == nil || n.Y.Type() == nil {
958                 n.SetType(nil)
959                 return n
960         }
961         t := n.X.Type()
962         if !t.IsPtr() {
963                 base.Errorf("first argument to unsafe.Slice must be pointer; have %L", t)
964         } else if t.Elem().NotInHeap() {
965                 // TODO(mdempsky): This can be relaxed, but should only affect the
966                 // Go runtime itself. End users should only see //go:notinheap
967                 // types due to incomplete C structs in cgo, and those types don't
968                 // have a meaningful size anyway.
969                 base.Errorf("unsafe.Slice of incomplete (or unallocatable) type not allowed")
970         }
971
972         if !checkunsafeslice(&n.Y) {
973                 n.SetType(nil)
974                 return n
975         }
976         n.SetType(types.NewSlice(t.Elem()))
977         return n
978 }