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