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 "fmt" 9 "go/constant" 10 "go/token" 11 "strings" 12 13 "cmd/compile/internal/base" 14 "cmd/compile/internal/ir" 15 "cmd/compile/internal/types" 16 "cmd/internal/src" 17) 18 19// Function collecting autotmps generated during typechecking, 20// to be included in the package-level init function. 21var InitTodoFunc = ir.NewFunc(base.Pos) 22 23var inimport bool // set during import 24 25var TypecheckAllowed bool 26 27var ( 28 NeedRuntimeType = func(*types.Type) {} 29) 30 31func AssignExpr(n ir.Node) ir.Node { return typecheck(n, ctxExpr|ctxAssign) } 32func Expr(n ir.Node) ir.Node { return typecheck(n, ctxExpr) } 33func Stmt(n ir.Node) ir.Node { return typecheck(n, ctxStmt) } 34 35func Exprs(exprs []ir.Node) { typecheckslice(exprs, ctxExpr) } 36func Stmts(stmts []ir.Node) { typecheckslice(stmts, ctxStmt) } 37 38func Call(pos src.XPos, callee ir.Node, args []ir.Node, dots bool) ir.Node { 39 call := ir.NewCallExpr(pos, ir.OCALL, callee, args) 40 call.IsDDD = dots 41 return typecheck(call, ctxStmt|ctxExpr) 42} 43 44func Callee(n ir.Node) ir.Node { 45 return typecheck(n, ctxExpr|ctxCallee) 46} 47 48func FuncBody(n *ir.Func) { 49 ir.CurFunc = n 50 errorsBefore := base.Errors() 51 Stmts(n.Body) 52 CheckUnused(n) 53 CheckReturn(n) 54 if ir.IsBlank(n.Nname) || base.Errors() > errorsBefore { 55 n.Body = nil // blank function or type errors; do not compile 56 } 57} 58 59var importlist []*ir.Func 60 61// AllImportedBodies reads in the bodies of all imported functions and typechecks 62// them, if needed. 63func AllImportedBodies() { 64 for _, n := range importlist { 65 if n.Inl != nil { 66 ImportedBody(n) 67 } 68 } 69} 70 71var traceIndent []byte 72 73func tracePrint(title string, n ir.Node) func(np *ir.Node) { 74 indent := traceIndent 75 76 // guard against nil 77 var pos, op string 78 var tc uint8 79 if n != nil { 80 pos = base.FmtPos(n.Pos()) 81 op = n.Op().String() 82 tc = n.Typecheck() 83 } 84 85 types.SkipSizeForTracing = true 86 defer func() { types.SkipSizeForTracing = false }() 87 fmt.Printf("%s: %s%s %p %s %v tc=%d\n", pos, indent, title, n, op, n, tc) 88 traceIndent = append(traceIndent, ". "...) 89 90 return func(np *ir.Node) { 91 traceIndent = traceIndent[:len(traceIndent)-2] 92 93 // if we have a result, use that 94 if np != nil { 95 n = *np 96 } 97 98 // guard against nil 99 // use outer pos, op so we don't get empty pos/op if n == nil (nicer output) 100 var tc uint8 101 var typ *types.Type 102 if n != nil { 103 pos = base.FmtPos(n.Pos()) 104 op = n.Op().String() 105 tc = n.Typecheck() 106 typ = n.Type() 107 } 108 109 types.SkipSizeForTracing = true 110 defer func() { types.SkipSizeForTracing = false }() 111 fmt.Printf("%s: %s=> %p %s %v tc=%d type=%L\n", pos, indent, n, op, n, tc, typ) 112 } 113} 114 115const ( 116 ctxStmt = 1 << iota // evaluated at statement level 117 ctxExpr // evaluated in value context 118 ctxType // evaluated in type context 119 ctxCallee // call-only expressions are ok 120 ctxMultiOK // multivalue function returns are ok 121 ctxAssign // assigning to expression 122) 123 124// type checks the whole tree of an expression. 125// calculates expression types. 126// evaluates compile time constants. 127// marks variables that escape the local frame. 128// rewrites n.Op to be more specific in some cases. 129 130var typecheckdefstack []*ir.Name 131 132// Resolve ONONAME to definition, if any. 133func Resolve(n ir.Node) (res ir.Node) { 134 if n == nil || n.Op() != ir.ONONAME { 135 return n 136 } 137 138 // only trace if there's work to do 139 if base.EnableTrace && base.Flag.LowerT { 140 defer tracePrint("resolve", n)(&res) 141 } 142 143 if sym := n.Sym(); sym.Pkg != types.LocalPkg { 144 // We might have an ir.Ident from oldname or importDot. 145 if id, ok := n.(*ir.Ident); ok { 146 if pkgName := DotImportRefs[id]; pkgName != nil { 147 pkgName.Used = true 148 } 149 } 150 151 return expandDecl(n) 152 } 153 154 r := ir.AsNode(n.Sym().Def) 155 if r == nil { 156 return n 157 } 158 159 if r.Op() == ir.OIOTA { 160 if x := getIotaValue(); x >= 0 { 161 return ir.NewInt(x) 162 } 163 return n 164 } 165 166 return r 167} 168 169func typecheckslice(l []ir.Node, top int) { 170 for i := range l { 171 l[i] = typecheck(l[i], top) 172 } 173} 174 175var _typekind = []string{ 176 types.TINT: "int", 177 types.TUINT: "uint", 178 types.TINT8: "int8", 179 types.TUINT8: "uint8", 180 types.TINT16: "int16", 181 types.TUINT16: "uint16", 182 types.TINT32: "int32", 183 types.TUINT32: "uint32", 184 types.TINT64: "int64", 185 types.TUINT64: "uint64", 186 types.TUINTPTR: "uintptr", 187 types.TCOMPLEX64: "complex64", 188 types.TCOMPLEX128: "complex128", 189 types.TFLOAT32: "float32", 190 types.TFLOAT64: "float64", 191 types.TBOOL: "bool", 192 types.TSTRING: "string", 193 types.TPTR: "pointer", 194 types.TUNSAFEPTR: "unsafe.Pointer", 195 types.TSTRUCT: "struct", 196 types.TINTER: "interface", 197 types.TCHAN: "chan", 198 types.TMAP: "map", 199 types.TARRAY: "array", 200 types.TSLICE: "slice", 201 types.TFUNC: "func", 202 types.TNIL: "nil", 203 types.TIDEAL: "untyped number", 204} 205 206func typekind(t *types.Type) string { 207 if t.IsUntyped() { 208 return fmt.Sprintf("%v", t) 209 } 210 et := t.Kind() 211 if int(et) < len(_typekind) { 212 s := _typekind[et] 213 if s != "" { 214 return s 215 } 216 } 217 return fmt.Sprintf("etype=%d", et) 218} 219 220func cycleFor(start ir.Node) []ir.Node { 221 // Find the start node in typecheck_tcstack. 222 // We know that it must exist because each time we mark 223 // a node with n.SetTypecheck(2) we push it on the stack, 224 // and each time we mark a node with n.SetTypecheck(2) we 225 // pop it from the stack. We hit a cycle when we encounter 226 // a node marked 2 in which case is must be on the stack. 227 i := len(typecheck_tcstack) - 1 228 for i > 0 && typecheck_tcstack[i] != start { 229 i-- 230 } 231 232 // collect all nodes with same Op 233 var cycle []ir.Node 234 for _, n := range typecheck_tcstack[i:] { 235 if n.Op() == start.Op() { 236 cycle = append(cycle, n) 237 } 238 } 239 240 return cycle 241} 242 243func cycleTrace(cycle []ir.Node) string { 244 var s string 245 for i, n := range cycle { 246 s += fmt.Sprintf("\n\t%v: %v uses %v", ir.Line(n), n, cycle[(i+1)%len(cycle)]) 247 } 248 return s 249} 250 251var typecheck_tcstack []ir.Node 252 253func Func(fn *ir.Func) { 254 new := Stmt(fn) 255 if new != fn { 256 base.Fatalf("typecheck changed func") 257 } 258} 259 260func typecheckNtype(n ir.Ntype) ir.Ntype { 261 return typecheck(n, ctxType).(ir.Ntype) 262} 263 264// typecheck type checks node n. 265// The result of typecheck MUST be assigned back to n, e.g. 266// n.Left = typecheck(n.Left, top) 267func typecheck(n ir.Node, top int) (res ir.Node) { 268 // cannot type check until all the source has been parsed 269 if !TypecheckAllowed { 270 base.Fatalf("early typecheck") 271 } 272 273 if n == nil { 274 return nil 275 } 276 277 // only trace if there's work to do 278 if base.EnableTrace && base.Flag.LowerT { 279 defer tracePrint("typecheck", n)(&res) 280 } 281 282 lno := ir.SetPos(n) 283 284 // Skip over parens. 285 for n.Op() == ir.OPAREN { 286 n = n.(*ir.ParenExpr).X 287 } 288 289 // Resolve definition of name and value of iota lazily. 290 n = Resolve(n) 291 292 // Skip typecheck if already done. 293 // But re-typecheck ONAME/OTYPE/OLITERAL/OPACK node in case context has changed. 294 if n.Typecheck() == 1 || n.Typecheck() == 3 { 295 switch n.Op() { 296 case ir.ONAME, ir.OTYPE, ir.OLITERAL, ir.OPACK: 297 break 298 299 default: 300 base.Pos = lno 301 return n 302 } 303 } 304 305 if n.Typecheck() == 2 { 306 // Typechecking loop. Trying printing a meaningful message, 307 // otherwise a stack trace of typechecking. 308 switch n.Op() { 309 // We can already diagnose variables used as types. 310 case ir.ONAME: 311 n := n.(*ir.Name) 312 if top&(ctxExpr|ctxType) == ctxType { 313 base.Errorf("%v is not a type", n) 314 } 315 316 case ir.OTYPE: 317 // Only report a type cycle if we are expecting a type. 318 // Otherwise let other code report an error. 319 if top&ctxType == ctxType { 320 // A cycle containing only alias types is an error 321 // since it would expand indefinitely when aliases 322 // are substituted. 323 cycle := cycleFor(n) 324 for _, n1 := range cycle { 325 if n1.Name() != nil && !n1.Name().Alias() { 326 // Cycle is ok. But if n is an alias type and doesn't 327 // have a type yet, we have a recursive type declaration 328 // with aliases that we can't handle properly yet. 329 // Report an error rather than crashing later. 330 if n.Name() != nil && n.Name().Alias() && n.Type() == nil { 331 base.Pos = n.Pos() 332 base.Fatalf("cannot handle alias type declaration (issue #25838): %v", n) 333 } 334 base.Pos = lno 335 return n 336 } 337 } 338 base.ErrorfAt(n.Pos(), "invalid recursive type alias %v%s", n, cycleTrace(cycle)) 339 } 340 341 case ir.OLITERAL: 342 if top&(ctxExpr|ctxType) == ctxType { 343 base.Errorf("%v is not a type", n) 344 break 345 } 346 base.ErrorfAt(n.Pos(), "constant definition loop%s", cycleTrace(cycleFor(n))) 347 } 348 349 if base.Errors() == 0 { 350 var trace string 351 for i := len(typecheck_tcstack) - 1; i >= 0; i-- { 352 x := typecheck_tcstack[i] 353 trace += fmt.Sprintf("\n\t%v %v", ir.Line(x), x) 354 } 355 base.Errorf("typechecking loop involving %v%s", n, trace) 356 } 357 358 base.Pos = lno 359 return n 360 } 361 362 typecheck_tcstack = append(typecheck_tcstack, n) 363 364 n.SetTypecheck(2) 365 n = typecheck1(n, top) 366 n.SetTypecheck(1) 367 368 last := len(typecheck_tcstack) - 1 369 typecheck_tcstack[last] = nil 370 typecheck_tcstack = typecheck_tcstack[:last] 371 372 _, isExpr := n.(ir.Expr) 373 _, isStmt := n.(ir.Stmt) 374 isMulti := false 375 switch n.Op() { 376 case ir.OCALLFUNC, ir.OCALLINTER, ir.OCALLMETH: 377 n := n.(*ir.CallExpr) 378 if t := n.X.Type(); t != nil && t.Kind() == types.TFUNC { 379 nr := t.NumResults() 380 isMulti = nr > 1 381 if nr == 0 { 382 isExpr = false 383 } 384 } 385 case ir.OAPPEND: 386 // Must be used (and not BinaryExpr/UnaryExpr). 387 isStmt = false 388 case ir.OCLOSE, ir.ODELETE, ir.OPANIC, ir.OPRINT, ir.OPRINTN, ir.OVARKILL, ir.OVARLIVE: 389 // Must not be used. 390 isExpr = false 391 isStmt = true 392 case ir.OCOPY, ir.ORECOVER, ir.ORECV: 393 // Can be used or not. 394 isStmt = true 395 } 396 397 t := n.Type() 398 if t != nil && !t.IsFuncArgStruct() && n.Op() != ir.OTYPE { 399 switch t.Kind() { 400 case types.TFUNC, // might have TANY; wait until it's called 401 types.TANY, types.TFORW, types.TIDEAL, types.TNIL, types.TBLANK: 402 break 403 404 default: 405 types.CheckSize(t) 406 } 407 } 408 if t != nil { 409 n = EvalConst(n) 410 t = n.Type() 411 } 412 413 // TODO(rsc): Lots of the complexity here is because typecheck can 414 // see OTYPE, ONAME, and OLITERAL nodes multiple times. 415 // Once we make the IR a proper tree, we should be able to simplify 416 // this code a bit, especially the final case. 417 switch { 418 case top&(ctxStmt|ctxExpr) == ctxExpr && !isExpr && n.Op() != ir.OTYPE && !isMulti: 419 if !n.Diag() { 420 base.Errorf("%v used as value", n) 421 n.SetDiag(true) 422 } 423 if t != nil { 424 n.SetType(nil) 425 } 426 427 case top&ctxType == 0 && n.Op() == ir.OTYPE && t != nil: 428 if !n.Type().Broke() { 429 base.Errorf("type %v is not an expression", n.Type()) 430 n.SetDiag(true) 431 } 432 433 case top&(ctxStmt|ctxExpr) == ctxStmt && !isStmt && t != nil: 434 if !n.Diag() { 435 base.Errorf("%v evaluated but not used", n) 436 n.SetDiag(true) 437 } 438 n.SetType(nil) 439 440 case top&(ctxType|ctxExpr) == ctxType && n.Op() != ir.OTYPE && n.Op() != ir.ONONAME && (t != nil || n.Op() == ir.ONAME): 441 base.Errorf("%v is not a type", n) 442 if t != nil { 443 if n.Op() == ir.ONAME { 444 t.SetBroke(true) 445 } else { 446 n.SetType(nil) 447 } 448 } 449 450 } 451 452 base.Pos = lno 453 return n 454} 455 456// indexlit implements typechecking of untyped values as 457// array/slice indexes. It is almost equivalent to DefaultLit 458// but also accepts untyped numeric values representable as 459// value of type int (see also checkmake for comparison). 460// The result of indexlit MUST be assigned back to n, e.g. 461// n.Left = indexlit(n.Left) 462func indexlit(n ir.Node) ir.Node { 463 if n != nil && n.Type() != nil && n.Type().Kind() == types.TIDEAL { 464 return DefaultLit(n, types.Types[types.TINT]) 465 } 466 return n 467} 468 469// typecheck1 should ONLY be called from typecheck. 470func typecheck1(n ir.Node, top int) ir.Node { 471 if n, ok := n.(*ir.Name); ok { 472 typecheckdef(n) 473 } 474 475 switch n.Op() { 476 default: 477 ir.Dump("typecheck", n) 478 base.Fatalf("typecheck %v", n.Op()) 479 panic("unreachable") 480 481 case ir.OLITERAL: 482 if n.Sym() == nil && n.Type() == nil { 483 if !n.Diag() { 484 base.Fatalf("literal missing type: %v", n) 485 } 486 } 487 return n 488 489 case ir.ONIL: 490 return n 491 492 // names 493 case ir.ONONAME: 494 if !n.Diag() { 495 // Note: adderrorname looks for this string and 496 // adds context about the outer expression 497 base.ErrorfAt(n.Pos(), "undefined: %v", n.Sym()) 498 n.SetDiag(true) 499 } 500 n.SetType(nil) 501 return n 502 503 case ir.ONAME: 504 n := n.(*ir.Name) 505 if n.BuiltinOp != 0 { 506 if top&ctxCallee == 0 { 507 base.Errorf("use of builtin %v not in function call", n.Sym()) 508 n.SetType(nil) 509 return n 510 } 511 return n 512 } 513 if top&ctxAssign == 0 { 514 // not a write to the variable 515 if ir.IsBlank(n) { 516 base.Errorf("cannot use _ as value") 517 n.SetType(nil) 518 return n 519 } 520 n.SetUsed(true) 521 } 522 return n 523 524 case ir.OLINKSYMOFFSET: 525 // type already set 526 return n 527 528 case ir.OPACK: 529 n := n.(*ir.PkgName) 530 base.Errorf("use of package %v without selector", n.Sym()) 531 n.SetDiag(true) 532 return n 533 534 // types (ODEREF is with exprs) 535 case ir.OTYPE: 536 return n 537 538 case ir.OTSLICE: 539 n := n.(*ir.SliceType) 540 return tcSliceType(n) 541 542 case ir.OTARRAY: 543 n := n.(*ir.ArrayType) 544 return tcArrayType(n) 545 546 case ir.OTMAP: 547 n := n.(*ir.MapType) 548 return tcMapType(n) 549 550 case ir.OTCHAN: 551 n := n.(*ir.ChanType) 552 return tcChanType(n) 553 554 case ir.OTSTRUCT: 555 n := n.(*ir.StructType) 556 return tcStructType(n) 557 558 case ir.OTINTER: 559 n := n.(*ir.InterfaceType) 560 return tcInterfaceType(n) 561 562 case ir.OTFUNC: 563 n := n.(*ir.FuncType) 564 return tcFuncType(n) 565 // type or expr 566 case ir.ODEREF: 567 n := n.(*ir.StarExpr) 568 return tcStar(n, top) 569 570 // x op= y 571 case ir.OASOP: 572 n := n.(*ir.AssignOpStmt) 573 n.X, n.Y = Expr(n.X), Expr(n.Y) 574 checkassign(n, n.X) 575 if n.IncDec && !okforarith[n.X.Type().Kind()] { 576 base.Errorf("invalid operation: %v (non-numeric type %v)", n, n.X.Type()) 577 return n 578 } 579 switch n.AsOp { 580 case ir.OLSH, ir.ORSH: 581 n.X, n.Y, _ = tcShift(n, n.X, n.Y) 582 case ir.OADD, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OMOD, ir.OMUL, ir.OOR, ir.OSUB, ir.OXOR: 583 n.X, n.Y, _ = tcArith(n, n.AsOp, n.X, n.Y) 584 default: 585 base.Fatalf("invalid assign op: %v", n.AsOp) 586 } 587 return n 588 589 // logical operators 590 case ir.OANDAND, ir.OOROR: 591 n := n.(*ir.LogicalExpr) 592 n.X, n.Y = Expr(n.X), Expr(n.Y) 593 if n.X.Type() == nil || n.Y.Type() == nil { 594 n.SetType(nil) 595 return n 596 } 597 // For "x == x && len(s)", it's better to report that "len(s)" (type int) 598 // can't be used with "&&" than to report that "x == x" (type untyped bool) 599 // can't be converted to int (see issue #41500). 600 if !n.X.Type().IsBoolean() { 601 base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, n.Op(), typekind(n.X.Type())) 602 n.SetType(nil) 603 return n 604 } 605 if !n.Y.Type().IsBoolean() { 606 base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, n.Op(), typekind(n.Y.Type())) 607 n.SetType(nil) 608 return n 609 } 610 l, r, t := tcArith(n, n.Op(), n.X, n.Y) 611 n.X, n.Y = l, r 612 n.SetType(t) 613 return n 614 615 // shift operators 616 case ir.OLSH, ir.ORSH: 617 n := n.(*ir.BinaryExpr) 618 n.X, n.Y = Expr(n.X), Expr(n.Y) 619 l, r, t := tcShift(n, n.X, n.Y) 620 n.X, n.Y = l, r 621 n.SetType(t) 622 return n 623 624 // comparison operators 625 case ir.OEQ, ir.OGE, ir.OGT, ir.OLE, ir.OLT, ir.ONE: 626 n := n.(*ir.BinaryExpr) 627 n.X, n.Y = Expr(n.X), Expr(n.Y) 628 l, r, t := tcArith(n, n.Op(), n.X, n.Y) 629 if t != nil { 630 n.X, n.Y = l, r 631 n.SetType(types.UntypedBool) 632 if con := EvalConst(n); con.Op() == ir.OLITERAL { 633 return con 634 } 635 n.X, n.Y = defaultlit2(l, r, true) 636 } 637 return n 638 639 // binary operators 640 case ir.OADD, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OMOD, ir.OMUL, ir.OOR, ir.OSUB, ir.OXOR: 641 n := n.(*ir.BinaryExpr) 642 n.X, n.Y = Expr(n.X), Expr(n.Y) 643 l, r, t := tcArith(n, n.Op(), n.X, n.Y) 644 if t != nil && t.Kind() == types.TSTRING && n.Op() == ir.OADD { 645 // create or update OADDSTR node with list of strings in x + y + z + (w + v) + ... 646 var add *ir.AddStringExpr 647 if l.Op() == ir.OADDSTR { 648 add = l.(*ir.AddStringExpr) 649 add.SetPos(n.Pos()) 650 } else { 651 add = ir.NewAddStringExpr(n.Pos(), []ir.Node{l}) 652 } 653 if r.Op() == ir.OADDSTR { 654 r := r.(*ir.AddStringExpr) 655 add.List.Append(r.List.Take()...) 656 } else { 657 add.List.Append(r) 658 } 659 add.SetType(t) 660 return add 661 } 662 n.X, n.Y = l, r 663 n.SetType(t) 664 return n 665 666 case ir.OBITNOT, ir.ONEG, ir.ONOT, ir.OPLUS: 667 n := n.(*ir.UnaryExpr) 668 return tcUnaryArith(n) 669 670 // exprs 671 case ir.OADDR: 672 n := n.(*ir.AddrExpr) 673 return tcAddr(n) 674 675 case ir.OCOMPLIT: 676 return tcCompLit(n.(*ir.CompLitExpr)) 677 678 case ir.OXDOT, ir.ODOT: 679 n := n.(*ir.SelectorExpr) 680 return tcDot(n, top) 681 682 case ir.ODOTTYPE: 683 n := n.(*ir.TypeAssertExpr) 684 return tcDotType(n) 685 686 case ir.OINDEX: 687 n := n.(*ir.IndexExpr) 688 return tcIndex(n) 689 690 case ir.ORECV: 691 n := n.(*ir.UnaryExpr) 692 return tcRecv(n) 693 694 case ir.OSEND: 695 n := n.(*ir.SendStmt) 696 return tcSend(n) 697 698 case ir.OSLICEHEADER: 699 n := n.(*ir.SliceHeaderExpr) 700 return tcSliceHeader(n) 701 702 case ir.OMAKESLICECOPY: 703 n := n.(*ir.MakeExpr) 704 return tcMakeSliceCopy(n) 705 706 case ir.OSLICE, ir.OSLICE3: 707 n := n.(*ir.SliceExpr) 708 return tcSlice(n) 709 710 // call and call like 711 case ir.OCALL: 712 n := n.(*ir.CallExpr) 713 return tcCall(n, top) 714 715 case ir.OALIGNOF, ir.OOFFSETOF, ir.OSIZEOF: 716 n := n.(*ir.UnaryExpr) 717 n.SetType(types.Types[types.TUINTPTR]) 718 return n 719 720 case ir.OCAP, ir.OLEN: 721 n := n.(*ir.UnaryExpr) 722 return tcLenCap(n) 723 724 case ir.OREAL, ir.OIMAG: 725 n := n.(*ir.UnaryExpr) 726 return tcRealImag(n) 727 728 case ir.OCOMPLEX: 729 n := n.(*ir.BinaryExpr) 730 return tcComplex(n) 731 732 case ir.OCLOSE: 733 n := n.(*ir.UnaryExpr) 734 return tcClose(n) 735 736 case ir.ODELETE: 737 n := n.(*ir.CallExpr) 738 return tcDelete(n) 739 740 case ir.OAPPEND: 741 n := n.(*ir.CallExpr) 742 return tcAppend(n) 743 744 case ir.OCOPY: 745 n := n.(*ir.BinaryExpr) 746 return tcCopy(n) 747 748 case ir.OCONV: 749 n := n.(*ir.ConvExpr) 750 return tcConv(n) 751 752 case ir.OMAKE: 753 n := n.(*ir.CallExpr) 754 return tcMake(n) 755 756 case ir.ONEW: 757 n := n.(*ir.UnaryExpr) 758 return tcNew(n) 759 760 case ir.OPRINT, ir.OPRINTN: 761 n := n.(*ir.CallExpr) 762 return tcPrint(n) 763 764 case ir.OPANIC: 765 n := n.(*ir.UnaryExpr) 766 return tcPanic(n) 767 768 case ir.ORECOVER: 769 n := n.(*ir.CallExpr) 770 return tcRecover(n) 771 772 case ir.ORECOVERFP: 773 n := n.(*ir.CallExpr) 774 return tcRecoverFP(n) 775 776 case ir.OUNSAFEADD: 777 n := n.(*ir.BinaryExpr) 778 return tcUnsafeAdd(n) 779 780 case ir.OUNSAFESLICE: 781 n := n.(*ir.BinaryExpr) 782 return tcUnsafeSlice(n) 783 784 case ir.OCLOSURE: 785 n := n.(*ir.ClosureExpr) 786 return tcClosure(n, top) 787 788 case ir.OITAB: 789 n := n.(*ir.UnaryExpr) 790 return tcITab(n) 791 792 case ir.OIDATA: 793 // Whoever creates the OIDATA node must know a priori the concrete type at that moment, 794 // usually by just having checked the OITAB. 795 n := n.(*ir.UnaryExpr) 796 base.Fatalf("cannot typecheck interface data %v", n) 797 panic("unreachable") 798 799 case ir.OSPTR: 800 n := n.(*ir.UnaryExpr) 801 return tcSPtr(n) 802 803 case ir.OCFUNC: 804 n := n.(*ir.UnaryExpr) 805 n.X = Expr(n.X) 806 n.SetType(types.Types[types.TUINTPTR]) 807 return n 808 809 case ir.OGETCALLERPC, ir.OGETCALLERSP: 810 n := n.(*ir.CallExpr) 811 if len(n.Args) != 0 { 812 base.FatalfAt(n.Pos(), "unexpected arguments: %v", n) 813 } 814 n.SetType(types.Types[types.TUINTPTR]) 815 return n 816 817 case ir.OCONVNOP: 818 n := n.(*ir.ConvExpr) 819 n.X = Expr(n.X) 820 return n 821 822 // statements 823 case ir.OAS: 824 n := n.(*ir.AssignStmt) 825 tcAssign(n) 826 827 // Code that creates temps does not bother to set defn, so do it here. 828 if n.X.Op() == ir.ONAME && ir.IsAutoTmp(n.X) { 829 n.X.Name().Defn = n 830 } 831 return n 832 833 case ir.OAS2: 834 tcAssignList(n.(*ir.AssignListStmt)) 835 return n 836 837 case ir.OBREAK, 838 ir.OCONTINUE, 839 ir.ODCL, 840 ir.OGOTO, 841 ir.OFALL, 842 ir.OVARKILL, 843 ir.OVARLIVE: 844 return n 845 846 case ir.OBLOCK: 847 n := n.(*ir.BlockStmt) 848 Stmts(n.List) 849 return n 850 851 case ir.OLABEL: 852 if n.Sym().IsBlank() { 853 // Empty identifier is valid but useless. 854 // Eliminate now to simplify life later. 855 // See issues 7538, 11589, 11593. 856 n = ir.NewBlockStmt(n.Pos(), nil) 857 } 858 return n 859 860 case ir.ODEFER, ir.OGO: 861 n := n.(*ir.GoDeferStmt) 862 n.Call = typecheck(n.Call, ctxStmt|ctxExpr) 863 if !n.Call.Diag() { 864 tcGoDefer(n) 865 } 866 return n 867 868 case ir.OFOR, ir.OFORUNTIL: 869 n := n.(*ir.ForStmt) 870 return tcFor(n) 871 872 case ir.OIF: 873 n := n.(*ir.IfStmt) 874 return tcIf(n) 875 876 case ir.ORETURN: 877 n := n.(*ir.ReturnStmt) 878 return tcReturn(n) 879 880 case ir.OTAILCALL: 881 n := n.(*ir.TailCallStmt) 882 n.Call = typecheck(n.Call, ctxStmt|ctxExpr).(*ir.CallExpr) 883 return n 884 885 case ir.OCHECKNIL: 886 n := n.(*ir.UnaryExpr) 887 return tcCheckNil(n) 888 889 case ir.OSELECT: 890 tcSelect(n.(*ir.SelectStmt)) 891 return n 892 893 case ir.OSWITCH: 894 tcSwitch(n.(*ir.SwitchStmt)) 895 return n 896 897 case ir.ORANGE: 898 tcRange(n.(*ir.RangeStmt)) 899 return n 900 901 case ir.OTYPESW: 902 n := n.(*ir.TypeSwitchGuard) 903 base.Errorf("use of .(type) outside type switch") 904 n.SetDiag(true) 905 return n 906 907 case ir.ODCLFUNC: 908 tcFunc(n.(*ir.Func)) 909 return n 910 911 case ir.ODCLCONST: 912 n := n.(*ir.Decl) 913 n.X = Expr(n.X).(*ir.Name) 914 return n 915 916 case ir.ODCLTYPE: 917 n := n.(*ir.Decl) 918 n.X = typecheck(n.X, ctxType).(*ir.Name) 919 types.CheckSize(n.X.Type()) 920 return n 921 } 922 923 // No return n here! 924 // Individual cases can type-assert n, introducing a new one. 925 // Each must execute its own return n. 926} 927 928func typecheckargs(n ir.InitNode) { 929 var list []ir.Node 930 switch n := n.(type) { 931 default: 932 base.Fatalf("typecheckargs %+v", n.Op()) 933 case *ir.CallExpr: 934 list = n.Args 935 if n.IsDDD { 936 Exprs(list) 937 return 938 } 939 case *ir.ReturnStmt: 940 list = n.Results 941 } 942 if len(list) != 1 { 943 Exprs(list) 944 return 945 } 946 947 typecheckslice(list, ctxExpr|ctxMultiOK) 948 t := list[0].Type() 949 if t == nil || !t.IsFuncArgStruct() { 950 return 951 } 952 953 // Save n as n.Orig for fmt.go. 954 if ir.Orig(n) == n { 955 n.(ir.OrigNode).SetOrig(ir.SepCopy(n)) 956 } 957 958 // Rewrite f(g()) into t1, t2, ... = g(); f(t1, t2, ...). 959 RewriteMultiValueCall(n, list[0]) 960} 961 962// RewriteMultiValueCall rewrites multi-valued f() to use temporaries, 963// so the backend wouldn't need to worry about tuple-valued expressions. 964func RewriteMultiValueCall(n ir.InitNode, call ir.Node) { 965 // If we're outside of function context, then this call will 966 // be executed during the generated init function. However, 967 // init.go hasn't yet created it. Instead, associate the 968 // temporary variables with InitTodoFunc for now, and init.go 969 // will reassociate them later when it's appropriate. 970 static := ir.CurFunc == nil 971 if static { 972 ir.CurFunc = InitTodoFunc 973 } 974 975 as := ir.NewAssignListStmt(base.Pos, ir.OAS2, nil, []ir.Node{call}) 976 results := call.Type().FieldSlice() 977 list := make([]ir.Node, len(results)) 978 for i, result := range results { 979 tmp := Temp(result.Type) 980 as.PtrInit().Append(ir.NewDecl(base.Pos, ir.ODCL, tmp)) 981 as.Lhs.Append(tmp) 982 list[i] = tmp 983 } 984 if static { 985 ir.CurFunc = nil 986 } 987 988 n.PtrInit().Append(Stmt(as)) 989 990 switch n := n.(type) { 991 default: 992 base.Fatalf("rewriteMultiValueCall %+v", n.Op()) 993 case *ir.CallExpr: 994 n.Args = list 995 case *ir.ReturnStmt: 996 n.Results = list 997 case *ir.AssignListStmt: 998 if n.Op() != ir.OAS2FUNC { 999 base.Fatalf("rewriteMultiValueCall: invalid op %v", n.Op()) 1000 } 1001 as.SetOp(ir.OAS2FUNC) 1002 n.SetOp(ir.OAS2) 1003 n.Rhs = make([]ir.Node, len(list)) 1004 for i, tmp := range list { 1005 n.Rhs[i] = AssignConv(tmp, n.Lhs[i].Type(), "assignment") 1006 } 1007 } 1008} 1009 1010func checksliceindex(l ir.Node, r ir.Node, tp *types.Type) bool { 1011 t := r.Type() 1012 if t == nil { 1013 return false 1014 } 1015 if !t.IsInteger() { 1016 base.Errorf("invalid slice index %v (type %v)", r, t) 1017 return false 1018 } 1019 1020 if r.Op() == ir.OLITERAL { 1021 x := r.Val() 1022 if constant.Sign(x) < 0 { 1023 base.Errorf("invalid slice index %v (index must be non-negative)", r) 1024 return false 1025 } else if tp != nil && tp.NumElem() >= 0 && constant.Compare(x, token.GTR, constant.MakeInt64(tp.NumElem())) { 1026 base.Errorf("invalid slice index %v (out of bounds for %d-element array)", r, tp.NumElem()) 1027 return false 1028 } else if ir.IsConst(l, constant.String) && constant.Compare(x, token.GTR, constant.MakeInt64(int64(len(ir.StringVal(l))))) { 1029 base.Errorf("invalid slice index %v (out of bounds for %d-byte string)", r, len(ir.StringVal(l))) 1030 return false 1031 } else if ir.ConstOverflow(x, types.Types[types.TINT]) { 1032 base.Errorf("invalid slice index %v (index too large)", r) 1033 return false 1034 } 1035 } 1036 1037 return true 1038} 1039 1040func checksliceconst(lo ir.Node, hi ir.Node) bool { 1041 if lo != nil && hi != nil && lo.Op() == ir.OLITERAL && hi.Op() == ir.OLITERAL && constant.Compare(lo.Val(), token.GTR, hi.Val()) { 1042 base.Errorf("invalid slice index: %v > %v", lo, hi) 1043 return false 1044 } 1045 1046 return true 1047} 1048 1049// The result of implicitstar MUST be assigned back to n, e.g. 1050// n.Left = implicitstar(n.Left) 1051func implicitstar(n ir.Node) ir.Node { 1052 // insert implicit * if needed for fixed array 1053 t := n.Type() 1054 if t == nil || !t.IsPtr() { 1055 return n 1056 } 1057 t = t.Elem() 1058 if t == nil { 1059 return n 1060 } 1061 if !t.IsArray() { 1062 return n 1063 } 1064 star := ir.NewStarExpr(base.Pos, n) 1065 star.SetImplicit(true) 1066 return Expr(star) 1067} 1068 1069func needOneArg(n *ir.CallExpr, f string, args ...interface{}) (ir.Node, bool) { 1070 if len(n.Args) == 0 { 1071 p := fmt.Sprintf(f, args...) 1072 base.Errorf("missing argument to %s: %v", p, n) 1073 return nil, false 1074 } 1075 1076 if len(n.Args) > 1 { 1077 p := fmt.Sprintf(f, args...) 1078 base.Errorf("too many arguments to %s: %v", p, n) 1079 return n.Args[0], false 1080 } 1081 1082 return n.Args[0], true 1083} 1084 1085func needTwoArgs(n *ir.CallExpr) (ir.Node, ir.Node, bool) { 1086 if len(n.Args) != 2 { 1087 if len(n.Args) < 2 { 1088 base.Errorf("not enough arguments in call to %v", n) 1089 } else { 1090 base.Errorf("too many arguments in call to %v", n) 1091 } 1092 return nil, nil, false 1093 } 1094 return n.Args[0], n.Args[1], true 1095} 1096 1097// Lookdot1 looks up the specified method s in the list fs of methods, returning 1098// the matching field or nil. If dostrcmp is 0, it matches the symbols. If 1099// dostrcmp is 1, it matches by name exactly. If dostrcmp is 2, it matches names 1100// with case folding. 1101func Lookdot1(errnode ir.Node, s *types.Sym, t *types.Type, fs *types.Fields, dostrcmp int) *types.Field { 1102 var r *types.Field 1103 for _, f := range fs.Slice() { 1104 if dostrcmp != 0 && f.Sym.Name == s.Name { 1105 return f 1106 } 1107 if dostrcmp == 2 && strings.EqualFold(f.Sym.Name, s.Name) { 1108 return f 1109 } 1110 if f.Sym != s { 1111 continue 1112 } 1113 if r != nil { 1114 if errnode != nil { 1115 base.Errorf("ambiguous selector %v", errnode) 1116 } else if t.IsPtr() { 1117 base.Errorf("ambiguous selector (%v).%v", t, s) 1118 } else { 1119 base.Errorf("ambiguous selector %v.%v", t, s) 1120 } 1121 break 1122 } 1123 1124 r = f 1125 } 1126 1127 return r 1128} 1129 1130// typecheckMethodExpr checks selector expressions (ODOT) where the 1131// base expression is a type expression (OTYPE). 1132func typecheckMethodExpr(n *ir.SelectorExpr) (res ir.Node) { 1133 if base.EnableTrace && base.Flag.LowerT { 1134 defer tracePrint("typecheckMethodExpr", n)(&res) 1135 } 1136 1137 t := n.X.Type() 1138 1139 // Compute the method set for t. 1140 var ms *types.Fields 1141 if t.IsInterface() { 1142 ms = t.AllMethods() 1143 } else { 1144 mt := types.ReceiverBaseType(t) 1145 if mt == nil { 1146 base.Errorf("%v undefined (type %v has no method %v)", n, t, n.Sel) 1147 n.SetType(nil) 1148 return n 1149 } 1150 CalcMethods(mt) 1151 ms = mt.AllMethods() 1152 1153 // The method expression T.m requires a wrapper when T 1154 // is different from m's declared receiver type. We 1155 // normally generate these wrappers while writing out 1156 // runtime type descriptors, which is always done for 1157 // types declared at package scope. However, we need 1158 // to make sure to generate wrappers for anonymous 1159 // receiver types too. 1160 if mt.Sym() == nil { 1161 NeedRuntimeType(t) 1162 } 1163 } 1164 1165 s := n.Sel 1166 m := Lookdot1(n, s, t, ms, 0) 1167 if m == nil { 1168 if Lookdot1(n, s, t, ms, 1) != nil { 1169 base.Errorf("%v undefined (cannot refer to unexported method %v)", n, s) 1170 } else if _, ambig := dotpath(s, t, nil, false); ambig { 1171 base.Errorf("%v undefined (ambiguous selector)", n) // method or field 1172 } else { 1173 base.Errorf("%v undefined (type %v has no method %v)", n, t, s) 1174 } 1175 n.SetType(nil) 1176 return n 1177 } 1178 1179 if !types.IsMethodApplicable(t, m) { 1180 base.Errorf("invalid method expression %v (needs pointer receiver: (*%v).%S)", n, t, s) 1181 n.SetType(nil) 1182 return n 1183 } 1184 1185 n.SetOp(ir.OMETHEXPR) 1186 n.Selection = m 1187 n.SetType(NewMethodType(m.Type, n.X.Type())) 1188 return n 1189} 1190 1191func derefall(t *types.Type) *types.Type { 1192 for t != nil && t.IsPtr() { 1193 t = t.Elem() 1194 } 1195 return t 1196} 1197 1198// Lookdot looks up field or method n.Sel in the type t and returns the matching 1199// field. It transforms the op of node n to ODOTINTER or ODOTMETH, if appropriate. 1200// It also may add a StarExpr node to n.X as needed for access to non-pointer 1201// methods. If dostrcmp is 0, it matches the field/method with the exact symbol 1202// as n.Sel (appropriate for exported fields). If dostrcmp is 1, it matches by name 1203// exactly. If dostrcmp is 2, it matches names with case folding. 1204func Lookdot(n *ir.SelectorExpr, t *types.Type, dostrcmp int) *types.Field { 1205 s := n.Sel 1206 1207 types.CalcSize(t) 1208 var f1 *types.Field 1209 if t.IsStruct() { 1210 f1 = Lookdot1(n, s, t, t.Fields(), dostrcmp) 1211 } else if t.IsInterface() { 1212 f1 = Lookdot1(n, s, t, t.AllMethods(), dostrcmp) 1213 } 1214 1215 var f2 *types.Field 1216 if n.X.Type() == t || n.X.Type().Sym() == nil { 1217 mt := types.ReceiverBaseType(t) 1218 if mt != nil { 1219 f2 = Lookdot1(n, s, mt, mt.Methods(), dostrcmp) 1220 } 1221 } 1222 1223 if f1 != nil { 1224 if dostrcmp > 1 || f1.Broke() { 1225 // Already in the process of diagnosing an error. 1226 return f1 1227 } 1228 if f2 != nil { 1229 base.Errorf("%v is both field and method", n.Sel) 1230 } 1231 if f1.Offset == types.BADWIDTH { 1232 base.Fatalf("Lookdot badwidth t=%v, f1=%v@%p", t, f1, f1) 1233 } 1234 n.Selection = f1 1235 n.SetType(f1.Type) 1236 if t.IsInterface() { 1237 if n.X.Type().IsPtr() { 1238 star := ir.NewStarExpr(base.Pos, n.X) 1239 star.SetImplicit(true) 1240 n.X = Expr(star) 1241 } 1242 1243 n.SetOp(ir.ODOTINTER) 1244 } 1245 return f1 1246 } 1247 1248 if f2 != nil { 1249 if dostrcmp > 1 { 1250 // Already in the process of diagnosing an error. 1251 return f2 1252 } 1253 orig := n.X 1254 tt := n.X.Type() 1255 types.CalcSize(tt) 1256 rcvr := f2.Type.Recv().Type 1257 if !types.Identical(rcvr, tt) { 1258 if rcvr.IsPtr() && types.Identical(rcvr.Elem(), tt) { 1259 checklvalue(n.X, "call pointer method on") 1260 addr := NodAddr(n.X) 1261 addr.SetImplicit(true) 1262 n.X = typecheck(addr, ctxType|ctxExpr) 1263 } else if tt.IsPtr() && (!rcvr.IsPtr() || rcvr.IsPtr() && rcvr.Elem().NotInHeap()) && types.Identical(tt.Elem(), rcvr) { 1264 star := ir.NewStarExpr(base.Pos, n.X) 1265 star.SetImplicit(true) 1266 n.X = typecheck(star, ctxType|ctxExpr) 1267 } else if tt.IsPtr() && tt.Elem().IsPtr() && types.Identical(derefall(tt), derefall(rcvr)) { 1268 base.Errorf("calling method %v with receiver %L requires explicit dereference", n.Sel, n.X) 1269 for tt.IsPtr() { 1270 // Stop one level early for method with pointer receiver. 1271 if rcvr.IsPtr() && !tt.Elem().IsPtr() { 1272 break 1273 } 1274 star := ir.NewStarExpr(base.Pos, n.X) 1275 star.SetImplicit(true) 1276 n.X = typecheck(star, ctxType|ctxExpr) 1277 tt = tt.Elem() 1278 } 1279 } else { 1280 base.Fatalf("method mismatch: %v for %v", rcvr, tt) 1281 } 1282 } 1283 1284 // Check that we haven't implicitly dereferenced any defined pointer types. 1285 for x := n.X; ; { 1286 var inner ir.Node 1287 implicit := false 1288 switch x := x.(type) { 1289 case *ir.AddrExpr: 1290 inner, implicit = x.X, x.Implicit() 1291 case *ir.SelectorExpr: 1292 inner, implicit = x.X, x.Implicit() 1293 case *ir.StarExpr: 1294 inner, implicit = x.X, x.Implicit() 1295 } 1296 if !implicit { 1297 break 1298 } 1299 if inner.Type().Sym() != nil && (x.Op() == ir.ODEREF || x.Op() == ir.ODOTPTR) { 1300 // Found an implicit dereference of a defined pointer type. 1301 // Restore n.X for better error message. 1302 n.X = orig 1303 return nil 1304 } 1305 x = inner 1306 } 1307 1308 n.Selection = f2 1309 n.SetType(f2.Type) 1310 n.SetOp(ir.ODOTMETH) 1311 1312 return f2 1313 } 1314 1315 return nil 1316} 1317 1318func nokeys(l ir.Nodes) bool { 1319 for _, n := range l { 1320 if n.Op() == ir.OKEY || n.Op() == ir.OSTRUCTKEY { 1321 return false 1322 } 1323 } 1324 return true 1325} 1326 1327func hasddd(t *types.Type) bool { 1328 for _, tl := range t.Fields().Slice() { 1329 if tl.IsDDD() { 1330 return true 1331 } 1332 } 1333 1334 return false 1335} 1336 1337// typecheck assignment: type list = expression list 1338func typecheckaste(op ir.Op, call ir.Node, isddd bool, tstruct *types.Type, nl ir.Nodes, desc func() string) { 1339 var t *types.Type 1340 var i int 1341 1342 lno := base.Pos 1343 defer func() { base.Pos = lno }() 1344 1345 if tstruct.Broke() { 1346 return 1347 } 1348 1349 var n ir.Node 1350 if len(nl) == 1 { 1351 n = nl[0] 1352 } 1353 1354 n1 := tstruct.NumFields() 1355 n2 := len(nl) 1356 if !hasddd(tstruct) { 1357 if isddd { 1358 goto invalidddd 1359 } 1360 if n2 > n1 { 1361 goto toomany 1362 } 1363 if n2 < n1 { 1364 goto notenough 1365 } 1366 } else { 1367 if !isddd { 1368 if n2 < n1-1 { 1369 goto notenough 1370 } 1371 } else { 1372 if n2 > n1 { 1373 goto toomany 1374 } 1375 if n2 < n1 { 1376 goto notenough 1377 } 1378 } 1379 } 1380 1381 i = 0 1382 for _, tl := range tstruct.Fields().Slice() { 1383 t = tl.Type 1384 if tl.IsDDD() { 1385 if isddd { 1386 if i >= len(nl) { 1387 goto notenough 1388 } 1389 if len(nl)-i > 1 { 1390 goto toomany 1391 } 1392 n = nl[i] 1393 ir.SetPos(n) 1394 if n.Type() != nil { 1395 nl[i] = assignconvfn(n, t, desc) 1396 } 1397 return 1398 } 1399 1400 // TODO(mdempsky): Make into ... call with implicit slice. 1401 for ; i < len(nl); i++ { 1402 n = nl[i] 1403 ir.SetPos(n) 1404 if n.Type() != nil { 1405 nl[i] = assignconvfn(n, t.Elem(), desc) 1406 } 1407 } 1408 return 1409 } 1410 1411 if i >= len(nl) { 1412 goto notenough 1413 } 1414 n = nl[i] 1415 ir.SetPos(n) 1416 if n.Type() != nil { 1417 nl[i] = assignconvfn(n, t, desc) 1418 } 1419 i++ 1420 } 1421 1422 if i < len(nl) { 1423 goto toomany 1424 } 1425 1426invalidddd: 1427 if isddd { 1428 if call != nil { 1429 base.Errorf("invalid use of ... in call to %v", call) 1430 } else { 1431 base.Errorf("invalid use of ... in %v", op) 1432 } 1433 } 1434 return 1435 1436notenough: 1437 if n == nil || (!n.Diag() && n.Type() != nil) { 1438 details := errorDetails(nl, tstruct, isddd) 1439 if call != nil { 1440 // call is the expression being called, not the overall call. 1441 // Method expressions have the form T.M, and the compiler has 1442 // rewritten those to ONAME nodes but left T in Left. 1443 if call.Op() == ir.OMETHEXPR { 1444 call := call.(*ir.SelectorExpr) 1445 base.Errorf("not enough arguments in call to method expression %v%s", call, details) 1446 } else { 1447 base.Errorf("not enough arguments in call to %v%s", call, details) 1448 } 1449 } else { 1450 base.Errorf("not enough arguments to %v%s", op, details) 1451 } 1452 if n != nil { 1453 n.SetDiag(true) 1454 } 1455 } 1456 return 1457 1458toomany: 1459 details := errorDetails(nl, tstruct, isddd) 1460 if call != nil { 1461 base.Errorf("too many arguments in call to %v%s", call, details) 1462 } else { 1463 base.Errorf("too many arguments to %v%s", op, details) 1464 } 1465} 1466 1467func errorDetails(nl ir.Nodes, tstruct *types.Type, isddd bool) string { 1468 // Suppress any return message signatures if: 1469 // 1470 // (1) We don't know any type at a call site (see #19012). 1471 // (2) Any node has an unknown type. 1472 // (3) Invalid type for variadic parameter (see #46957). 1473 if tstruct == nil { 1474 return "" // case 1 1475 } 1476 1477 if isddd && !nl[len(nl)-1].Type().IsSlice() { 1478 return "" // case 3 1479 } 1480 1481 for _, n := range nl { 1482 if n.Type() == nil { 1483 return "" // case 2 1484 } 1485 } 1486 return fmt.Sprintf("\n\thave %s\n\twant %v", fmtSignature(nl, isddd), tstruct) 1487} 1488 1489// sigrepr is a type's representation to the outside world, 1490// in string representations of return signatures 1491// e.g in error messages about wrong arguments to return. 1492func sigrepr(t *types.Type, isddd bool) string { 1493 switch t { 1494 case types.UntypedString: 1495 return "string" 1496 case types.UntypedBool: 1497 return "bool" 1498 } 1499 1500 if t.Kind() == types.TIDEAL { 1501 // "untyped number" is not commonly used 1502 // outside of the compiler, so let's use "number". 1503 // TODO(mdempsky): Revisit this. 1504 return "number" 1505 } 1506 1507 // Turn []T... argument to ...T for clearer error message. 1508 if isddd { 1509 if !t.IsSlice() { 1510 base.Fatalf("bad type for ... argument: %v", t) 1511 } 1512 return "..." + t.Elem().String() 1513 } 1514 return t.String() 1515} 1516 1517// sigerr returns the signature of the types at the call or return. 1518func fmtSignature(nl ir.Nodes, isddd bool) string { 1519 if len(nl) < 1 { 1520 return "()" 1521 } 1522 1523 var typeStrings []string 1524 for i, n := range nl { 1525 isdddArg := isddd && i == len(nl)-1 1526 typeStrings = append(typeStrings, sigrepr(n.Type(), isdddArg)) 1527 } 1528 1529 return fmt.Sprintf("(%s)", strings.Join(typeStrings, ", ")) 1530} 1531 1532// type check composite 1533func fielddup(name string, hash map[string]bool) { 1534 if hash[name] { 1535 base.Errorf("duplicate field name in struct literal: %s", name) 1536 return 1537 } 1538 hash[name] = true 1539} 1540 1541// iscomptype reports whether type t is a composite literal type. 1542func iscomptype(t *types.Type) bool { 1543 switch t.Kind() { 1544 case types.TARRAY, types.TSLICE, types.TSTRUCT, types.TMAP: 1545 return true 1546 default: 1547 return false 1548 } 1549} 1550 1551// pushtype adds elided type information for composite literals if 1552// appropriate, and returns the resulting expression. 1553func pushtype(nn ir.Node, t *types.Type) ir.Node { 1554 if nn == nil || nn.Op() != ir.OCOMPLIT { 1555 return nn 1556 } 1557 n := nn.(*ir.CompLitExpr) 1558 if n.Ntype != nil { 1559 return n 1560 } 1561 1562 switch { 1563 case iscomptype(t): 1564 // For T, return T{...}. 1565 n.Ntype = ir.TypeNode(t) 1566 1567 case t.IsPtr() && iscomptype(t.Elem()): 1568 // For *T, return &T{...}. 1569 n.Ntype = ir.TypeNode(t.Elem()) 1570 1571 addr := NodAddrAt(n.Pos(), n) 1572 addr.SetImplicit(true) 1573 return addr 1574 } 1575 return n 1576} 1577 1578// typecheckarraylit type-checks a sequence of slice/array literal elements. 1579func typecheckarraylit(elemType *types.Type, bound int64, elts []ir.Node, ctx string) int64 { 1580 // If there are key/value pairs, create a map to keep seen 1581 // keys so we can check for duplicate indices. 1582 var indices map[int64]bool 1583 for _, elt := range elts { 1584 if elt.Op() == ir.OKEY { 1585 indices = make(map[int64]bool) 1586 break 1587 } 1588 } 1589 1590 var key, length int64 1591 for i, elt := range elts { 1592 ir.SetPos(elt) 1593 r := elts[i] 1594 var kv *ir.KeyExpr 1595 if elt.Op() == ir.OKEY { 1596 elt := elt.(*ir.KeyExpr) 1597 elt.Key = Expr(elt.Key) 1598 key = IndexConst(elt.Key) 1599 if key < 0 { 1600 if !elt.Key.Diag() { 1601 if key == -2 { 1602 base.Errorf("index too large") 1603 } else { 1604 base.Errorf("index must be non-negative integer constant") 1605 } 1606 elt.Key.SetDiag(true) 1607 } 1608 key = -(1 << 30) // stay negative for a while 1609 } 1610 kv = elt 1611 r = elt.Value 1612 } 1613 1614 r = pushtype(r, elemType) 1615 r = Expr(r) 1616 r = AssignConv(r, elemType, ctx) 1617 if kv != nil { 1618 kv.Value = r 1619 } else { 1620 elts[i] = r 1621 } 1622 1623 if key >= 0 { 1624 if indices != nil { 1625 if indices[key] { 1626 base.Errorf("duplicate index in %s: %d", ctx, key) 1627 } else { 1628 indices[key] = true 1629 } 1630 } 1631 1632 if bound >= 0 && key >= bound { 1633 base.Errorf("array index %d out of bounds [0:%d]", key, bound) 1634 bound = -1 1635 } 1636 } 1637 1638 key++ 1639 if key > length { 1640 length = key 1641 } 1642 } 1643 1644 return length 1645} 1646 1647// visible reports whether sym is exported or locally defined. 1648func visible(sym *types.Sym) bool { 1649 return sym != nil && (types.IsExported(sym.Name) || sym.Pkg == types.LocalPkg) 1650} 1651 1652// nonexported reports whether sym is an unexported field. 1653func nonexported(sym *types.Sym) bool { 1654 return sym != nil && !types.IsExported(sym.Name) 1655} 1656 1657func checklvalue(n ir.Node, verb string) { 1658 if !ir.IsAddressable(n) { 1659 base.Errorf("cannot %s %v", verb, n) 1660 } 1661} 1662 1663func checkassign(stmt ir.Node, n ir.Node) { 1664 // have already complained about n being invalid 1665 if n.Type() == nil { 1666 if base.Errors() == 0 { 1667 base.Fatalf("expected an error about %v", n) 1668 } 1669 return 1670 } 1671 1672 if ir.IsAddressable(n) { 1673 return 1674 } 1675 if n.Op() == ir.OINDEXMAP { 1676 n := n.(*ir.IndexExpr) 1677 n.Assigned = true 1678 return 1679 } 1680 1681 defer n.SetType(nil) 1682 if n.Diag() { 1683 return 1684 } 1685 switch { 1686 case n.Op() == ir.ODOT && n.(*ir.SelectorExpr).X.Op() == ir.OINDEXMAP: 1687 base.Errorf("cannot assign to struct field %v in map", n) 1688 case (n.Op() == ir.OINDEX && n.(*ir.IndexExpr).X.Type().IsString()) || n.Op() == ir.OSLICESTR: 1689 base.Errorf("cannot assign to %v (strings are immutable)", n) 1690 case n.Op() == ir.OLITERAL && n.Sym() != nil && ir.IsConstNode(n): 1691 base.Errorf("cannot assign to %v (declared const)", n) 1692 default: 1693 base.Errorf("cannot assign to %v", n) 1694 } 1695} 1696 1697func checkassignto(src *types.Type, dst ir.Node) { 1698 // TODO(mdempsky): Handle all untyped types correctly. 1699 if src == types.UntypedBool && dst.Type().IsBoolean() { 1700 return 1701 } 1702 1703 if op, why := Assignop(src, dst.Type()); op == ir.OXXX { 1704 base.Errorf("cannot assign %v to %L in multiple assignment%s", src, dst, why) 1705 return 1706 } 1707} 1708 1709// The result of stringtoruneslit MUST be assigned back to n, e.g. 1710// n.Left = stringtoruneslit(n.Left) 1711func stringtoruneslit(n *ir.ConvExpr) ir.Node { 1712 if n.X.Op() != ir.OLITERAL || n.X.Val().Kind() != constant.String { 1713 base.Fatalf("stringtoarraylit %v", n) 1714 } 1715 1716 var l []ir.Node 1717 i := 0 1718 for _, r := range ir.StringVal(n.X) { 1719 l = append(l, ir.NewKeyExpr(base.Pos, ir.NewInt(int64(i)), ir.NewInt(int64(r)))) 1720 i++ 1721 } 1722 1723 nn := ir.NewCompLitExpr(base.Pos, ir.OCOMPLIT, ir.TypeNode(n.Type()), nil) 1724 nn.List = l 1725 return Expr(nn) 1726} 1727 1728var mapqueue []*ir.MapType 1729 1730func CheckMapKeys() { 1731 for _, n := range mapqueue { 1732 k := n.Type().MapType().Key 1733 if !k.Broke() && !types.IsComparable(k) { 1734 base.ErrorfAt(n.Pos(), "invalid map key type %v", k) 1735 } 1736 } 1737 mapqueue = nil 1738} 1739 1740func typecheckdeftype(n *ir.Name) { 1741 if base.EnableTrace && base.Flag.LowerT { 1742 defer tracePrint("typecheckdeftype", n)(nil) 1743 } 1744 1745 t := types.NewNamed(n) 1746 if n.Curfn != nil { 1747 t.SetVargen() 1748 } 1749 1750 if n.Pragma()&ir.NotInHeap != 0 { 1751 t.SetNotInHeap(true) 1752 } 1753 1754 n.SetType(t) 1755 n.SetTypecheck(1) 1756 n.SetWalkdef(1) 1757 1758 types.DeferCheckSize() 1759 errorsBefore := base.Errors() 1760 n.Ntype = typecheckNtype(n.Ntype) 1761 if underlying := n.Ntype.Type(); underlying != nil { 1762 t.SetUnderlying(underlying) 1763 } else { 1764 n.SetDiag(true) 1765 n.SetType(nil) 1766 } 1767 if t.Kind() == types.TFORW && base.Errors() > errorsBefore { 1768 // Something went wrong during type-checking, 1769 // but it was reported. Silence future errors. 1770 t.SetBroke(true) 1771 } 1772 types.ResumeCheckSize() 1773} 1774 1775func typecheckdef(n *ir.Name) { 1776 if base.EnableTrace && base.Flag.LowerT { 1777 defer tracePrint("typecheckdef", n)(nil) 1778 } 1779 1780 if n.Walkdef() == 1 { 1781 return 1782 } 1783 1784 if n.Type() != nil { // builtin 1785 // Mark as Walkdef so that if n.SetType(nil) is called later, we 1786 // won't try walking again. 1787 if got := n.Walkdef(); got != 0 { 1788 base.Fatalf("unexpected walkdef: %v", got) 1789 } 1790 n.SetWalkdef(1) 1791 return 1792 } 1793 1794 lno := ir.SetPos(n) 1795 typecheckdefstack = append(typecheckdefstack, n) 1796 if n.Walkdef() == 2 { 1797 base.FlushErrors() 1798 fmt.Printf("typecheckdef loop:") 1799 for i := len(typecheckdefstack) - 1; i >= 0; i-- { 1800 n := typecheckdefstack[i] 1801 fmt.Printf(" %v", n.Sym()) 1802 } 1803 fmt.Printf("\n") 1804 base.Fatalf("typecheckdef loop") 1805 } 1806 1807 n.SetWalkdef(2) 1808 1809 switch n.Op() { 1810 default: 1811 base.Fatalf("typecheckdef %v", n.Op()) 1812 1813 case ir.OLITERAL: 1814 if n.Ntype != nil { 1815 n.Ntype = typecheckNtype(n.Ntype) 1816 n.SetType(n.Ntype.Type()) 1817 n.Ntype = nil 1818 if n.Type() == nil { 1819 n.SetDiag(true) 1820 goto ret 1821 } 1822 } 1823 1824 e := n.Defn 1825 n.Defn = nil 1826 if e == nil { 1827 ir.Dump("typecheckdef nil defn", n) 1828 base.ErrorfAt(n.Pos(), "xxx") 1829 } 1830 1831 e = Expr(e) 1832 if e.Type() == nil { 1833 goto ret 1834 } 1835 if !ir.IsConstNode(e) { 1836 if !e.Diag() { 1837 if e.Op() == ir.ONIL { 1838 base.ErrorfAt(n.Pos(), "const initializer cannot be nil") 1839 } else { 1840 base.ErrorfAt(n.Pos(), "const initializer %v is not a constant", e) 1841 } 1842 e.SetDiag(true) 1843 } 1844 goto ret 1845 } 1846 1847 t := n.Type() 1848 if t != nil { 1849 if !ir.OKForConst[t.Kind()] { 1850 base.ErrorfAt(n.Pos(), "invalid constant type %v", t) 1851 goto ret 1852 } 1853 1854 if !e.Type().IsUntyped() && !types.Identical(t, e.Type()) { 1855 base.ErrorfAt(n.Pos(), "cannot use %L as type %v in const initializer", e, t) 1856 goto ret 1857 } 1858 1859 e = convlit(e, t) 1860 } 1861 1862 n.SetType(e.Type()) 1863 if n.Type() != nil { 1864 n.SetVal(e.Val()) 1865 } 1866 1867 case ir.ONAME: 1868 if n.Ntype != nil { 1869 n.Ntype = typecheckNtype(n.Ntype) 1870 n.SetType(n.Ntype.Type()) 1871 if n.Type() == nil { 1872 n.SetDiag(true) 1873 goto ret 1874 } 1875 } 1876 1877 if n.Type() != nil { 1878 break 1879 } 1880 if n.Defn == nil { 1881 if n.BuiltinOp != 0 { // like OPRINTN 1882 break 1883 } 1884 if base.Errors() > 0 { 1885 // Can have undefined variables in x := foo 1886 // that make x have an n.name.Defn == nil. 1887 // If there are other errors anyway, don't 1888 // bother adding to the noise. 1889 break 1890 } 1891 1892 base.Fatalf("var without type, init: %v", n.Sym()) 1893 } 1894 1895 if n.Defn.Op() == ir.ONAME { 1896 n.Defn = Expr(n.Defn) 1897 n.SetType(n.Defn.Type()) 1898 break 1899 } 1900 1901 n.Defn = Stmt(n.Defn) // fills in n.Type 1902 1903 case ir.OTYPE: 1904 if n.Alias() { 1905 // Type alias declaration: Simply use the rhs type - no need 1906 // to create a new type. 1907 // If we have a syntax error, name.Ntype may be nil. 1908 if n.Ntype != nil { 1909 n.Ntype = typecheckNtype(n.Ntype) 1910 n.SetType(n.Ntype.Type()) 1911 if n.Type() == nil { 1912 n.SetDiag(true) 1913 goto ret 1914 } 1915 } 1916 break 1917 } 1918 1919 // regular type declaration 1920 typecheckdeftype(n) 1921 } 1922 1923ret: 1924 if n.Op() != ir.OLITERAL && n.Type() != nil && n.Type().IsUntyped() { 1925 base.Fatalf("got %v for %v", n.Type(), n) 1926 } 1927 last := len(typecheckdefstack) - 1 1928 if typecheckdefstack[last] != n { 1929 base.Fatalf("typecheckdefstack mismatch") 1930 } 1931 typecheckdefstack[last] = nil 1932 typecheckdefstack = typecheckdefstack[:last] 1933 1934 base.Pos = lno 1935 n.SetWalkdef(1) 1936} 1937 1938func checkmake(t *types.Type, arg string, np *ir.Node) bool { 1939 n := *np 1940 if !n.Type().IsInteger() && n.Type().Kind() != types.TIDEAL { 1941 base.Errorf("non-integer %s argument in make(%v) - %v", arg, t, n.Type()) 1942 return false 1943 } 1944 1945 // Do range checks for constants before DefaultLit 1946 // to avoid redundant "constant NNN overflows int" errors. 1947 if n.Op() == ir.OLITERAL { 1948 v := toint(n.Val()) 1949 if constant.Sign(v) < 0 { 1950 base.Errorf("negative %s argument in make(%v)", arg, t) 1951 return false 1952 } 1953 if ir.ConstOverflow(v, types.Types[types.TINT]) { 1954 base.Errorf("%s argument too large in make(%v)", arg, t) 1955 return false 1956 } 1957 } 1958 1959 // DefaultLit is necessary for non-constants too: n might be 1.1<<k. 1960 // TODO(gri) The length argument requirements for (array/slice) make 1961 // are the same as for index expressions. Factor the code better; 1962 // for instance, indexlit might be called here and incorporate some 1963 // of the bounds checks done for make. 1964 n = DefaultLit(n, types.Types[types.TINT]) 1965 *np = n 1966 1967 return true 1968} 1969 1970// checkunsafeslice is like checkmake but for unsafe.Slice. 1971func checkunsafeslice(np *ir.Node) bool { 1972 n := *np 1973 if !n.Type().IsInteger() && n.Type().Kind() != types.TIDEAL { 1974 base.Errorf("non-integer len argument in unsafe.Slice - %v", n.Type()) 1975 return false 1976 } 1977 1978 // Do range checks for constants before DefaultLit 1979 // to avoid redundant "constant NNN overflows int" errors. 1980 if n.Op() == ir.OLITERAL { 1981 v := toint(n.Val()) 1982 if constant.Sign(v) < 0 { 1983 base.Errorf("negative len argument in unsafe.Slice") 1984 return false 1985 } 1986 if ir.ConstOverflow(v, types.Types[types.TINT]) { 1987 base.Errorf("len argument too large in unsafe.Slice") 1988 return false 1989 } 1990 } 1991 1992 // DefaultLit is necessary for non-constants too: n might be 1.1<<k. 1993 n = DefaultLit(n, types.Types[types.TINT]) 1994 *np = n 1995 1996 return true 1997} 1998 1999// markBreak marks control statements containing break statements with SetHasBreak(true). 2000func markBreak(fn *ir.Func) { 2001 var labels map[*types.Sym]ir.Node 2002 var implicit ir.Node 2003 2004 var mark func(ir.Node) bool 2005 mark = func(n ir.Node) bool { 2006 switch n.Op() { 2007 default: 2008 ir.DoChildren(n, mark) 2009 2010 case ir.OBREAK: 2011 n := n.(*ir.BranchStmt) 2012 if n.Label == nil { 2013 setHasBreak(implicit) 2014 } else { 2015 setHasBreak(labels[n.Label]) 2016 } 2017 2018 case ir.OFOR, ir.OFORUNTIL, ir.OSWITCH, ir.OSELECT, ir.ORANGE: 2019 old := implicit 2020 implicit = n 2021 var sym *types.Sym 2022 switch n := n.(type) { 2023 case *ir.ForStmt: 2024 sym = n.Label 2025 case *ir.RangeStmt: 2026 sym = n.Label 2027 case *ir.SelectStmt: 2028 sym = n.Label 2029 case *ir.SwitchStmt: 2030 sym = n.Label 2031 } 2032 if sym != nil { 2033 if labels == nil { 2034 // Map creation delayed until we need it - most functions don't. 2035 labels = make(map[*types.Sym]ir.Node) 2036 } 2037 labels[sym] = n 2038 } 2039 ir.DoChildren(n, mark) 2040 if sym != nil { 2041 delete(labels, sym) 2042 } 2043 implicit = old 2044 } 2045 return false 2046 } 2047 2048 mark(fn) 2049} 2050 2051func controlLabel(n ir.Node) *types.Sym { 2052 switch n := n.(type) { 2053 default: 2054 base.Fatalf("controlLabel %+v", n.Op()) 2055 return nil 2056 case *ir.ForStmt: 2057 return n.Label 2058 case *ir.RangeStmt: 2059 return n.Label 2060 case *ir.SelectStmt: 2061 return n.Label 2062 case *ir.SwitchStmt: 2063 return n.Label 2064 } 2065} 2066 2067func setHasBreak(n ir.Node) { 2068 switch n := n.(type) { 2069 default: 2070 base.Fatalf("setHasBreak %+v", n.Op()) 2071 case nil: 2072 // ignore 2073 case *ir.ForStmt: 2074 n.HasBreak = true 2075 case *ir.RangeStmt: 2076 n.HasBreak = true 2077 case *ir.SelectStmt: 2078 n.HasBreak = true 2079 case *ir.SwitchStmt: 2080 n.HasBreak = true 2081 } 2082} 2083 2084// isTermNodes reports whether the Nodes list ends with a terminating statement. 2085func isTermNodes(l ir.Nodes) bool { 2086 s := l 2087 c := len(s) 2088 if c == 0 { 2089 return false 2090 } 2091 return isTermNode(s[c-1]) 2092} 2093 2094// isTermNode reports whether the node n, the last one in a 2095// statement list, is a terminating statement. 2096func isTermNode(n ir.Node) bool { 2097 switch n.Op() { 2098 // NOTE: OLABEL is treated as a separate statement, 2099 // not a separate prefix, so skipping to the last statement 2100 // in the block handles the labeled statement case by 2101 // skipping over the label. No case OLABEL here. 2102 2103 case ir.OBLOCK: 2104 n := n.(*ir.BlockStmt) 2105 return isTermNodes(n.List) 2106 2107 case ir.OGOTO, ir.ORETURN, ir.OTAILCALL, ir.OPANIC, ir.OFALL: 2108 return true 2109 2110 case ir.OFOR, ir.OFORUNTIL: 2111 n := n.(*ir.ForStmt) 2112 if n.Cond != nil { 2113 return false 2114 } 2115 if n.HasBreak { 2116 return false 2117 } 2118 return true 2119 2120 case ir.OIF: 2121 n := n.(*ir.IfStmt) 2122 return isTermNodes(n.Body) && isTermNodes(n.Else) 2123 2124 case ir.OSWITCH: 2125 n := n.(*ir.SwitchStmt) 2126 if n.HasBreak { 2127 return false 2128 } 2129 def := false 2130 for _, cas := range n.Cases { 2131 if !isTermNodes(cas.Body) { 2132 return false 2133 } 2134 if len(cas.List) == 0 { // default 2135 def = true 2136 } 2137 } 2138 return def 2139 2140 case ir.OSELECT: 2141 n := n.(*ir.SelectStmt) 2142 if n.HasBreak { 2143 return false 2144 } 2145 for _, cas := range n.Cases { 2146 if !isTermNodes(cas.Body) { 2147 return false 2148 } 2149 } 2150 return true 2151 } 2152 2153 return false 2154} 2155 2156// CheckUnused checks for any declared variables that weren't used. 2157func CheckUnused(fn *ir.Func) { 2158 // Only report unused variables if we haven't seen any type-checking 2159 // errors yet. 2160 if base.Errors() != 0 { 2161 return 2162 } 2163 2164 // Propagate the used flag for typeswitch variables up to the NONAME in its definition. 2165 for _, ln := range fn.Dcl { 2166 if ln.Op() == ir.ONAME && ln.Class == ir.PAUTO && ln.Used() { 2167 if guard, ok := ln.Defn.(*ir.TypeSwitchGuard); ok { 2168 guard.Used = true 2169 } 2170 } 2171 } 2172 2173 for _, ln := range fn.Dcl { 2174 if ln.Op() != ir.ONAME || ln.Class != ir.PAUTO || ln.Used() { 2175 continue 2176 } 2177 if defn, ok := ln.Defn.(*ir.TypeSwitchGuard); ok { 2178 if defn.Used { 2179 continue 2180 } 2181 base.ErrorfAt(defn.Tag.Pos(), "%v declared but not used", ln.Sym()) 2182 defn.Used = true // suppress repeats 2183 } else { 2184 base.ErrorfAt(ln.Pos(), "%v declared but not used", ln.Sym()) 2185 } 2186 } 2187} 2188 2189// CheckReturn makes sure that fn terminates appropriately. 2190func CheckReturn(fn *ir.Func) { 2191 if fn.Type() != nil && fn.Type().NumResults() != 0 && len(fn.Body) != 0 { 2192 markBreak(fn) 2193 if !isTermNodes(fn.Body) { 2194 base.ErrorfAt(fn.Endlineno, "missing return at end of function") 2195 } 2196 } 2197} 2198 2199// getIotaValue returns the current value for "iota", 2200// or -1 if not within a ConstSpec. 2201func getIotaValue() int64 { 2202 if i := len(typecheckdefstack); i > 0 { 2203 if x := typecheckdefstack[i-1]; x.Op() == ir.OLITERAL { 2204 return x.Iota() 2205 } 2206 } 2207 2208 if ir.CurFunc != nil && ir.CurFunc.Iota >= 0 { 2209 return ir.CurFunc.Iota 2210 } 2211 2212 return -1 2213} 2214 2215// curpkg returns the current package, based on Curfn. 2216func curpkg() *types.Pkg { 2217 fn := ir.CurFunc 2218 if fn == nil { 2219 // Initialization expressions for package-scope variables. 2220 return types.LocalPkg 2221 } 2222 return fnpkg(fn.Nname) 2223} 2224 2225func Conv(n ir.Node, t *types.Type) ir.Node { 2226 if types.Identical(n.Type(), t) { 2227 return n 2228 } 2229 n = ir.NewConvExpr(base.Pos, ir.OCONV, nil, n) 2230 n.SetType(t) 2231 n = Expr(n) 2232 return n 2233} 2234 2235// ConvNop converts node n to type t using the OCONVNOP op 2236// and typechecks the result with ctxExpr. 2237func ConvNop(n ir.Node, t *types.Type) ir.Node { 2238 if types.Identical(n.Type(), t) { 2239 return n 2240 } 2241 n = ir.NewConvExpr(base.Pos, ir.OCONVNOP, nil, n) 2242 n.SetType(t) 2243 n = Expr(n) 2244 return n 2245} 2246