github.com/rsc/go@v0.0.0-20150416155037-e040fd465409/src/cmd/internal/gc/typecheck.go (about) 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 gc 6 7 import ( 8 "cmd/internal/obj" 9 "fmt" 10 "math" 11 "strings" 12 ) 13 14 /* 15 * type check the whole tree of an expression. 16 * calculates expression types. 17 * evaluates compile time constants. 18 * marks variables that escape the local frame. 19 * rewrites n->op to be more specific in some cases. 20 */ 21 var typecheckdefstack *NodeList 22 23 /* 24 * resolve ONONAME to definition, if any. 25 */ 26 func resolve(n *Node) *Node { 27 if n != nil && n.Op == ONONAME && n.Sym != nil { 28 r := n.Sym.Def 29 if r != nil { 30 if r.Op != OIOTA { 31 n = r 32 } else if n.Iota >= 0 { 33 n = Nodintconst(int64(n.Iota)) 34 } 35 } 36 } 37 38 return n 39 } 40 41 func typechecklist(l *NodeList, top int) { 42 for ; l != nil; l = l.Next { 43 typecheck(&l.N, top) 44 } 45 } 46 47 var _typekind = []string{ 48 TINT: "int", 49 TUINT: "uint", 50 TINT8: "int8", 51 TUINT8: "uint8", 52 TINT16: "int16", 53 TUINT16: "uint16", 54 TINT32: "int32", 55 TUINT32: "uint32", 56 TINT64: "int64", 57 TUINT64: "uint64", 58 TUINTPTR: "uintptr", 59 TCOMPLEX64: "complex64", 60 TCOMPLEX128: "complex128", 61 TFLOAT32: "float32", 62 TFLOAT64: "float64", 63 TBOOL: "bool", 64 TSTRING: "string", 65 TPTR32: "pointer", 66 TPTR64: "pointer", 67 TUNSAFEPTR: "unsafe.Pointer", 68 TSTRUCT: "struct", 69 TINTER: "interface", 70 TCHAN: "chan", 71 TMAP: "map", 72 TARRAY: "array", 73 TFUNC: "func", 74 TNIL: "nil", 75 TIDEAL: "untyped number", 76 } 77 78 var typekind_buf string 79 80 func typekind(t *Type) string { 81 if Isslice(t) { 82 return "slice" 83 } 84 et := int(t.Etype) 85 if 0 <= et && et < len(_typekind) { 86 s := _typekind[et] 87 if s != "" { 88 return s 89 } 90 } 91 typekind_buf = fmt.Sprintf("etype=%d", et) 92 return typekind_buf 93 } 94 95 /* 96 * sprint_depchain prints a dependency chain 97 * of nodes into fmt. 98 * It is used by typecheck in the case of OLITERAL nodes 99 * to print constant definition loops. 100 */ 101 func sprint_depchain(fmt_ *string, stack *NodeList, cur *Node, first *Node) { 102 for l := stack; l != nil; l = l.Next { 103 if l.N.Op == cur.Op { 104 if l.N != first { 105 sprint_depchain(fmt_, l.Next, l.N, first) 106 } 107 *fmt_ += fmt.Sprintf("\n\t%v: %v uses %v", l.N.Line(), Nconv(l.N, 0), Nconv(cur, 0)) 108 return 109 } 110 } 111 } 112 113 /* 114 * type check node *np. 115 * replaces *np with a new pointer in some cases. 116 * returns the final value of *np as a convenience. 117 */ 118 119 var typecheck_tcstack *NodeList 120 var typecheck_tcfree *NodeList 121 122 func typecheck(np **Node, top int) *Node { 123 // cannot type check until all the source has been parsed 124 if typecheckok == 0 { 125 Fatal("early typecheck") 126 } 127 128 n := *np 129 if n == nil { 130 return nil 131 } 132 133 lno := int(setlineno(n)) 134 135 // Skip over parens. 136 for n.Op == OPAREN { 137 n = n.Left 138 } 139 140 // Resolve definition of name and value of iota lazily. 141 n = resolve(n) 142 143 *np = n 144 145 // Skip typecheck if already done. 146 // But re-typecheck ONAME/OTYPE/OLITERAL/OPACK node in case context has changed. 147 if n.Typecheck == 1 { 148 switch n.Op { 149 case ONAME, OTYPE, OLITERAL, OPACK: 150 break 151 152 default: 153 lineno = int32(lno) 154 return n 155 } 156 } 157 158 if n.Typecheck == 2 { 159 // Typechecking loop. Trying printing a meaningful message, 160 // otherwise a stack trace of typechecking. 161 var fmt_ string 162 switch n.Op { 163 // We can already diagnose variables used as types. 164 case ONAME: 165 if top&(Erv|Etype) == Etype { 166 Yyerror("%v is not a type", Nconv(n, 0)) 167 } 168 169 case OLITERAL: 170 if top&(Erv|Etype) == Etype { 171 Yyerror("%v is not a type", Nconv(n, 0)) 172 break 173 } 174 175 fmt_ = "" 176 sprint_depchain(&fmt_, typecheck_tcstack, n, n) 177 yyerrorl(int(n.Lineno), "constant definition loop%s", fmt_) 178 } 179 180 if nsavederrors+nerrors == 0 { 181 fmt_ = "" 182 for l := typecheck_tcstack; l != nil; l = l.Next { 183 fmt_ += fmt.Sprintf("\n\t%v %v", l.N.Line(), Nconv(l.N, 0)) 184 } 185 Yyerror("typechecking loop involving %v%s", Nconv(n, 0), fmt_) 186 } 187 188 lineno = int32(lno) 189 return n 190 } 191 192 n.Typecheck = 2 193 194 var l *NodeList 195 if typecheck_tcfree != nil { 196 l = typecheck_tcfree 197 typecheck_tcfree = l.Next 198 } else { 199 l = new(NodeList) 200 } 201 l.Next = typecheck_tcstack 202 l.N = n 203 typecheck_tcstack = l 204 205 typecheck1(&n, top) 206 *np = n 207 n.Typecheck = 1 208 209 if typecheck_tcstack != l { 210 Fatal("typecheck stack out of sync") 211 } 212 typecheck_tcstack = l.Next 213 l.Next = typecheck_tcfree 214 typecheck_tcfree = l 215 216 lineno = int32(lno) 217 return n 218 } 219 220 /* 221 * does n contain a call or receive operation? 222 */ 223 func callrecv(n *Node) bool { 224 if n == nil { 225 return false 226 } 227 228 switch n.Op { 229 case OCALL, 230 OCALLMETH, 231 OCALLINTER, 232 OCALLFUNC, 233 ORECV, 234 OCAP, 235 OLEN, 236 OCOPY, 237 ONEW, 238 OAPPEND, 239 ODELETE: 240 return true 241 } 242 243 return callrecv(n.Left) || callrecv(n.Right) || callrecv(n.Ntest) || callrecv(n.Nincr) || callrecvlist(n.Ninit) || callrecvlist(n.Nbody) || callrecvlist(n.Nelse) || callrecvlist(n.List) || callrecvlist(n.Rlist) 244 } 245 246 func callrecvlist(l *NodeList) bool { 247 for ; l != nil; l = l.Next { 248 if callrecv(l.N) { 249 return true 250 } 251 } 252 return false 253 } 254 255 // indexlit implements typechecking of untyped values as 256 // array/slice indexes. It is equivalent to defaultlit 257 // except for constants of numerical kind, which are acceptable 258 // whenever they can be represented by a value of type int. 259 func indexlit(np **Node) { 260 n := *np 261 if n == nil || !isideal(n.Type) { 262 return 263 } 264 switch consttype(n) { 265 case CTINT, CTRUNE, CTFLT, CTCPLX: 266 defaultlit(np, Types[TINT]) 267 } 268 269 defaultlit(np, nil) 270 } 271 272 func typecheck1(np **Node, top int) { 273 n := *np 274 defer func() { 275 *np = n 276 }() 277 278 if n.Sym != nil { 279 if n.Op == ONAME && n.Etype != 0 && top&Ecall == 0 { 280 Yyerror("use of builtin %v not in function call", Sconv(n.Sym, 0)) 281 n.Type = nil 282 return 283 } 284 285 typecheckdef(n) 286 if n.Op == ONONAME { 287 n.Type = nil 288 return 289 } 290 } 291 292 ok := 0 293 OpSwitch: 294 switch n.Op { 295 // until typecheck is complete, do nothing. 296 default: 297 Dump("typecheck", n) 298 299 Fatal("typecheck %v", Oconv(int(n.Op), 0)) 300 301 /* 302 * names 303 */ 304 case OLITERAL: 305 ok |= Erv 306 307 if n.Type == nil && n.Val.Ctype == CTSTR { 308 n.Type = idealstring 309 } 310 break OpSwitch 311 312 case ONONAME: 313 ok |= Erv 314 break OpSwitch 315 316 case ONAME: 317 if n.Decldepth == 0 { 318 n.Decldepth = decldepth 319 } 320 if n.Etype != 0 { 321 ok |= Ecall 322 break OpSwitch 323 } 324 325 if top&Easgn == 0 { 326 // not a write to the variable 327 if isblank(n) { 328 Yyerror("cannot use _ as value") 329 n.Type = nil 330 return 331 } 332 333 n.Used = true 334 } 335 336 if top&Ecall == 0 && isunsafebuiltin(n) { 337 Yyerror("%v is not an expression, must be called", Nconv(n, 0)) 338 n.Type = nil 339 return 340 } 341 342 ok |= Erv 343 break OpSwitch 344 345 case OPACK: 346 Yyerror("use of package %v without selector", Sconv(n.Sym, 0)) 347 n.Type = nil 348 return 349 350 case ODDD: 351 break 352 353 /* 354 * types (OIND is with exprs) 355 */ 356 case OTYPE: 357 ok |= Etype 358 359 if n.Type == nil { 360 n.Type = nil 361 return 362 } 363 364 case OTARRAY: 365 ok |= Etype 366 t := typ(TARRAY) 367 l := n.Left 368 r := n.Right 369 if l == nil { 370 t.Bound = -1 // slice 371 } else if l.Op == ODDD { 372 t.Bound = -100 // to be filled in 373 if top&Ecomplit == 0 && n.Diag == 0 { 374 t.Broke = 1 375 n.Diag = 1 376 Yyerror("use of [...] array outside of array literal") 377 } 378 } else { 379 l := typecheck(&n.Left, Erv) 380 var v Val 381 switch consttype(l) { 382 case CTINT, CTRUNE: 383 v = l.Val 384 385 case CTFLT: 386 v = toint(l.Val) 387 388 default: 389 if l.Type != nil && Isint[l.Type.Etype] && l.Op != OLITERAL { 390 Yyerror("non-constant array bound %v", Nconv(l, 0)) 391 } else { 392 Yyerror("invalid array bound %v", Nconv(l, 0)) 393 } 394 n.Type = nil 395 return 396 } 397 398 t.Bound = Mpgetfix(v.U.Xval) 399 if doesoverflow(v, Types[TINT]) { 400 Yyerror("array bound is too large") 401 n.Type = nil 402 return 403 } else if t.Bound < 0 { 404 Yyerror("array bound must be non-negative") 405 n.Type = nil 406 return 407 } 408 } 409 410 typecheck(&r, Etype) 411 if r.Type == nil { 412 n.Type = nil 413 return 414 } 415 t.Type = r.Type 416 n.Op = OTYPE 417 n.Type = t 418 n.Left = nil 419 n.Right = nil 420 if t.Bound != -100 { 421 checkwidth(t) 422 } 423 424 case OTMAP: 425 ok |= Etype 426 l := typecheck(&n.Left, Etype) 427 r := typecheck(&n.Right, Etype) 428 if l.Type == nil || r.Type == nil { 429 n.Type = nil 430 return 431 } 432 n.Op = OTYPE 433 n.Type = maptype(l.Type, r.Type) 434 n.Left = nil 435 n.Right = nil 436 437 case OTCHAN: 438 ok |= Etype 439 l := typecheck(&n.Left, Etype) 440 if l.Type == nil { 441 n.Type = nil 442 return 443 } 444 t := typ(TCHAN) 445 t.Type = l.Type 446 t.Chan = n.Etype 447 n.Op = OTYPE 448 n.Type = t 449 n.Left = nil 450 n.Etype = 0 451 452 case OTSTRUCT: 453 ok |= Etype 454 n.Op = OTYPE 455 n.Type = tostruct(n.List) 456 if n.Type == nil || n.Type.Broke != 0 { 457 n.Type = nil 458 return 459 } 460 n.List = nil 461 462 case OTINTER: 463 ok |= Etype 464 n.Op = OTYPE 465 n.Type = tointerface(n.List) 466 if n.Type == nil { 467 n.Type = nil 468 return 469 } 470 471 case OTFUNC: 472 ok |= Etype 473 n.Op = OTYPE 474 n.Type = functype(n.Left, n.List, n.Rlist) 475 if n.Type == nil { 476 n.Type = nil 477 return 478 } 479 480 /* 481 * type or expr 482 */ 483 case OIND: 484 ntop := Erv | Etype 485 486 if top&Eaddr == 0 { // The *x in &*x is not an indirect. 487 ntop |= Eindir 488 } 489 ntop |= top & Ecomplit 490 l := typecheck(&n.Left, ntop) 491 t := l.Type 492 if t == nil { 493 n.Type = nil 494 return 495 } 496 if l.Op == OTYPE { 497 ok |= Etype 498 n.Op = OTYPE 499 n.Type = Ptrto(l.Type) 500 n.Left = nil 501 break OpSwitch 502 } 503 504 if !Isptr[t.Etype] { 505 if top&(Erv|Etop) != 0 { 506 Yyerror("invalid indirect of %v", Nconv(n.Left, obj.FmtLong)) 507 n.Type = nil 508 return 509 } 510 511 break OpSwitch 512 } 513 514 ok |= Erv 515 n.Type = t.Type 516 break OpSwitch 517 518 /* 519 * arithmetic exprs 520 */ 521 case OASOP, 522 OADD, 523 OAND, 524 OANDAND, 525 OANDNOT, 526 ODIV, 527 OEQ, 528 OGE, 529 OGT, 530 OLE, 531 OLT, 532 OLSH, 533 ORSH, 534 OMOD, 535 OMUL, 536 ONE, 537 OOR, 538 OOROR, 539 OSUB, 540 OXOR: 541 var l *Node 542 var op int 543 var r *Node 544 if n.Op == OASOP { 545 ok |= Etop 546 l = typecheck(&n.Left, Erv) 547 r = typecheck(&n.Right, Erv) 548 checkassign(n, n.Left) 549 if l.Type == nil || r.Type == nil { 550 n.Type = nil 551 return 552 } 553 op = int(n.Etype) 554 } else { 555 ok |= Erv 556 l = typecheck(&n.Left, Erv|top&Eiota) 557 r = typecheck(&n.Right, Erv|top&Eiota) 558 if l.Type == nil || r.Type == nil { 559 n.Type = nil 560 return 561 } 562 op = int(n.Op) 563 } 564 if op == OLSH || op == ORSH { 565 defaultlit(&r, Types[TUINT]) 566 n.Right = r 567 t := r.Type 568 if !Isint[t.Etype] || Issigned[t.Etype] { 569 Yyerror("invalid operation: %v (shift count type %v, must be unsigned integer)", Nconv(n, 0), Tconv(r.Type, 0)) 570 n.Type = nil 571 return 572 } 573 574 t = l.Type 575 if t != nil && t.Etype != TIDEAL && !Isint[t.Etype] { 576 Yyerror("invalid operation: %v (shift of type %v)", Nconv(n, 0), Tconv(t, 0)) 577 n.Type = nil 578 return 579 } 580 581 // no defaultlit for left 582 // the outer context gives the type 583 n.Type = l.Type 584 585 break OpSwitch 586 } 587 588 // ideal mixed with non-ideal 589 defaultlit2(&l, &r, 0) 590 591 n.Left = l 592 n.Right = r 593 if l.Type == nil || r.Type == nil { 594 n.Type = nil 595 return 596 } 597 t := l.Type 598 if t.Etype == TIDEAL { 599 t = r.Type 600 } 601 et := int(t.Etype) 602 if et == TIDEAL { 603 et = TINT 604 } 605 aop := 0 606 if iscmp[n.Op] && t.Etype != TIDEAL && !Eqtype(l.Type, r.Type) { 607 // comparison is okay as long as one side is 608 // assignable to the other. convert so they have 609 // the same type. 610 // 611 // the only conversion that isn't a no-op is concrete == interface. 612 // in that case, check comparability of the concrete type. 613 // The conversion allocates, so only do it if the concrete type is huge. 614 if r.Type.Etype != TBLANK { 615 aop = assignop(l.Type, r.Type, nil) 616 if aop != 0 { 617 if Isinter(r.Type) && !Isinter(l.Type) && algtype1(l.Type, nil) == ANOEQ { 618 Yyerror("invalid operation: %v (operator %v not defined on %s)", Nconv(n, 0), Oconv(int(op), 0), typekind(l.Type)) 619 n.Type = nil 620 return 621 } 622 623 dowidth(l.Type) 624 if Isinter(r.Type) == Isinter(l.Type) || l.Type.Width >= 1<<16 { 625 l = Nod(aop, l, nil) 626 l.Type = r.Type 627 l.Typecheck = 1 628 n.Left = l 629 } 630 631 t = r.Type 632 goto converted 633 } 634 } 635 636 if l.Type.Etype != TBLANK { 637 aop = assignop(r.Type, l.Type, nil) 638 if aop != 0 { 639 if Isinter(l.Type) && !Isinter(r.Type) && algtype1(r.Type, nil) == ANOEQ { 640 Yyerror("invalid operation: %v (operator %v not defined on %s)", Nconv(n, 0), Oconv(int(op), 0), typekind(r.Type)) 641 n.Type = nil 642 return 643 } 644 645 dowidth(r.Type) 646 if Isinter(r.Type) == Isinter(l.Type) || r.Type.Width >= 1<<16 { 647 r = Nod(aop, r, nil) 648 r.Type = l.Type 649 r.Typecheck = 1 650 n.Right = r 651 } 652 653 t = l.Type 654 } 655 } 656 657 converted: 658 et = int(t.Etype) 659 } 660 661 if t.Etype != TIDEAL && !Eqtype(l.Type, r.Type) { 662 defaultlit2(&l, &r, 1) 663 if n.Op == OASOP && n.Implicit { 664 Yyerror("invalid operation: %v (non-numeric type %v)", Nconv(n, 0), Tconv(l.Type, 0)) 665 n.Type = nil 666 return 667 } 668 669 if Isinter(r.Type) == Isinter(l.Type) || aop == 0 { 670 Yyerror("invalid operation: %v (mismatched types %v and %v)", Nconv(n, 0), Tconv(l.Type, 0), Tconv(r.Type, 0)) 671 n.Type = nil 672 return 673 } 674 } 675 676 if !okfor[op][et] { 677 Yyerror("invalid operation: %v (operator %v not defined on %s)", Nconv(n, 0), Oconv(int(op), 0), typekind(t)) 678 n.Type = nil 679 return 680 } 681 682 // okfor allows any array == array, map == map, func == func. 683 // restrict to slice/map/func == nil and nil == slice/map/func. 684 if Isfixedarray(l.Type) && algtype1(l.Type, nil) == ANOEQ { 685 Yyerror("invalid operation: %v (%v cannot be compared)", Nconv(n, 0), Tconv(l.Type, 0)) 686 n.Type = nil 687 return 688 } 689 690 if Isslice(l.Type) && !isnil(l) && !isnil(r) { 691 Yyerror("invalid operation: %v (slice can only be compared to nil)", Nconv(n, 0)) 692 n.Type = nil 693 return 694 } 695 696 if l.Type.Etype == TMAP && !isnil(l) && !isnil(r) { 697 Yyerror("invalid operation: %v (map can only be compared to nil)", Nconv(n, 0)) 698 n.Type = nil 699 return 700 } 701 702 if l.Type.Etype == TFUNC && !isnil(l) && !isnil(r) { 703 Yyerror("invalid operation: %v (func can only be compared to nil)", Nconv(n, 0)) 704 n.Type = nil 705 return 706 } 707 708 var badtype *Type 709 if l.Type.Etype == TSTRUCT && algtype1(l.Type, &badtype) == ANOEQ { 710 Yyerror("invalid operation: %v (struct containing %v cannot be compared)", Nconv(n, 0), Tconv(badtype, 0)) 711 n.Type = nil 712 return 713 } 714 715 t = l.Type 716 if iscmp[n.Op] { 717 evconst(n) 718 t = idealbool 719 if n.Op != OLITERAL { 720 defaultlit2(&l, &r, 1) 721 n.Left = l 722 n.Right = r 723 } 724 } else if n.Op == OANDAND || n.Op == OOROR { 725 if l.Type == r.Type { 726 t = l.Type 727 } else if l.Type == idealbool { 728 t = r.Type 729 } else if r.Type == idealbool { 730 t = l.Type 731 } 732 } else 733 // non-comparison operators on ideal bools should make them lose their ideal-ness 734 if t == idealbool { 735 t = Types[TBOOL] 736 } 737 738 if et == TSTRING { 739 if iscmp[n.Op] { 740 n.Etype = n.Op 741 n.Op = OCMPSTR 742 } else if n.Op == OADD { 743 // create OADDSTR node with list of strings in x + y + z + (w + v) + ... 744 n.Op = OADDSTR 745 746 if l.Op == OADDSTR { 747 n.List = l.List 748 } else { 749 n.List = list1(l) 750 } 751 if r.Op == OADDSTR { 752 n.List = concat(n.List, r.List) 753 } else { 754 n.List = list(n.List, r) 755 } 756 n.Left = nil 757 n.Right = nil 758 } 759 } 760 761 if et == TINTER { 762 if l.Op == OLITERAL && l.Val.Ctype == CTNIL { 763 // swap for back end 764 n.Left = r 765 766 n.Right = l 767 } else if r.Op == OLITERAL && r.Val.Ctype == CTNIL { 768 } else // leave alone for back end 769 if Isinter(r.Type) == Isinter(l.Type) { 770 n.Etype = n.Op 771 n.Op = OCMPIFACE 772 } 773 } 774 775 if (op == ODIV || op == OMOD) && Isconst(r, CTINT) { 776 if mpcmpfixc(r.Val.U.Xval, 0) == 0 { 777 Yyerror("division by zero") 778 n.Type = nil 779 return 780 } 781 } 782 783 n.Type = t 784 break OpSwitch 785 786 case OCOM, OMINUS, ONOT, OPLUS: 787 ok |= Erv 788 l := typecheck(&n.Left, Erv|top&Eiota) 789 t := l.Type 790 if t == nil { 791 n.Type = nil 792 return 793 } 794 if !okfor[n.Op][t.Etype] { 795 Yyerror("invalid operation: %v %v", Oconv(int(n.Op), 0), Tconv(t, 0)) 796 n.Type = nil 797 return 798 } 799 800 n.Type = t 801 break OpSwitch 802 803 /* 804 * exprs 805 */ 806 case OADDR: 807 ok |= Erv 808 809 typecheck(&n.Left, Erv|Eaddr) 810 if n.Left.Type == nil { 811 n.Type = nil 812 return 813 } 814 checklvalue(n.Left, "take the address of") 815 r := outervalue(n.Left) 816 var l *Node 817 for l = n.Left; l != r; l = l.Left { 818 l.Addrtaken = true 819 if l.Closure != nil { 820 l.Closure.Addrtaken = true 821 } 822 } 823 824 if l.Orig != l && l.Op == ONAME { 825 Fatal("found non-orig name node %v", Nconv(l, 0)) 826 } 827 l.Addrtaken = true 828 if l.Closure != nil { 829 l.Closure.Addrtaken = true 830 } 831 defaultlit(&n.Left, nil) 832 l = n.Left 833 t := l.Type 834 if t == nil { 835 n.Type = nil 836 return 837 } 838 n.Type = Ptrto(t) 839 break OpSwitch 840 841 case OCOMPLIT: 842 ok |= Erv 843 typecheckcomplit(&n) 844 if n.Type == nil { 845 n.Type = nil 846 return 847 } 848 break OpSwitch 849 850 case OXDOT, ODOT: 851 if n.Op == OXDOT { 852 n = adddot(n) 853 n.Op = ODOT 854 if n.Left == nil { 855 n.Type = nil 856 return 857 } 858 } 859 860 typecheck(&n.Left, Erv|Etype) 861 862 defaultlit(&n.Left, nil) 863 if n.Right.Op != ONAME { 864 Yyerror("rhs of . must be a name") // impossible 865 n.Type = nil 866 return 867 } 868 869 t := n.Left.Type 870 if t == nil { 871 adderrorname(n) 872 n.Type = nil 873 return 874 } 875 876 r := n.Right 877 878 if n.Left.Op == OTYPE { 879 if !looktypedot(n, t, 0) { 880 if looktypedot(n, t, 1) { 881 Yyerror("%v undefined (cannot refer to unexported method %v)", Nconv(n, 0), Sconv(n.Right.Sym, 0)) 882 } else { 883 Yyerror("%v undefined (type %v has no method %v)", Nconv(n, 0), Tconv(t, 0), Sconv(n.Right.Sym, 0)) 884 } 885 n.Type = nil 886 return 887 } 888 889 if n.Type.Etype != TFUNC || n.Type.Thistuple != 1 { 890 Yyerror("type %v has no method %v", Tconv(n.Left.Type, 0), Sconv(n.Right.Sym, obj.FmtShort)) 891 n.Type = nil 892 n.Type = nil 893 return 894 } 895 896 n.Op = ONAME 897 n.Sym = n.Right.Sym 898 n.Type = methodfunc(n.Type, n.Left.Type) 899 n.Xoffset = 0 900 n.Class = PFUNC 901 ok = Erv 902 break OpSwitch 903 } 904 905 if Isptr[t.Etype] && t.Type.Etype != TINTER { 906 t = t.Type 907 if t == nil { 908 n.Type = nil 909 return 910 } 911 n.Op = ODOTPTR 912 checkwidth(t) 913 } 914 915 if isblank(n.Right) { 916 Yyerror("cannot refer to blank field or method") 917 n.Type = nil 918 return 919 } 920 921 if !lookdot(n, t, 0) { 922 if lookdot(n, t, 1) { 923 Yyerror("%v undefined (cannot refer to unexported field or method %v)", Nconv(n, 0), Sconv(n.Right.Sym, 0)) 924 } else { 925 Yyerror("%v undefined (type %v has no field or method %v)", Nconv(n, 0), Tconv(n.Left.Type, 0), Sconv(n.Right.Sym, 0)) 926 } 927 n.Type = nil 928 return 929 } 930 931 switch n.Op { 932 case ODOTINTER, ODOTMETH: 933 if top&Ecall != 0 { 934 ok |= Ecall 935 } else { 936 typecheckpartialcall(n, r) 937 ok |= Erv 938 } 939 940 default: 941 ok |= Erv 942 } 943 944 break OpSwitch 945 946 case ODOTTYPE: 947 ok |= Erv 948 typecheck(&n.Left, Erv) 949 defaultlit(&n.Left, nil) 950 l := n.Left 951 t := l.Type 952 if t == nil { 953 n.Type = nil 954 return 955 } 956 if !Isinter(t) { 957 Yyerror("invalid type assertion: %v (non-interface type %v on left)", Nconv(n, 0), Tconv(t, 0)) 958 n.Type = nil 959 return 960 } 961 962 if n.Right != nil { 963 typecheck(&n.Right, Etype) 964 n.Type = n.Right.Type 965 n.Right = nil 966 if n.Type == nil { 967 n.Type = nil 968 return 969 } 970 } 971 972 if n.Type != nil && n.Type.Etype != TINTER { 973 var have *Type 974 var missing *Type 975 var ptr int 976 if !implements(n.Type, t, &missing, &have, &ptr) { 977 if have != nil && have.Sym == missing.Sym { 978 Yyerror("impossible type assertion:\n\t%v does not implement %v (wrong type for %v method)\n"+"\t\thave %v%v\n\t\twant %v%v", Tconv(n.Type, 0), Tconv(t, 0), Sconv(missing.Sym, 0), Sconv(have.Sym, 0), Tconv(have.Type, obj.FmtShort|obj.FmtByte), Sconv(missing.Sym, 0), Tconv(missing.Type, obj.FmtShort|obj.FmtByte)) 979 } else if ptr != 0 { 980 Yyerror("impossible type assertion:\n\t%v does not implement %v (%v method has pointer receiver)", Tconv(n.Type, 0), Tconv(t, 0), Sconv(missing.Sym, 0)) 981 } else if have != nil { 982 Yyerror("impossible type assertion:\n\t%v does not implement %v (missing %v method)\n"+"\t\thave %v%v\n\t\twant %v%v", Tconv(n.Type, 0), Tconv(t, 0), Sconv(missing.Sym, 0), Sconv(have.Sym, 0), Tconv(have.Type, obj.FmtShort|obj.FmtByte), Sconv(missing.Sym, 0), Tconv(missing.Type, obj.FmtShort|obj.FmtByte)) 983 } else { 984 Yyerror("impossible type assertion:\n\t%v does not implement %v (missing %v method)", Tconv(n.Type, 0), Tconv(t, 0), Sconv(missing.Sym, 0)) 985 } 986 n.Type = nil 987 return 988 } 989 } 990 991 break OpSwitch 992 993 case OINDEX: 994 ok |= Erv 995 typecheck(&n.Left, Erv) 996 defaultlit(&n.Left, nil) 997 implicitstar(&n.Left) 998 l := n.Left 999 typecheck(&n.Right, Erv) 1000 r := n.Right 1001 t := l.Type 1002 if t == nil || r.Type == nil { 1003 n.Type = nil 1004 return 1005 } 1006 switch t.Etype { 1007 default: 1008 Yyerror("invalid operation: %v (type %v does not support indexing)", Nconv(n, 0), Tconv(t, 0)) 1009 n.Type = nil 1010 return 1011 1012 case TSTRING, TARRAY: 1013 indexlit(&n.Right) 1014 if t.Etype == TSTRING { 1015 n.Type = Types[TUINT8] 1016 } else { 1017 n.Type = t.Type 1018 } 1019 why := "string" 1020 if t.Etype == TARRAY { 1021 if Isfixedarray(t) { 1022 why = "array" 1023 } else { 1024 why = "slice" 1025 } 1026 } 1027 1028 if n.Right.Type != nil && !Isint[n.Right.Type.Etype] { 1029 Yyerror("non-integer %s index %v", why, Nconv(n.Right, 0)) 1030 break 1031 } 1032 1033 if Isconst(n.Right, CTINT) { 1034 x := Mpgetfix(n.Right.Val.U.Xval) 1035 if x < 0 { 1036 Yyerror("invalid %s index %v (index must be non-negative)", why, Nconv(n.Right, 0)) 1037 } else if Isfixedarray(t) && t.Bound > 0 && x >= t.Bound { 1038 Yyerror("invalid array index %v (out of bounds for %d-element array)", Nconv(n.Right, 0), t.Bound) 1039 } else if Isconst(n.Left, CTSTR) && x >= int64(len(n.Left.Val.U.Sval)) { 1040 Yyerror("invalid string index %v (out of bounds for %d-byte string)", Nconv(n.Right, 0), len(n.Left.Val.U.Sval)) 1041 } else if Mpcmpfixfix(n.Right.Val.U.Xval, Maxintval[TINT]) > 0 { 1042 Yyerror("invalid %s index %v (index too large)", why, Nconv(n.Right, 0)) 1043 } 1044 } 1045 1046 case TMAP: 1047 n.Etype = 0 1048 defaultlit(&n.Right, t.Down) 1049 if n.Right.Type != nil { 1050 n.Right = assignconv(n.Right, t.Down, "map index") 1051 } 1052 n.Type = t.Type 1053 n.Op = OINDEXMAP 1054 } 1055 1056 break OpSwitch 1057 1058 case ORECV: 1059 ok |= Etop | Erv 1060 typecheck(&n.Left, Erv) 1061 defaultlit(&n.Left, nil) 1062 l := n.Left 1063 t := l.Type 1064 if t == nil { 1065 n.Type = nil 1066 return 1067 } 1068 if t.Etype != TCHAN { 1069 Yyerror("invalid operation: %v (receive from non-chan type %v)", Nconv(n, 0), Tconv(t, 0)) 1070 n.Type = nil 1071 return 1072 } 1073 1074 if t.Chan&Crecv == 0 { 1075 Yyerror("invalid operation: %v (receive from send-only type %v)", Nconv(n, 0), Tconv(t, 0)) 1076 n.Type = nil 1077 return 1078 } 1079 1080 n.Type = t.Type 1081 break OpSwitch 1082 1083 case OSEND: 1084 ok |= Etop 1085 l := typecheck(&n.Left, Erv) 1086 typecheck(&n.Right, Erv) 1087 defaultlit(&n.Left, nil) 1088 l = n.Left 1089 t := l.Type 1090 if t == nil { 1091 n.Type = nil 1092 return 1093 } 1094 if t.Etype != TCHAN { 1095 Yyerror("invalid operation: %v (send to non-chan type %v)", Nconv(n, 0), Tconv(t, 0)) 1096 n.Type = nil 1097 return 1098 } 1099 1100 if t.Chan&Csend == 0 { 1101 Yyerror("invalid operation: %v (send to receive-only type %v)", Nconv(n, 0), Tconv(t, 0)) 1102 n.Type = nil 1103 return 1104 } 1105 1106 defaultlit(&n.Right, t.Type) 1107 r := n.Right 1108 if r.Type == nil { 1109 n.Type = nil 1110 return 1111 } 1112 n.Right = assignconv(r, l.Type.Type, "send") 1113 1114 // TODO: more aggressive 1115 n.Etype = 0 1116 1117 n.Type = nil 1118 break OpSwitch 1119 1120 case OSLICE: 1121 ok |= Erv 1122 typecheck(&n.Left, top) 1123 typecheck(&n.Right.Left, Erv) 1124 typecheck(&n.Right.Right, Erv) 1125 defaultlit(&n.Left, nil) 1126 indexlit(&n.Right.Left) 1127 indexlit(&n.Right.Right) 1128 l := n.Left 1129 if Isfixedarray(l.Type) { 1130 if !islvalue(n.Left) { 1131 Yyerror("invalid operation %v (slice of unaddressable value)", Nconv(n, 0)) 1132 n.Type = nil 1133 return 1134 } 1135 1136 n.Left = Nod(OADDR, n.Left, nil) 1137 n.Left.Implicit = true 1138 typecheck(&n.Left, Erv) 1139 l = n.Left 1140 } 1141 1142 t := l.Type 1143 if t == nil { 1144 n.Type = nil 1145 return 1146 } 1147 var tp *Type 1148 if Istype(t, TSTRING) { 1149 n.Type = t 1150 n.Op = OSLICESTR 1151 } else if Isptr[t.Etype] && Isfixedarray(t.Type) { 1152 tp = t.Type 1153 n.Type = typ(TARRAY) 1154 n.Type.Type = tp.Type 1155 n.Type.Bound = -1 1156 dowidth(n.Type) 1157 n.Op = OSLICEARR 1158 } else if Isslice(t) { 1159 n.Type = t 1160 } else { 1161 Yyerror("cannot slice %v (type %v)", Nconv(l, 0), Tconv(t, 0)) 1162 n.Type = nil 1163 return 1164 } 1165 1166 lo := n.Right.Left 1167 if lo != nil && checksliceindex(l, lo, tp) < 0 { 1168 n.Type = nil 1169 return 1170 } 1171 hi := n.Right.Right 1172 if hi != nil && checksliceindex(l, hi, tp) < 0 { 1173 n.Type = nil 1174 return 1175 } 1176 if checksliceconst(lo, hi) < 0 { 1177 n.Type = nil 1178 return 1179 } 1180 break OpSwitch 1181 1182 case OSLICE3: 1183 ok |= Erv 1184 typecheck(&n.Left, top) 1185 typecheck(&n.Right.Left, Erv) 1186 typecheck(&n.Right.Right.Left, Erv) 1187 typecheck(&n.Right.Right.Right, Erv) 1188 defaultlit(&n.Left, nil) 1189 indexlit(&n.Right.Left) 1190 indexlit(&n.Right.Right.Left) 1191 indexlit(&n.Right.Right.Right) 1192 l := n.Left 1193 if Isfixedarray(l.Type) { 1194 if !islvalue(n.Left) { 1195 Yyerror("invalid operation %v (slice of unaddressable value)", Nconv(n, 0)) 1196 n.Type = nil 1197 return 1198 } 1199 1200 n.Left = Nod(OADDR, n.Left, nil) 1201 n.Left.Implicit = true 1202 typecheck(&n.Left, Erv) 1203 l = n.Left 1204 } 1205 1206 t := l.Type 1207 if t == nil { 1208 n.Type = nil 1209 return 1210 } 1211 if Istype(t, TSTRING) { 1212 Yyerror("invalid operation %v (3-index slice of string)", Nconv(n, 0)) 1213 n.Type = nil 1214 return 1215 } 1216 1217 var tp *Type 1218 if Isptr[t.Etype] && Isfixedarray(t.Type) { 1219 tp = t.Type 1220 n.Type = typ(TARRAY) 1221 n.Type.Type = tp.Type 1222 n.Type.Bound = -1 1223 dowidth(n.Type) 1224 n.Op = OSLICE3ARR 1225 } else if Isslice(t) { 1226 n.Type = t 1227 } else { 1228 Yyerror("cannot slice %v (type %v)", Nconv(l, 0), Tconv(t, 0)) 1229 n.Type = nil 1230 return 1231 } 1232 1233 lo := n.Right.Left 1234 if lo != nil && checksliceindex(l, lo, tp) < 0 { 1235 n.Type = nil 1236 return 1237 } 1238 mid := n.Right.Right.Left 1239 if mid != nil && checksliceindex(l, mid, tp) < 0 { 1240 n.Type = nil 1241 return 1242 } 1243 hi := n.Right.Right.Right 1244 if hi != nil && checksliceindex(l, hi, tp) < 0 { 1245 n.Type = nil 1246 return 1247 } 1248 if checksliceconst(lo, hi) < 0 || checksliceconst(lo, mid) < 0 || checksliceconst(mid, hi) < 0 { 1249 n.Type = nil 1250 return 1251 } 1252 break OpSwitch 1253 1254 /* 1255 * call and call like 1256 */ 1257 case OCALL: 1258 l := n.Left 1259 1260 if l.Op == ONAME { 1261 r := unsafenmagic(n) 1262 if r != nil { 1263 if n.Isddd { 1264 Yyerror("invalid use of ... with builtin %v", Nconv(l, 0)) 1265 } 1266 n = r 1267 typecheck1(&n, top) 1268 return 1269 } 1270 } 1271 1272 typecheck(&n.Left, Erv|Etype|Ecall|top&Eproc) 1273 n.Diag |= n.Left.Diag 1274 l = n.Left 1275 if l.Op == ONAME && l.Etype != 0 { 1276 if n.Isddd && l.Etype != OAPPEND { 1277 Yyerror("invalid use of ... with builtin %v", Nconv(l, 0)) 1278 } 1279 1280 // builtin: OLEN, OCAP, etc. 1281 n.Op = l.Etype 1282 1283 n.Left = n.Right 1284 n.Right = nil 1285 typecheck1(&n, top) 1286 return 1287 } 1288 1289 defaultlit(&n.Left, nil) 1290 l = n.Left 1291 if l.Op == OTYPE { 1292 if n.Isddd || l.Type.Bound == -100 { 1293 if l.Type.Broke == 0 { 1294 Yyerror("invalid use of ... in type conversion", l) 1295 } 1296 n.Diag = 1 1297 } 1298 1299 // pick off before type-checking arguments 1300 ok |= Erv 1301 1302 // turn CALL(type, arg) into CONV(arg) w/ type 1303 n.Left = nil 1304 1305 n.Op = OCONV 1306 n.Type = l.Type 1307 if onearg(n, "conversion to %v", Tconv(l.Type, 0)) < 0 { 1308 n.Type = nil 1309 return 1310 } 1311 typecheck1(&n, top) 1312 return 1313 } 1314 1315 if count(n.List) == 1 && !n.Isddd { 1316 typecheck(&n.List.N, Erv|Efnstruct) 1317 } else { 1318 typechecklist(n.List, Erv) 1319 } 1320 t := l.Type 1321 if t == nil { 1322 n.Type = nil 1323 return 1324 } 1325 checkwidth(t) 1326 1327 switch l.Op { 1328 case ODOTINTER: 1329 n.Op = OCALLINTER 1330 1331 case ODOTMETH: 1332 n.Op = OCALLMETH 1333 1334 // typecheckaste was used here but there wasn't enough 1335 // information further down the call chain to know if we 1336 // were testing a method receiver for unexported fields. 1337 // It isn't necessary, so just do a sanity check. 1338 tp := getthisx(t).Type.Type 1339 1340 if l.Left == nil || !Eqtype(l.Left.Type, tp) { 1341 Fatal("method receiver") 1342 } 1343 1344 default: 1345 n.Op = OCALLFUNC 1346 if t.Etype != TFUNC { 1347 Yyerror("cannot call non-function %v (type %v)", Nconv(l, 0), Tconv(t, 0)) 1348 n.Type = nil 1349 return 1350 } 1351 } 1352 1353 typecheckaste(OCALL, n.Left, n.Isddd, getinargx(t), n.List, func() string { return fmt.Sprintf("argument to %v", Nconv(n.Left, 0)) }) 1354 ok |= Etop 1355 if t.Outtuple == 0 { 1356 break OpSwitch 1357 } 1358 ok |= Erv 1359 if t.Outtuple == 1 { 1360 t := getoutargx(l.Type).Type 1361 if t == nil { 1362 n.Type = nil 1363 return 1364 } 1365 if t.Etype == TFIELD { 1366 t = t.Type 1367 } 1368 n.Type = t 1369 1370 if n.Op == OCALLFUNC && n.Left.Op == ONAME && (compiling_runtime != 0 || n.Left.Sym.Pkg == Runtimepkg) && n.Left.Sym.Name == "getg" { 1371 // Emit code for runtime.getg() directly instead of calling function. 1372 // Most such rewrites (for example the similar one for math.Sqrt) should be done in walk, 1373 // so that the ordering pass can make sure to preserve the semantics of the original code 1374 // (in particular, the exact time of the function call) by introducing temporaries. 1375 // In this case, we know getg() always returns the same result within a given function 1376 // and we want to avoid the temporaries, so we do the rewrite earlier than is typical. 1377 n.Op = OGETG 1378 } 1379 1380 break OpSwitch 1381 } 1382 1383 // multiple return 1384 if top&(Efnstruct|Etop) == 0 { 1385 Yyerror("multiple-value %v() in single-value context", Nconv(l, 0)) 1386 break OpSwitch 1387 } 1388 1389 n.Type = getoutargx(l.Type) 1390 1391 break OpSwitch 1392 1393 case OCAP, OLEN, OREAL, OIMAG: 1394 ok |= Erv 1395 if onearg(n, "%v", Oconv(int(n.Op), 0)) < 0 { 1396 n.Type = nil 1397 return 1398 } 1399 typecheck(&n.Left, Erv) 1400 defaultlit(&n.Left, nil) 1401 implicitstar(&n.Left) 1402 l := n.Left 1403 t := l.Type 1404 if t == nil { 1405 n.Type = nil 1406 return 1407 } 1408 switch n.Op { 1409 case OCAP: 1410 if !okforcap[t.Etype] { 1411 goto badcall1 1412 } 1413 1414 case OLEN: 1415 if !okforlen[t.Etype] { 1416 goto badcall1 1417 } 1418 1419 case OREAL, OIMAG: 1420 if !Iscomplex[t.Etype] { 1421 goto badcall1 1422 } 1423 if Isconst(l, CTCPLX) { 1424 r := n 1425 if n.Op == OREAL { 1426 n = nodfltconst(&l.Val.U.Cval.Real) 1427 } else { 1428 n = nodfltconst(&l.Val.U.Cval.Imag) 1429 } 1430 n.Orig = r 1431 } 1432 1433 n.Type = Types[cplxsubtype(int(t.Etype))] 1434 break OpSwitch 1435 } 1436 1437 // might be constant 1438 switch t.Etype { 1439 case TSTRING: 1440 if Isconst(l, CTSTR) { 1441 r := Nod(OXXX, nil, nil) 1442 Nodconst(r, Types[TINT], int64(len(l.Val.U.Sval))) 1443 r.Orig = n 1444 n = r 1445 } 1446 1447 case TARRAY: 1448 if t.Bound < 0 { // slice 1449 break 1450 } 1451 if callrecv(l) { // has call or receive 1452 break 1453 } 1454 r := Nod(OXXX, nil, nil) 1455 Nodconst(r, Types[TINT], t.Bound) 1456 r.Orig = n 1457 n = r 1458 } 1459 1460 n.Type = Types[TINT] 1461 break OpSwitch 1462 1463 badcall1: 1464 Yyerror("invalid argument %v for %v", Nconv(n.Left, obj.FmtLong), Oconv(int(n.Op), 0)) 1465 n.Type = nil 1466 return 1467 1468 case OCOMPLEX: 1469 ok |= Erv 1470 var r *Node 1471 var l *Node 1472 if count(n.List) == 1 { 1473 typechecklist(n.List, Efnstruct) 1474 if n.List.N.Op != OCALLFUNC && n.List.N.Op != OCALLMETH { 1475 Yyerror("invalid operation: complex expects two arguments") 1476 n.Type = nil 1477 return 1478 } 1479 1480 t := n.List.N.Left.Type 1481 if t.Outtuple != 2 { 1482 Yyerror("invalid operation: complex expects two arguments, %v returns %d results", Nconv(n.List.N, 0), t.Outtuple) 1483 n.Type = nil 1484 return 1485 } 1486 1487 t = n.List.N.Type.Type 1488 l = t.Nname 1489 r = t.Down.Nname 1490 } else { 1491 if twoarg(n) < 0 { 1492 n.Type = nil 1493 return 1494 } 1495 l = typecheck(&n.Left, Erv|top&Eiota) 1496 r = typecheck(&n.Right, Erv|top&Eiota) 1497 if l.Type == nil || r.Type == nil { 1498 n.Type = nil 1499 return 1500 } 1501 defaultlit2(&l, &r, 0) 1502 if l.Type == nil || r.Type == nil { 1503 n.Type = nil 1504 return 1505 } 1506 n.Left = l 1507 n.Right = r 1508 } 1509 1510 if !Eqtype(l.Type, r.Type) { 1511 Yyerror("invalid operation: %v (mismatched types %v and %v)", Nconv(n, 0), Tconv(l.Type, 0), Tconv(r.Type, 0)) 1512 n.Type = nil 1513 return 1514 } 1515 1516 var t *Type 1517 switch l.Type.Etype { 1518 default: 1519 Yyerror("invalid operation: %v (arguments have type %v, expected floating-point)", Nconv(n, 0), Tconv(l.Type, 0), r.Type) 1520 n.Type = nil 1521 return 1522 1523 case TIDEAL: 1524 t = Types[TIDEAL] 1525 1526 case TFLOAT32: 1527 t = Types[TCOMPLEX64] 1528 1529 case TFLOAT64: 1530 t = Types[TCOMPLEX128] 1531 } 1532 1533 if l.Op == OLITERAL && r.Op == OLITERAL { 1534 // make it a complex literal 1535 r = nodcplxlit(l.Val, r.Val) 1536 1537 r.Orig = n 1538 n = r 1539 } 1540 1541 n.Type = t 1542 break OpSwitch 1543 1544 case OCLOSE: 1545 if onearg(n, "%v", Oconv(int(n.Op), 0)) < 0 { 1546 n.Type = nil 1547 return 1548 } 1549 typecheck(&n.Left, Erv) 1550 defaultlit(&n.Left, nil) 1551 l := n.Left 1552 t := l.Type 1553 if t == nil { 1554 n.Type = nil 1555 return 1556 } 1557 if t.Etype != TCHAN { 1558 Yyerror("invalid operation: %v (non-chan type %v)", Nconv(n, 0), Tconv(t, 0)) 1559 n.Type = nil 1560 return 1561 } 1562 1563 if t.Chan&Csend == 0 { 1564 Yyerror("invalid operation: %v (cannot close receive-only channel)", Nconv(n, 0)) 1565 n.Type = nil 1566 return 1567 } 1568 1569 ok |= Etop 1570 break OpSwitch 1571 1572 case ODELETE: 1573 args := n.List 1574 if args == nil { 1575 Yyerror("missing arguments to delete") 1576 n.Type = nil 1577 return 1578 } 1579 1580 if args.Next == nil { 1581 Yyerror("missing second (key) argument to delete") 1582 n.Type = nil 1583 return 1584 } 1585 1586 if args.Next.Next != nil { 1587 Yyerror("too many arguments to delete") 1588 n.Type = nil 1589 return 1590 } 1591 1592 ok |= Etop 1593 typechecklist(args, Erv) 1594 l := args.N 1595 r := args.Next.N 1596 if l.Type != nil && l.Type.Etype != TMAP { 1597 Yyerror("first argument to delete must be map; have %v", Tconv(l.Type, obj.FmtLong)) 1598 n.Type = nil 1599 return 1600 } 1601 1602 args.Next.N = assignconv(r, l.Type.Down, "delete") 1603 break OpSwitch 1604 1605 case OAPPEND: 1606 ok |= Erv 1607 args := n.List 1608 if args == nil { 1609 Yyerror("missing arguments to append") 1610 n.Type = nil 1611 return 1612 } 1613 1614 if count(args) == 1 && !n.Isddd { 1615 typecheck(&args.N, Erv|Efnstruct) 1616 } else { 1617 typechecklist(args, Erv) 1618 } 1619 1620 t := args.N.Type 1621 if t == nil { 1622 n.Type = nil 1623 return 1624 } 1625 1626 // Unpack multiple-return result before type-checking. 1627 if Istype(t, TSTRUCT) && t.Funarg != 0 { 1628 t = t.Type 1629 if Istype(t, TFIELD) { 1630 t = t.Type 1631 } 1632 } 1633 1634 n.Type = t 1635 if !Isslice(t) { 1636 if Isconst(args.N, CTNIL) { 1637 Yyerror("first argument to append must be typed slice; have untyped nil", t) 1638 n.Type = nil 1639 return 1640 } 1641 1642 Yyerror("first argument to append must be slice; have %v", Tconv(t, obj.FmtLong)) 1643 n.Type = nil 1644 return 1645 } 1646 1647 if n.Isddd { 1648 if args.Next == nil { 1649 Yyerror("cannot use ... on first argument to append") 1650 n.Type = nil 1651 return 1652 } 1653 1654 if args.Next.Next != nil { 1655 Yyerror("too many arguments to append") 1656 n.Type = nil 1657 return 1658 } 1659 1660 if Istype(t.Type, TUINT8) && Istype(args.Next.N.Type, TSTRING) { 1661 defaultlit(&args.Next.N, Types[TSTRING]) 1662 break OpSwitch 1663 } 1664 1665 args.Next.N = assignconv(args.Next.N, t.Orig, "append") 1666 break OpSwitch 1667 } 1668 1669 for args = args.Next; args != nil; args = args.Next { 1670 if args.N.Type == nil { 1671 continue 1672 } 1673 args.N = assignconv(args.N, t.Type, "append") 1674 } 1675 1676 break OpSwitch 1677 1678 case OCOPY: 1679 ok |= Etop | Erv 1680 args := n.List 1681 if args == nil || args.Next == nil { 1682 Yyerror("missing arguments to copy") 1683 n.Type = nil 1684 return 1685 } 1686 1687 if args.Next.Next != nil { 1688 Yyerror("too many arguments to copy") 1689 n.Type = nil 1690 return 1691 } 1692 1693 n.Left = args.N 1694 n.Right = args.Next.N 1695 n.List = nil 1696 n.Type = Types[TINT] 1697 typecheck(&n.Left, Erv) 1698 typecheck(&n.Right, Erv) 1699 if n.Left.Type == nil || n.Right.Type == nil { 1700 n.Type = nil 1701 return 1702 } 1703 defaultlit(&n.Left, nil) 1704 defaultlit(&n.Right, nil) 1705 if n.Left.Type == nil || n.Right.Type == nil { 1706 n.Type = nil 1707 return 1708 } 1709 1710 // copy([]byte, string) 1711 if Isslice(n.Left.Type) && n.Right.Type.Etype == TSTRING { 1712 if Eqtype(n.Left.Type.Type, bytetype) { 1713 break OpSwitch 1714 } 1715 Yyerror("arguments to copy have different element types: %v and string", Tconv(n.Left.Type, obj.FmtLong)) 1716 n.Type = nil 1717 return 1718 } 1719 1720 if !Isslice(n.Left.Type) || !Isslice(n.Right.Type) { 1721 if !Isslice(n.Left.Type) && !Isslice(n.Right.Type) { 1722 Yyerror("arguments to copy must be slices; have %v, %v", Tconv(n.Left.Type, obj.FmtLong), Tconv(n.Right.Type, obj.FmtLong)) 1723 } else if !Isslice(n.Left.Type) { 1724 Yyerror("first argument to copy should be slice; have %v", Tconv(n.Left.Type, obj.FmtLong)) 1725 } else { 1726 Yyerror("second argument to copy should be slice or string; have %v", Tconv(n.Right.Type, obj.FmtLong)) 1727 } 1728 n.Type = nil 1729 return 1730 } 1731 1732 if !Eqtype(n.Left.Type.Type, n.Right.Type.Type) { 1733 Yyerror("arguments to copy have different element types: %v and %v", Tconv(n.Left.Type, obj.FmtLong), Tconv(n.Right.Type, obj.FmtLong)) 1734 n.Type = nil 1735 return 1736 } 1737 1738 break OpSwitch 1739 1740 case OCONV: 1741 { 1742 ok |= Erv 1743 saveorignode(n) 1744 typecheck(&n.Left, Erv|top&(Eindir|Eiota)) 1745 convlit1(&n.Left, n.Type, true) 1746 t := n.Left.Type 1747 if t == nil || n.Type == nil { 1748 n.Type = nil 1749 return 1750 } 1751 var why string 1752 n.Op = uint8(convertop(t, n.Type, &why)) 1753 if (n.Op) == 0 { 1754 if n.Diag == 0 && n.Type.Broke == 0 { 1755 Yyerror("cannot convert %v to type %v%s", Nconv(n.Left, obj.FmtLong), Tconv(n.Type, 0), why) 1756 n.Diag = 1 1757 } 1758 1759 n.Op = OCONV 1760 } 1761 1762 switch n.Op { 1763 case OCONVNOP: 1764 if n.Left.Op == OLITERAL && n.Type != Types[TBOOL] { 1765 r := Nod(OXXX, nil, nil) 1766 n.Op = OCONV 1767 n.Orig = r 1768 *r = *n 1769 n.Op = OLITERAL 1770 n.Val = n.Left.Val 1771 } 1772 1773 // do not use stringtoarraylit. 1774 // generated code and compiler memory footprint is better without it. 1775 case OSTRARRAYBYTE: 1776 break 1777 1778 case OSTRARRAYRUNE: 1779 if n.Left.Op == OLITERAL { 1780 stringtoarraylit(&n) 1781 } 1782 } 1783 1784 break OpSwitch 1785 } 1786 break OpSwitch 1787 1788 case OMAKE: 1789 ok |= Erv 1790 args := n.List 1791 if args == nil { 1792 Yyerror("missing argument to make") 1793 n.Type = nil 1794 return 1795 } 1796 1797 n.List = nil 1798 l := args.N 1799 args = args.Next 1800 typecheck(&l, Etype) 1801 t := l.Type 1802 if t == nil { 1803 n.Type = nil 1804 return 1805 } 1806 1807 switch t.Etype { 1808 default: 1809 Yyerror("cannot make type %v", Tconv(t, 0)) 1810 n.Type = nil 1811 return 1812 1813 case TARRAY: 1814 if !Isslice(t) { 1815 Yyerror("cannot make type %v", Tconv(t, 0)) 1816 n.Type = nil 1817 return 1818 } 1819 1820 if args == nil { 1821 Yyerror("missing len argument to make(%v)", Tconv(t, 0)) 1822 n.Type = nil 1823 return 1824 } 1825 1826 l = args.N 1827 args = args.Next 1828 typecheck(&l, Erv) 1829 var r *Node 1830 if args != nil { 1831 r = args.N 1832 args = args.Next 1833 typecheck(&r, Erv) 1834 } 1835 1836 if l.Type == nil || (r != nil && r.Type == nil) { 1837 n.Type = nil 1838 return 1839 } 1840 et := bool2int(checkmake(t, "len", l) < 0) 1841 et |= bool2int(r != nil && checkmake(t, "cap", r) < 0) 1842 if et != 0 { 1843 n.Type = nil 1844 return 1845 } 1846 if Isconst(l, CTINT) && r != nil && Isconst(r, CTINT) && Mpcmpfixfix(l.Val.U.Xval, r.Val.U.Xval) > 0 { 1847 Yyerror("len larger than cap in make(%v)", Tconv(t, 0)) 1848 n.Type = nil 1849 return 1850 } 1851 1852 n.Left = l 1853 n.Right = r 1854 n.Op = OMAKESLICE 1855 1856 case TMAP: 1857 if args != nil { 1858 l = args.N 1859 args = args.Next 1860 typecheck(&l, Erv) 1861 defaultlit(&l, Types[TINT]) 1862 if l.Type == nil { 1863 n.Type = nil 1864 return 1865 } 1866 if checkmake(t, "size", l) < 0 { 1867 n.Type = nil 1868 return 1869 } 1870 n.Left = l 1871 } else { 1872 n.Left = Nodintconst(0) 1873 } 1874 n.Op = OMAKEMAP 1875 1876 case TCHAN: 1877 l = nil 1878 if args != nil { 1879 l = args.N 1880 args = args.Next 1881 typecheck(&l, Erv) 1882 defaultlit(&l, Types[TINT]) 1883 if l.Type == nil { 1884 n.Type = nil 1885 return 1886 } 1887 if checkmake(t, "buffer", l) < 0 { 1888 n.Type = nil 1889 return 1890 } 1891 n.Left = l 1892 } else { 1893 n.Left = Nodintconst(0) 1894 } 1895 n.Op = OMAKECHAN 1896 } 1897 1898 if args != nil { 1899 Yyerror("too many arguments to make(%v)", Tconv(t, 0)) 1900 n.Op = OMAKE 1901 n.Type = nil 1902 return 1903 } 1904 1905 n.Type = t 1906 break OpSwitch 1907 1908 case ONEW: 1909 ok |= Erv 1910 args := n.List 1911 if args == nil { 1912 Yyerror("missing argument to new") 1913 n.Type = nil 1914 return 1915 } 1916 1917 l := args.N 1918 typecheck(&l, Etype) 1919 t := l.Type 1920 if t == nil { 1921 n.Type = nil 1922 return 1923 } 1924 if args.Next != nil { 1925 Yyerror("too many arguments to new(%v)", Tconv(t, 0)) 1926 n.Type = nil 1927 return 1928 } 1929 1930 n.Left = l 1931 n.Type = Ptrto(t) 1932 break OpSwitch 1933 1934 case OPRINT, OPRINTN: 1935 ok |= Etop 1936 typechecklist(n.List, Erv|Eindir) // Eindir: address does not escape 1937 for args := n.List; args != nil; args = args.Next { 1938 // Special case for print: int constant is int64, not int. 1939 if Isconst(args.N, CTINT) { 1940 defaultlit(&args.N, Types[TINT64]) 1941 } else { 1942 defaultlit(&args.N, nil) 1943 } 1944 } 1945 1946 break OpSwitch 1947 1948 case OPANIC: 1949 ok |= Etop 1950 if onearg(n, "panic") < 0 { 1951 n.Type = nil 1952 return 1953 } 1954 typecheck(&n.Left, Erv) 1955 defaultlit(&n.Left, Types[TINTER]) 1956 if n.Left.Type == nil { 1957 n.Type = nil 1958 return 1959 } 1960 break OpSwitch 1961 1962 case ORECOVER: 1963 ok |= Erv | Etop 1964 if n.List != nil { 1965 Yyerror("too many arguments to recover") 1966 n.Type = nil 1967 return 1968 } 1969 1970 n.Type = Types[TINTER] 1971 break OpSwitch 1972 1973 case OCLOSURE: 1974 ok |= Erv 1975 typecheckclosure(n, top) 1976 if n.Type == nil { 1977 n.Type = nil 1978 return 1979 } 1980 break OpSwitch 1981 1982 case OITAB: 1983 ok |= Erv 1984 typecheck(&n.Left, Erv) 1985 t := n.Left.Type 1986 if t == nil { 1987 n.Type = nil 1988 return 1989 } 1990 if t.Etype != TINTER { 1991 Fatal("OITAB of %v", Tconv(t, 0)) 1992 } 1993 n.Type = Ptrto(Types[TUINTPTR]) 1994 break OpSwitch 1995 1996 case OSPTR: 1997 ok |= Erv 1998 typecheck(&n.Left, Erv) 1999 t := n.Left.Type 2000 if t == nil { 2001 n.Type = nil 2002 return 2003 } 2004 if !Isslice(t) && t.Etype != TSTRING { 2005 Fatal("OSPTR of %v", Tconv(t, 0)) 2006 } 2007 if t.Etype == TSTRING { 2008 n.Type = Ptrto(Types[TUINT8]) 2009 } else { 2010 n.Type = Ptrto(t.Type) 2011 } 2012 break OpSwitch 2013 2014 case OCLOSUREVAR: 2015 ok |= Erv 2016 break OpSwitch 2017 2018 case OCFUNC: 2019 ok |= Erv 2020 typecheck(&n.Left, Erv) 2021 n.Type = Types[TUINTPTR] 2022 break OpSwitch 2023 2024 case OCONVNOP: 2025 ok |= Erv 2026 typecheck(&n.Left, Erv) 2027 break OpSwitch 2028 2029 /* 2030 * statements 2031 */ 2032 case OAS: 2033 ok |= Etop 2034 2035 typecheckas(n) 2036 2037 // Code that creates temps does not bother to set defn, so do it here. 2038 if n.Left.Op == ONAME && strings.HasPrefix(n.Left.Sym.Name, "autotmp_") { 2039 n.Left.Defn = n 2040 } 2041 break OpSwitch 2042 2043 case OAS2: 2044 ok |= Etop 2045 typecheckas2(n) 2046 break OpSwitch 2047 2048 case OBREAK, 2049 OCONTINUE, 2050 ODCL, 2051 OEMPTY, 2052 OGOTO, 2053 OXFALL, 2054 OVARKILL: 2055 ok |= Etop 2056 break OpSwitch 2057 2058 case OLABEL: 2059 ok |= Etop 2060 decldepth++ 2061 break OpSwitch 2062 2063 case ODEFER: 2064 ok |= Etop 2065 typecheck(&n.Left, Etop|Erv) 2066 if n.Left.Diag == 0 { 2067 checkdefergo(n) 2068 } 2069 break OpSwitch 2070 2071 case OPROC: 2072 ok |= Etop 2073 typecheck(&n.Left, Etop|Eproc|Erv) 2074 checkdefergo(n) 2075 break OpSwitch 2076 2077 case OFOR: 2078 ok |= Etop 2079 typechecklist(n.Ninit, Etop) 2080 decldepth++ 2081 typecheck(&n.Ntest, Erv) 2082 if n.Ntest != nil { 2083 t := n.Ntest.Type 2084 if t != nil && t.Etype != TBOOL { 2085 Yyerror("non-bool %v used as for condition", Nconv(n.Ntest, obj.FmtLong)) 2086 } 2087 } 2088 typecheck(&n.Nincr, Etop) 2089 typechecklist(n.Nbody, Etop) 2090 decldepth-- 2091 break OpSwitch 2092 2093 case OIF: 2094 ok |= Etop 2095 typechecklist(n.Ninit, Etop) 2096 typecheck(&n.Ntest, Erv) 2097 if n.Ntest != nil { 2098 t := n.Ntest.Type 2099 if t != nil && t.Etype != TBOOL { 2100 Yyerror("non-bool %v used as if condition", Nconv(n.Ntest, obj.FmtLong)) 2101 } 2102 } 2103 typechecklist(n.Nbody, Etop) 2104 typechecklist(n.Nelse, Etop) 2105 break OpSwitch 2106 2107 case ORETURN: 2108 ok |= Etop 2109 if count(n.List) == 1 { 2110 typechecklist(n.List, Erv|Efnstruct) 2111 } else { 2112 typechecklist(n.List, Erv) 2113 } 2114 if Curfn == nil { 2115 Yyerror("return outside function") 2116 n.Type = nil 2117 return 2118 } 2119 2120 if Curfn.Type.Outnamed != 0 && n.List == nil { 2121 break OpSwitch 2122 } 2123 typecheckaste(ORETURN, nil, false, getoutargx(Curfn.Type), n.List, func() string { return "return argument" }) 2124 break OpSwitch 2125 2126 case ORETJMP: 2127 ok |= Etop 2128 break OpSwitch 2129 2130 case OSELECT: 2131 ok |= Etop 2132 typecheckselect(n) 2133 break OpSwitch 2134 2135 case OSWITCH: 2136 ok |= Etop 2137 typecheckswitch(n) 2138 break OpSwitch 2139 2140 case ORANGE: 2141 ok |= Etop 2142 typecheckrange(n) 2143 break OpSwitch 2144 2145 case OTYPESW: 2146 Yyerror("use of .(type) outside type switch") 2147 n.Type = nil 2148 return 2149 2150 case OXCASE: 2151 ok |= Etop 2152 typechecklist(n.List, Erv) 2153 typechecklist(n.Nbody, Etop) 2154 break OpSwitch 2155 2156 case ODCLFUNC: 2157 ok |= Etop 2158 typecheckfunc(n) 2159 break OpSwitch 2160 2161 case ODCLCONST: 2162 ok |= Etop 2163 typecheck(&n.Left, Erv) 2164 break OpSwitch 2165 2166 case ODCLTYPE: 2167 ok |= Etop 2168 typecheck(&n.Left, Etype) 2169 if incannedimport == 0 { 2170 checkwidth(n.Left.Type) 2171 } 2172 break OpSwitch 2173 } 2174 2175 t := n.Type 2176 if t != nil && t.Funarg == 0 && n.Op != OTYPE { 2177 switch t.Etype { 2178 case TFUNC, // might have TANY; wait until its called 2179 TANY, 2180 TFORW, 2181 TIDEAL, 2182 TNIL, 2183 TBLANK: 2184 break 2185 2186 default: 2187 checkwidth(t) 2188 } 2189 } 2190 2191 if safemode != 0 && incannedimport == 0 && importpkg == nil && compiling_wrappers == 0 && t != nil && t.Etype == TUNSAFEPTR { 2192 Yyerror("cannot use unsafe.Pointer") 2193 } 2194 2195 evconst(n) 2196 if n.Op == OTYPE && top&Etype == 0 { 2197 Yyerror("type %v is not an expression", Tconv(n.Type, 0)) 2198 n.Type = nil 2199 return 2200 } 2201 2202 if top&(Erv|Etype) == Etype && n.Op != OTYPE { 2203 Yyerror("%v is not a type", Nconv(n, 0)) 2204 n.Type = nil 2205 return 2206 } 2207 2208 // TODO(rsc): simplify 2209 if (top&(Ecall|Erv|Etype) != 0) && top&Etop == 0 && ok&(Erv|Etype|Ecall) == 0 { 2210 Yyerror("%v used as value", Nconv(n, 0)) 2211 n.Type = nil 2212 return 2213 } 2214 2215 if (top&Etop != 0) && top&(Ecall|Erv|Etype) == 0 && ok&Etop == 0 { 2216 if n.Diag == 0 { 2217 Yyerror("%v evaluated but not used", Nconv(n, 0)) 2218 n.Diag = 1 2219 } 2220 2221 n.Type = nil 2222 return 2223 } 2224 2225 /* TODO 2226 if(n->type == T) 2227 fatal("typecheck nil type"); 2228 */ 2229 } 2230 2231 func checksliceindex(l *Node, r *Node, tp *Type) int { 2232 t := r.Type 2233 if t == nil { 2234 return -1 2235 } 2236 if !Isint[t.Etype] { 2237 Yyerror("invalid slice index %v (type %v)", Nconv(r, 0), Tconv(t, 0)) 2238 return -1 2239 } 2240 2241 if r.Op == OLITERAL { 2242 if Mpgetfix(r.Val.U.Xval) < 0 { 2243 Yyerror("invalid slice index %v (index must be non-negative)", Nconv(r, 0)) 2244 return -1 2245 } else if tp != nil && tp.Bound > 0 && Mpgetfix(r.Val.U.Xval) > tp.Bound { 2246 Yyerror("invalid slice index %v (out of bounds for %d-element array)", Nconv(r, 0), tp.Bound) 2247 return -1 2248 } else if Isconst(l, CTSTR) && Mpgetfix(r.Val.U.Xval) > int64(len(l.Val.U.Sval)) { 2249 Yyerror("invalid slice index %v (out of bounds for %d-byte string)", Nconv(r, 0), len(l.Val.U.Sval)) 2250 return -1 2251 } else if Mpcmpfixfix(r.Val.U.Xval, Maxintval[TINT]) > 0 { 2252 Yyerror("invalid slice index %v (index too large)", Nconv(r, 0)) 2253 return -1 2254 } 2255 } 2256 2257 return 0 2258 } 2259 2260 func checksliceconst(lo *Node, hi *Node) int { 2261 if lo != nil && hi != nil && lo.Op == OLITERAL && hi.Op == OLITERAL && Mpcmpfixfix(lo.Val.U.Xval, hi.Val.U.Xval) > 0 { 2262 Yyerror("invalid slice index: %v > %v", Nconv(lo, 0), Nconv(hi, 0)) 2263 return -1 2264 } 2265 2266 return 0 2267 } 2268 2269 func checkdefergo(n *Node) { 2270 what := "defer" 2271 if n.Op == OPROC { 2272 what = "go" 2273 } 2274 2275 switch n.Left.Op { 2276 // ok 2277 case OCALLINTER, 2278 OCALLMETH, 2279 OCALLFUNC, 2280 OCLOSE, 2281 OCOPY, 2282 ODELETE, 2283 OPANIC, 2284 OPRINT, 2285 OPRINTN, 2286 ORECOVER: 2287 return 2288 2289 case OAPPEND, 2290 OCAP, 2291 OCOMPLEX, 2292 OIMAG, 2293 OLEN, 2294 OMAKE, 2295 OMAKESLICE, 2296 OMAKECHAN, 2297 OMAKEMAP, 2298 ONEW, 2299 OREAL, 2300 OLITERAL: // conversion or unsafe.Alignof, Offsetof, Sizeof 2301 if n.Left.Orig != nil && n.Left.Orig.Op == OCONV { 2302 break 2303 } 2304 Yyerror("%s discards result of %v", what, Nconv(n.Left, 0)) 2305 return 2306 } 2307 2308 // type is broken or missing, most likely a method call on a broken type 2309 // we will warn about the broken type elsewhere. no need to emit a potentially confusing error 2310 if n.Left.Type == nil || n.Left.Type.Broke != 0 { 2311 return 2312 } 2313 2314 if n.Diag == 0 { 2315 // The syntax made sure it was a call, so this must be 2316 // a conversion. 2317 n.Diag = 1 2318 2319 Yyerror("%s requires function call, not conversion", what) 2320 } 2321 } 2322 2323 func implicitstar(nn **Node) { 2324 // insert implicit * if needed for fixed array 2325 n := *nn 2326 2327 t := n.Type 2328 if t == nil || !Isptr[t.Etype] { 2329 return 2330 } 2331 t = t.Type 2332 if t == nil { 2333 return 2334 } 2335 if !Isfixedarray(t) { 2336 return 2337 } 2338 n = Nod(OIND, n, nil) 2339 n.Implicit = true 2340 typecheck(&n, Erv) 2341 *nn = n 2342 } 2343 2344 func onearg(n *Node, f string, args ...interface{}) int { 2345 if n.Left != nil { 2346 return 0 2347 } 2348 if n.List == nil { 2349 p := fmt.Sprintf(f, args...) 2350 Yyerror("missing argument to %s: %v", p, Nconv(n, 0)) 2351 return -1 2352 } 2353 2354 if n.List.Next != nil { 2355 p := fmt.Sprintf(f, args...) 2356 Yyerror("too many arguments to %s: %v", p, Nconv(n, 0)) 2357 n.Left = n.List.N 2358 n.List = nil 2359 return -1 2360 } 2361 2362 n.Left = n.List.N 2363 n.List = nil 2364 return 0 2365 } 2366 2367 func twoarg(n *Node) int { 2368 if n.Left != nil { 2369 return 0 2370 } 2371 if n.List == nil { 2372 Yyerror("missing argument to %v - %v", Oconv(int(n.Op), 0), Nconv(n, 0)) 2373 return -1 2374 } 2375 2376 n.Left = n.List.N 2377 if n.List.Next == nil { 2378 Yyerror("missing argument to %v - %v", Oconv(int(n.Op), 0), Nconv(n, 0)) 2379 n.List = nil 2380 return -1 2381 } 2382 2383 if n.List.Next.Next != nil { 2384 Yyerror("too many arguments to %v - %v", Oconv(int(n.Op), 0), Nconv(n, 0)) 2385 n.List = nil 2386 return -1 2387 } 2388 2389 n.Right = n.List.Next.N 2390 n.List = nil 2391 return 0 2392 } 2393 2394 func lookdot1(errnode *Node, s *Sym, t *Type, f *Type, dostrcmp int) *Type { 2395 var r *Type 2396 for ; f != nil; f = f.Down { 2397 if dostrcmp != 0 && f.Sym.Name == s.Name { 2398 return f 2399 } 2400 if f.Sym != s { 2401 continue 2402 } 2403 if r != nil { 2404 if errnode != nil { 2405 Yyerror("ambiguous selector %v", Nconv(errnode, 0)) 2406 } else if Isptr[t.Etype] { 2407 Yyerror("ambiguous selector (%v).%v", Tconv(t, 0), Sconv(s, 0)) 2408 } else { 2409 Yyerror("ambiguous selector %v.%v", Tconv(t, 0), Sconv(s, 0)) 2410 } 2411 break 2412 } 2413 2414 r = f 2415 } 2416 2417 return r 2418 } 2419 2420 func looktypedot(n *Node, t *Type, dostrcmp int) bool { 2421 s := n.Right.Sym 2422 2423 if t.Etype == TINTER { 2424 f1 := lookdot1(n, s, t, t.Type, dostrcmp) 2425 if f1 == nil { 2426 return false 2427 } 2428 2429 n.Right = methodname(n.Right, t) 2430 n.Xoffset = f1.Width 2431 n.Type = f1.Type 2432 n.Op = ODOTINTER 2433 return true 2434 } 2435 2436 // Find the base type: methtype will fail if t 2437 // is not of the form T or *T. 2438 f2 := methtype(t, 0) 2439 2440 if f2 == nil { 2441 return false 2442 } 2443 2444 expandmeth(f2) 2445 f2 = lookdot1(n, s, f2, f2.Xmethod, dostrcmp) 2446 if f2 == nil { 2447 return false 2448 } 2449 2450 // disallow T.m if m requires *T receiver 2451 if Isptr[getthisx(f2.Type).Type.Type.Etype] && !Isptr[t.Etype] && f2.Embedded != 2 && !isifacemethod(f2.Type) { 2452 Yyerror("invalid method expression %v (needs pointer receiver: (*%v).%v)", Nconv(n, 0), Tconv(t, 0), Sconv(f2.Sym, obj.FmtShort)) 2453 return false 2454 } 2455 2456 n.Right = methodname(n.Right, t) 2457 n.Xoffset = f2.Width 2458 n.Type = f2.Type 2459 n.Op = ODOTMETH 2460 return true 2461 } 2462 2463 func derefall(t *Type) *Type { 2464 for t != nil && int(t.Etype) == Tptr { 2465 t = t.Type 2466 } 2467 return t 2468 } 2469 2470 func lookdot(n *Node, t *Type, dostrcmp int) bool { 2471 s := n.Right.Sym 2472 2473 dowidth(t) 2474 var f1 *Type 2475 if t.Etype == TSTRUCT || t.Etype == TINTER { 2476 f1 = lookdot1(n, s, t, t.Type, dostrcmp) 2477 } 2478 2479 var f2 *Type 2480 if n.Left.Type == t || n.Left.Type.Sym == nil { 2481 f2 = methtype(t, 0) 2482 if f2 != nil { 2483 // Use f2->method, not f2->xmethod: adddot has 2484 // already inserted all the necessary embedded dots. 2485 f2 = lookdot1(n, s, f2, f2.Method, dostrcmp) 2486 } 2487 } 2488 2489 if f1 != nil { 2490 if f2 != nil { 2491 Yyerror("%v is both field and method", Sconv(n.Right.Sym, 0)) 2492 } 2493 if f1.Width == BADWIDTH { 2494 Fatal("lookdot badwidth %v %p", Tconv(f1, 0), f1) 2495 } 2496 n.Xoffset = f1.Width 2497 n.Type = f1.Type 2498 n.Paramfld = f1 2499 if t.Etype == TINTER { 2500 if Isptr[n.Left.Type.Etype] { 2501 n.Left = Nod(OIND, n.Left, nil) // implicitstar 2502 n.Left.Implicit = true 2503 typecheck(&n.Left, Erv) 2504 } 2505 2506 n.Op = ODOTINTER 2507 } 2508 2509 return true 2510 } 2511 2512 if f2 != nil { 2513 tt := n.Left.Type 2514 dowidth(tt) 2515 rcvr := getthisx(f2.Type).Type.Type 2516 if !Eqtype(rcvr, tt) { 2517 if int(rcvr.Etype) == Tptr && Eqtype(rcvr.Type, tt) { 2518 checklvalue(n.Left, "call pointer method on") 2519 n.Left = Nod(OADDR, n.Left, nil) 2520 n.Left.Implicit = true 2521 typecheck(&n.Left, Etype|Erv) 2522 } else if int(tt.Etype) == Tptr && int(rcvr.Etype) != Tptr && Eqtype(tt.Type, rcvr) { 2523 n.Left = Nod(OIND, n.Left, nil) 2524 n.Left.Implicit = true 2525 typecheck(&n.Left, Etype|Erv) 2526 } else if int(tt.Etype) == Tptr && int(tt.Type.Etype) == Tptr && Eqtype(derefall(tt), derefall(rcvr)) { 2527 Yyerror("calling method %v with receiver %v requires explicit dereference", Nconv(n.Right, 0), Nconv(n.Left, obj.FmtLong)) 2528 for int(tt.Etype) == Tptr { 2529 // Stop one level early for method with pointer receiver. 2530 if int(rcvr.Etype) == Tptr && int(tt.Type.Etype) != Tptr { 2531 break 2532 } 2533 n.Left = Nod(OIND, n.Left, nil) 2534 n.Left.Implicit = true 2535 typecheck(&n.Left, Etype|Erv) 2536 tt = tt.Type 2537 } 2538 } else { 2539 Fatal("method mismatch: %v for %v", Tconv(rcvr, 0), Tconv(tt, 0)) 2540 } 2541 } 2542 2543 ll := n.Left 2544 for ll.Left != nil { 2545 ll = ll.Left 2546 } 2547 if ll.Implicit { 2548 if Isptr[ll.Type.Etype] && ll.Type.Sym != nil && ll.Type.Sym.Def != nil && ll.Type.Sym.Def.Op == OTYPE { 2549 // It is invalid to automatically dereference a named pointer type when selecting a method. 2550 // Make n->left == ll to clarify error message. 2551 n.Left = ll 2552 return false 2553 } 2554 } 2555 2556 n.Right = methodname(n.Right, n.Left.Type) 2557 n.Xoffset = f2.Width 2558 n.Type = f2.Type 2559 2560 // print("lookdot found [%p] %T\n", f2->type, f2->type); 2561 n.Op = ODOTMETH 2562 2563 return true 2564 } 2565 2566 return false 2567 } 2568 2569 func nokeys(l *NodeList) bool { 2570 for ; l != nil; l = l.Next { 2571 if l.N.Op == OKEY { 2572 return false 2573 } 2574 } 2575 return true 2576 } 2577 2578 func hasddd(t *Type) bool { 2579 for tl := t.Type; tl != nil; tl = tl.Down { 2580 if tl.Isddd { 2581 return true 2582 } 2583 } 2584 2585 return false 2586 } 2587 2588 func downcount(t *Type) int { 2589 n := 0 2590 for tl := t.Type; tl != nil; tl = tl.Down { 2591 n++ 2592 } 2593 2594 return n 2595 } 2596 2597 /* 2598 * typecheck assignment: type list = expression list 2599 */ 2600 func typecheckaste(op int, call *Node, isddd bool, tstruct *Type, nl *NodeList, desc func() string) { 2601 var t *Type 2602 var n *Node 2603 var n1 int 2604 var n2 int 2605 2606 lno := int(lineno) 2607 2608 if tstruct.Broke != 0 { 2609 goto out 2610 } 2611 2612 n = nil 2613 if nl != nil && nl.Next == nil { 2614 n = nl.N 2615 if n.Type != nil { 2616 if n.Type.Etype == TSTRUCT && n.Type.Funarg != 0 { 2617 if !hasddd(tstruct) { 2618 n1 := downcount(tstruct) 2619 n2 := downcount(n.Type) 2620 if n2 > n1 { 2621 goto toomany 2622 } 2623 if n2 < n1 { 2624 goto notenough 2625 } 2626 } 2627 2628 tn := n.Type.Type 2629 var why string 2630 for tl := tstruct.Type; tl != nil; tl = tl.Down { 2631 if tl.Isddd { 2632 for ; tn != nil; tn = tn.Down { 2633 if assignop(tn.Type, tl.Type.Type, &why) == 0 { 2634 if call != nil { 2635 Yyerror("cannot use %v as type %v in argument to %v%s", Tconv(tn.Type, 0), Tconv(tl.Type.Type, 0), Nconv(call, 0), why) 2636 } else { 2637 Yyerror("cannot use %v as type %v in %s%s", Tconv(tn.Type, 0), Tconv(tl.Type.Type, 0), desc(), why) 2638 } 2639 } 2640 } 2641 2642 goto out 2643 } 2644 2645 if tn == nil { 2646 goto notenough 2647 } 2648 if assignop(tn.Type, tl.Type, &why) == 0 { 2649 if call != nil { 2650 Yyerror("cannot use %v as type %v in argument to %v%s", Tconv(tn.Type, 0), Tconv(tl.Type, 0), Nconv(call, 0), why) 2651 } else { 2652 Yyerror("cannot use %v as type %v in %s%s", Tconv(tn.Type, 0), Tconv(tl.Type, 0), desc(), why) 2653 } 2654 } 2655 2656 tn = tn.Down 2657 } 2658 2659 if tn != nil { 2660 goto toomany 2661 } 2662 goto out 2663 } 2664 } 2665 } 2666 2667 n1 = downcount(tstruct) 2668 n2 = count(nl) 2669 if !hasddd(tstruct) { 2670 if n2 > n1 { 2671 goto toomany 2672 } 2673 if n2 < n1 { 2674 goto notenough 2675 } 2676 } else { 2677 if !isddd { 2678 if n2 < n1-1 { 2679 goto notenough 2680 } 2681 } else { 2682 if n2 > n1 { 2683 goto toomany 2684 } 2685 if n2 < n1 { 2686 goto notenough 2687 } 2688 } 2689 } 2690 2691 for tl := tstruct.Type; tl != nil; tl = tl.Down { 2692 t = tl.Type 2693 if tl.Isddd { 2694 if isddd { 2695 if nl == nil { 2696 goto notenough 2697 } 2698 if nl.Next != nil { 2699 goto toomany 2700 } 2701 n = nl.N 2702 setlineno(n) 2703 if n.Type != nil { 2704 nl.N = assignconvfn(n, t, desc) 2705 } 2706 goto out 2707 } 2708 2709 for ; nl != nil; nl = nl.Next { 2710 n = nl.N 2711 setlineno(nl.N) 2712 if n.Type != nil { 2713 nl.N = assignconvfn(n, t.Type, desc) 2714 } 2715 } 2716 2717 goto out 2718 } 2719 2720 if nl == nil { 2721 goto notenough 2722 } 2723 n = nl.N 2724 setlineno(n) 2725 if n.Type != nil { 2726 nl.N = assignconvfn(n, t, desc) 2727 } 2728 nl = nl.Next 2729 } 2730 2731 if nl != nil { 2732 goto toomany 2733 } 2734 if isddd { 2735 if call != nil { 2736 Yyerror("invalid use of ... in call to %v", Nconv(call, 0)) 2737 } else { 2738 Yyerror("invalid use of ... in %v", Oconv(int(op), 0)) 2739 } 2740 } 2741 2742 out: 2743 lineno = int32(lno) 2744 return 2745 2746 notenough: 2747 if n == nil || n.Diag == 0 { 2748 if call != nil { 2749 Yyerror("not enough arguments in call to %v", Nconv(call, 0)) 2750 } else { 2751 Yyerror("not enough arguments to %v", Oconv(int(op), 0)) 2752 } 2753 if n != nil { 2754 n.Diag = 1 2755 } 2756 } 2757 2758 goto out 2759 2760 toomany: 2761 if call != nil { 2762 Yyerror("too many arguments in call to %v", Nconv(call, 0)) 2763 } else { 2764 Yyerror("too many arguments to %v", Oconv(int(op), 0)) 2765 } 2766 goto out 2767 } 2768 2769 /* 2770 * type check composite 2771 */ 2772 func fielddup(n *Node, hash map[string]bool) { 2773 if n.Op != ONAME { 2774 Fatal("fielddup: not ONAME") 2775 } 2776 name := n.Sym.Name 2777 if hash[name] { 2778 Yyerror("duplicate field name in struct literal: %s", name) 2779 return 2780 } 2781 hash[name] = true 2782 } 2783 2784 func keydup(n *Node, hash []*Node) { 2785 orign := n 2786 if n.Op == OCONVIFACE { 2787 n = n.Left 2788 } 2789 evconst(n) 2790 if n.Op != OLITERAL { 2791 return // we dont check variables 2792 } 2793 2794 var b uint32 2795 switch n.Val.Ctype { 2796 default: // unknown, bool, nil 2797 b = 23 2798 2799 case CTINT, CTRUNE: 2800 b = uint32(Mpgetfix(n.Val.U.Xval)) 2801 2802 case CTFLT: 2803 d := mpgetflt(n.Val.U.Fval) 2804 x := math.Float64bits(d) 2805 for i := 0; i < 8; i++ { 2806 b = b*PRIME1 + uint32(x&0xFF) 2807 x >>= 8 2808 } 2809 2810 case CTSTR: 2811 b = 0 2812 s := n.Val.U.Sval 2813 for i := len(n.Val.U.Sval); i > 0; i-- { 2814 b = b*PRIME1 + uint32(s[0]) 2815 s = s[1:] 2816 } 2817 } 2818 2819 h := uint(b % uint32(len(hash))) 2820 var cmp Node 2821 for a := hash[h]; a != nil; a = a.Ntest { 2822 cmp.Op = OEQ 2823 cmp.Left = n 2824 b = 0 2825 if a.Op == OCONVIFACE && orign.Op == OCONVIFACE { 2826 if Eqtype(a.Left.Type, n.Type) { 2827 cmp.Right = a.Left 2828 evconst(&cmp) 2829 b = uint32(bool2int(cmp.Val.U.Bval)) 2830 } 2831 } else if Eqtype(a.Type, n.Type) { 2832 cmp.Right = a 2833 evconst(&cmp) 2834 b = uint32(bool2int(cmp.Val.U.Bval)) 2835 } 2836 2837 if b != 0 { 2838 Yyerror("duplicate key %v in map literal", Nconv(n, 0)) 2839 return 2840 } 2841 } 2842 2843 orign.Ntest = hash[h] 2844 hash[h] = orign 2845 } 2846 2847 func indexdup(n *Node, hash []*Node) { 2848 if n.Op != OLITERAL { 2849 Fatal("indexdup: not OLITERAL") 2850 } 2851 2852 b := uint32(Mpgetfix(n.Val.U.Xval)) 2853 h := uint(b % uint32(len(hash))) 2854 var c uint32 2855 for a := hash[h]; a != nil; a = a.Ntest { 2856 c = uint32(Mpgetfix(a.Val.U.Xval)) 2857 if b == c { 2858 Yyerror("duplicate index in array literal: %d", b) 2859 return 2860 } 2861 } 2862 2863 n.Ntest = hash[h] 2864 hash[h] = n 2865 } 2866 2867 func prime(h uint32, sr uint32) bool { 2868 for n := uint32(3); n <= sr; n += 2 { 2869 if h%n == 0 { 2870 return false 2871 } 2872 } 2873 return true 2874 } 2875 2876 func inithash(n *Node, autohash []*Node) []*Node { 2877 // count the number of entries 2878 h := uint32(0) 2879 2880 for ll := n.List; ll != nil; ll = ll.Next { 2881 h++ 2882 } 2883 2884 // if the auto hash table is 2885 // large enough use it. 2886 if h <= uint32(len(autohash)) { 2887 for i := range autohash { 2888 autohash[i] = nil 2889 } 2890 return autohash 2891 } 2892 2893 // make hash size odd and 12% larger than entries 2894 h += h / 8 2895 2896 h |= 1 2897 2898 // calculate sqrt of h 2899 sr := h / 2 2900 2901 for i := 0; i < 5; i++ { 2902 sr = (sr + h/sr) / 2 2903 } 2904 2905 // check for primeality 2906 for !prime(h, sr) { 2907 h += 2 2908 } 2909 2910 // build and return a throw-away hash table 2911 return make([]*Node, h) 2912 } 2913 2914 func iscomptype(t *Type) bool { 2915 switch t.Etype { 2916 case TARRAY, TSTRUCT, TMAP: 2917 return true 2918 2919 case TPTR32, TPTR64: 2920 switch t.Type.Etype { 2921 case TARRAY, TSTRUCT, TMAP: 2922 return true 2923 } 2924 } 2925 2926 return false 2927 } 2928 2929 func pushtype(n *Node, t *Type) { 2930 if n == nil || n.Op != OCOMPLIT || !iscomptype(t) { 2931 return 2932 } 2933 2934 if n.Right == nil { 2935 n.Right = typenod(t) 2936 n.Implicit = true // don't print 2937 n.Right.Implicit = true // * is okay 2938 } else if Debug['s'] != 0 { 2939 typecheck(&n.Right, Etype) 2940 if n.Right.Type != nil && Eqtype(n.Right.Type, t) { 2941 fmt.Printf("%v: redundant type: %v\n", n.Line(), Tconv(t, 0)) 2942 } 2943 } 2944 } 2945 2946 func typecheckcomplit(np **Node) { 2947 n := *np 2948 lno := lineno 2949 defer func() { 2950 lineno = lno 2951 *np = n 2952 }() 2953 2954 if n.Right == nil { 2955 if n.List != nil { 2956 setlineno(n.List.N) 2957 } 2958 Yyerror("missing type in composite literal") 2959 n.Type = nil 2960 return 2961 } 2962 2963 // Save original node (including n->right) 2964 norig := Nod(int(n.Op), nil, nil) 2965 2966 *norig = *n 2967 2968 setlineno(n.Right) 2969 l := typecheck(&n.Right, Etype|Ecomplit) /* sic */ 2970 t := l.Type 2971 if t == nil { 2972 n.Type = nil 2973 return 2974 } 2975 nerr := nerrors 2976 n.Type = t 2977 2978 if Isptr[t.Etype] { 2979 // For better or worse, we don't allow pointers as the composite literal type, 2980 // except when using the &T syntax, which sets implicit on the OIND. 2981 if !n.Right.Implicit { 2982 Yyerror("invalid pointer type %v for composite literal (use &%v instead)", Tconv(t, 0), Tconv(t.Type, 0)) 2983 n.Type = nil 2984 return 2985 } 2986 2987 // Also, the underlying type must be a struct, map, slice, or array. 2988 if !iscomptype(t) { 2989 Yyerror("invalid pointer type %v for composite literal", Tconv(t, 0)) 2990 n.Type = nil 2991 return 2992 } 2993 2994 t = t.Type 2995 } 2996 2997 var r *Node 2998 switch t.Etype { 2999 default: 3000 Yyerror("invalid type for composite literal: %v", Tconv(t, 0)) 3001 n.Type = nil 3002 3003 case TARRAY: 3004 var autohash [101]*Node 3005 hash := inithash(n, autohash[:]) 3006 3007 length := int64(0) 3008 i := 0 3009 var l *Node 3010 for ll := n.List; ll != nil; ll = ll.Next { 3011 l = ll.N 3012 setlineno(l) 3013 if l.Op != OKEY { 3014 l = Nod(OKEY, Nodintconst(int64(i)), l) 3015 l.Left.Type = Types[TINT] 3016 l.Left.Typecheck = 1 3017 ll.N = l 3018 } 3019 3020 typecheck(&l.Left, Erv) 3021 evconst(l.Left) 3022 i = nonnegconst(l.Left) 3023 if i < 0 && l.Left.Diag == 0 { 3024 Yyerror("array index must be non-negative integer constant") 3025 l.Left.Diag = 1 3026 i = -(1 << 30) // stay negative for a while 3027 } 3028 3029 if i >= 0 { 3030 indexdup(l.Left, hash) 3031 } 3032 i++ 3033 if int64(i) > length { 3034 length = int64(i) 3035 if t.Bound >= 0 && length > t.Bound { 3036 setlineno(l) 3037 Yyerror("array index %d out of bounds [0:%d]", length-1, t.Bound) 3038 t.Bound = -1 // no more errors 3039 } 3040 } 3041 3042 r = l.Right 3043 pushtype(r, t.Type) 3044 typecheck(&r, Erv) 3045 defaultlit(&r, t.Type) 3046 l.Right = assignconv(r, t.Type, "array element") 3047 } 3048 3049 if t.Bound == -100 { 3050 t.Bound = length 3051 } 3052 if t.Bound < 0 { 3053 n.Right = Nodintconst(length) 3054 } 3055 n.Op = OARRAYLIT 3056 3057 case TMAP: 3058 var autohash [101]*Node 3059 hash := inithash(n, autohash[:]) 3060 3061 var l *Node 3062 for ll := n.List; ll != nil; ll = ll.Next { 3063 l = ll.N 3064 setlineno(l) 3065 if l.Op != OKEY { 3066 typecheck(&ll.N, Erv) 3067 Yyerror("missing key in map literal") 3068 continue 3069 } 3070 3071 typecheck(&l.Left, Erv) 3072 defaultlit(&l.Left, t.Down) 3073 l.Left = assignconv(l.Left, t.Down, "map key") 3074 if l.Left.Op != OCONV { 3075 keydup(l.Left, hash) 3076 } 3077 3078 r = l.Right 3079 pushtype(r, t.Type) 3080 typecheck(&r, Erv) 3081 defaultlit(&r, t.Type) 3082 l.Right = assignconv(r, t.Type, "map value") 3083 } 3084 3085 n.Op = OMAPLIT 3086 3087 case TSTRUCT: 3088 bad := 0 3089 if n.List != nil && nokeys(n.List) { 3090 // simple list of variables 3091 f := t.Type 3092 3093 var s *Sym 3094 for ll := n.List; ll != nil; ll = ll.Next { 3095 setlineno(ll.N) 3096 typecheck(&ll.N, Erv) 3097 if f == nil { 3098 tmp12 := bad 3099 bad++ 3100 if tmp12 == 0 { 3101 Yyerror("too many values in struct initializer") 3102 } 3103 continue 3104 } 3105 3106 s = f.Sym 3107 if s != nil && !exportname(s.Name) && s.Pkg != localpkg { 3108 Yyerror("implicit assignment of unexported field '%s' in %v literal", s.Name, Tconv(t, 0)) 3109 } 3110 3111 // No pushtype allowed here. Must name fields for that. 3112 ll.N = assignconv(ll.N, f.Type, "field value") 3113 3114 ll.N = Nod(OKEY, newname(f.Sym), ll.N) 3115 ll.N.Left.Type = f 3116 ll.N.Left.Typecheck = 1 3117 f = f.Down 3118 } 3119 3120 if f != nil { 3121 Yyerror("too few values in struct initializer") 3122 } 3123 } else { 3124 hash := make(map[string]bool) 3125 3126 // keyed list 3127 var s *Sym 3128 var f *Type 3129 var l *Node 3130 var s1 *Sym 3131 for ll := n.List; ll != nil; ll = ll.Next { 3132 l = ll.N 3133 setlineno(l) 3134 if l.Op != OKEY { 3135 tmp13 := bad 3136 bad++ 3137 if tmp13 == 0 { 3138 Yyerror("mixture of field:value and value initializers") 3139 } 3140 typecheck(&ll.N, Erv) 3141 continue 3142 } 3143 3144 s = l.Left.Sym 3145 if s == nil { 3146 Yyerror("invalid field name %v in struct initializer", Nconv(l.Left, 0)) 3147 typecheck(&l.Right, Erv) 3148 continue 3149 } 3150 3151 // Sym might have resolved to name in other top-level 3152 // package, because of import dot. Redirect to correct sym 3153 // before we do the lookup. 3154 if s.Pkg != localpkg && exportname(s.Name) { 3155 s1 = Lookup(s.Name) 3156 if s1.Origpkg == s.Pkg { 3157 s = s1 3158 } 3159 } 3160 3161 f = lookdot1(nil, s, t, t.Type, 0) 3162 if f == nil { 3163 Yyerror("unknown %v field '%v' in struct literal", Tconv(t, 0), Sconv(s, 0)) 3164 continue 3165 } 3166 3167 l.Left = newname(s) 3168 l.Left.Typecheck = 1 3169 l.Left.Type = f 3170 s = f.Sym 3171 fielddup(newname(s), hash) 3172 r = l.Right 3173 3174 // No pushtype allowed here. Tried and rejected. 3175 typecheck(&r, Erv) 3176 3177 l.Right = assignconv(r, f.Type, "field value") 3178 } 3179 } 3180 3181 n.Op = OSTRUCTLIT 3182 } 3183 3184 if nerr != nerrors { 3185 n.Type = nil 3186 return 3187 } 3188 3189 n.Orig = norig 3190 if Isptr[n.Type.Etype] { 3191 n = Nod(OPTRLIT, n, nil) 3192 n.Typecheck = 1 3193 n.Type = n.Left.Type 3194 n.Left.Type = t 3195 n.Left.Typecheck = 1 3196 } 3197 3198 n.Orig = norig 3199 return 3200 } 3201 3202 /* 3203 * lvalue etc 3204 */ 3205 func islvalue(n *Node) bool { 3206 switch n.Op { 3207 case OINDEX: 3208 if Isfixedarray(n.Left.Type) { 3209 return islvalue(n.Left) 3210 } 3211 if n.Left.Type != nil && n.Left.Type.Etype == TSTRING { 3212 return false 3213 } 3214 fallthrough 3215 3216 // fall through 3217 case OIND, ODOTPTR, OCLOSUREVAR, OPARAM: 3218 return true 3219 3220 case ODOT: 3221 return islvalue(n.Left) 3222 3223 case ONAME: 3224 if n.Class == PFUNC { 3225 return false 3226 } 3227 return true 3228 } 3229 3230 return false 3231 } 3232 3233 func checklvalue(n *Node, verb string) { 3234 if !islvalue(n) { 3235 Yyerror("cannot %s %v", verb, Nconv(n, 0)) 3236 } 3237 } 3238 3239 func checkassign(stmt *Node, n *Node) { 3240 // Variables declared in ORANGE are assigned on every iteration. 3241 if n.Defn != stmt || stmt.Op == ORANGE { 3242 r := outervalue(n) 3243 var l *Node 3244 for l = n; l != r; l = l.Left { 3245 l.Assigned = true 3246 if l.Closure != nil { 3247 l.Closure.Assigned = true 3248 } 3249 } 3250 3251 l.Assigned = true 3252 if l.Closure != nil { 3253 l.Closure.Assigned = true 3254 } 3255 } 3256 3257 if islvalue(n) { 3258 return 3259 } 3260 if n.Op == OINDEXMAP { 3261 n.Etype = 1 3262 return 3263 } 3264 3265 // have already complained about n being undefined 3266 if n.Op == ONONAME { 3267 return 3268 } 3269 3270 Yyerror("cannot assign to %v", Nconv(n, 0)) 3271 } 3272 3273 func checkassignlist(stmt *Node, l *NodeList) { 3274 for ; l != nil; l = l.Next { 3275 checkassign(stmt, l.N) 3276 } 3277 } 3278 3279 // Check whether l and r are the same side effect-free expression, 3280 // so that it is safe to reuse one instead of computing both. 3281 func samesafeexpr(l *Node, r *Node) bool { 3282 if l.Op != r.Op || !Eqtype(l.Type, r.Type) { 3283 return false 3284 } 3285 3286 switch l.Op { 3287 case ONAME, OCLOSUREVAR: 3288 return l == r 3289 3290 case ODOT, ODOTPTR: 3291 return l.Right != nil && r.Right != nil && l.Right.Sym == r.Right.Sym && samesafeexpr(l.Left, r.Left) 3292 3293 case OIND: 3294 return samesafeexpr(l.Left, r.Left) 3295 3296 case OINDEX: 3297 return samesafeexpr(l.Left, r.Left) && samesafeexpr(l.Right, r.Right) 3298 } 3299 3300 return false 3301 } 3302 3303 /* 3304 * type check assignment. 3305 * if this assignment is the definition of a var on the left side, 3306 * fill in the var's type. 3307 */ 3308 func typecheckas(n *Node) { 3309 // delicate little dance. 3310 // the definition of n may refer to this assignment 3311 // as its definition, in which case it will call typecheckas. 3312 // in that case, do not call typecheck back, or it will cycle. 3313 // if the variable has a type (ntype) then typechecking 3314 // will not look at defn, so it is okay (and desirable, 3315 // so that the conversion below happens). 3316 n.Left = resolve(n.Left) 3317 3318 if n.Left.Defn != n || n.Left.Ntype != nil { 3319 typecheck(&n.Left, Erv|Easgn) 3320 } 3321 3322 typecheck(&n.Right, Erv) 3323 checkassign(n, n.Left) 3324 if n.Right != nil && n.Right.Type != nil { 3325 if n.Left.Type != nil { 3326 n.Right = assignconv(n.Right, n.Left.Type, "assignment") 3327 } 3328 } 3329 3330 if n.Left.Defn == n && n.Left.Ntype == nil { 3331 defaultlit(&n.Right, nil) 3332 n.Left.Type = n.Right.Type 3333 } 3334 3335 // second half of dance. 3336 // now that right is done, typecheck the left 3337 // just to get it over with. see dance above. 3338 n.Typecheck = 1 3339 3340 if n.Left.Typecheck == 0 { 3341 typecheck(&n.Left, Erv|Easgn) 3342 } 3343 3344 // Recognize slices being updated in place, for better code generation later. 3345 // Don't rewrite if using race detector, to avoid needing to teach race detector 3346 // about this optimization. 3347 if n.Left != nil && n.Left.Op != OINDEXMAP && n.Right != nil && flag_race == 0 { 3348 switch n.Right.Op { 3349 // For x = x[0:y], x can be updated in place, without touching pointer. 3350 // TODO(rsc): Reenable once it is actually updated in place without touching the pointer. 3351 case OSLICE, OSLICE3, OSLICESTR: 3352 if false && samesafeexpr(n.Left, n.Right.Left) && (n.Right.Right.Left == nil || iszero(n.Right.Right.Left)) { 3353 n.Right.Reslice = true 3354 } 3355 3356 // For x = append(x, ...), x can be updated in place when there is capacity, 3357 // without touching the pointer; otherwise the emitted code to growslice 3358 // can take care of updating the pointer, and only in that case. 3359 // TODO(rsc): Reenable once the emitted code does update the pointer. 3360 case OAPPEND: 3361 if false && n.Right.List != nil && samesafeexpr(n.Left, n.Right.List.N) { 3362 n.Right.Reslice = true 3363 } 3364 } 3365 } 3366 } 3367 3368 func checkassignto(src *Type, dst *Node) { 3369 var why string 3370 3371 if assignop(src, dst.Type, &why) == 0 { 3372 Yyerror("cannot assign %v to %v in multiple assignment%s", Tconv(src, 0), Nconv(dst, obj.FmtLong), why) 3373 return 3374 } 3375 } 3376 3377 func typecheckas2(n *Node) { 3378 for ll := n.List; ll != nil; ll = ll.Next { 3379 // delicate little dance. 3380 ll.N = resolve(ll.N) 3381 3382 if ll.N.Defn != n || ll.N.Ntype != nil { 3383 typecheck(&ll.N, Erv|Easgn) 3384 } 3385 } 3386 3387 cl := count(n.List) 3388 cr := count(n.Rlist) 3389 if cl > 1 && cr == 1 { 3390 typecheck(&n.Rlist.N, Erv|Efnstruct) 3391 } else { 3392 typechecklist(n.Rlist, Erv) 3393 } 3394 checkassignlist(n, n.List) 3395 3396 var l *Node 3397 var r *Node 3398 if cl == cr { 3399 // easy 3400 ll := n.List 3401 lr := n.Rlist 3402 for ; ll != nil; ll, lr = ll.Next, lr.Next { 3403 if ll.N.Type != nil && lr.N.Type != nil { 3404 lr.N = assignconv(lr.N, ll.N.Type, "assignment") 3405 } 3406 if ll.N.Defn == n && ll.N.Ntype == nil { 3407 defaultlit(&lr.N, nil) 3408 ll.N.Type = lr.N.Type 3409 } 3410 } 3411 3412 goto out 3413 } 3414 3415 l = n.List.N 3416 r = n.Rlist.N 3417 3418 // x,y,z = f() 3419 if cr == 1 { 3420 if r.Type == nil { 3421 goto out 3422 } 3423 switch r.Op { 3424 case OCALLMETH, OCALLINTER, OCALLFUNC: 3425 if r.Type.Etype != TSTRUCT || r.Type.Funarg == 0 { 3426 break 3427 } 3428 cr = structcount(r.Type) 3429 if cr != cl { 3430 goto mismatch 3431 } 3432 n.Op = OAS2FUNC 3433 var s Iter 3434 t := Structfirst(&s, &r.Type) 3435 for ll := n.List; ll != nil; ll = ll.Next { 3436 if t.Type != nil && ll.N.Type != nil { 3437 checkassignto(t.Type, ll.N) 3438 } 3439 if ll.N.Defn == n && ll.N.Ntype == nil { 3440 ll.N.Type = t.Type 3441 } 3442 t = structnext(&s) 3443 } 3444 3445 goto out 3446 } 3447 } 3448 3449 // x, ok = y 3450 if cl == 2 && cr == 1 { 3451 if r.Type == nil { 3452 goto out 3453 } 3454 switch r.Op { 3455 case OINDEXMAP, ORECV, ODOTTYPE: 3456 switch r.Op { 3457 case OINDEXMAP: 3458 n.Op = OAS2MAPR 3459 3460 case ORECV: 3461 n.Op = OAS2RECV 3462 3463 case ODOTTYPE: 3464 n.Op = OAS2DOTTYPE 3465 r.Op = ODOTTYPE2 3466 } 3467 3468 if l.Type != nil { 3469 checkassignto(r.Type, l) 3470 } 3471 if l.Defn == n { 3472 l.Type = r.Type 3473 } 3474 l := n.List.Next.N 3475 if l.Type != nil && l.Type.Etype != TBOOL { 3476 checkassignto(Types[TBOOL], l) 3477 } 3478 if l.Defn == n && l.Ntype == nil { 3479 l.Type = Types[TBOOL] 3480 } 3481 goto out 3482 } 3483 } 3484 3485 mismatch: 3486 Yyerror("assignment count mismatch: %d = %d", cl, cr) 3487 3488 // second half of dance 3489 out: 3490 n.Typecheck = 1 3491 3492 for ll := n.List; ll != nil; ll = ll.Next { 3493 if ll.N.Typecheck == 0 { 3494 typecheck(&ll.N, Erv|Easgn) 3495 } 3496 } 3497 } 3498 3499 /* 3500 * type check function definition 3501 */ 3502 func typecheckfunc(n *Node) { 3503 typecheck(&n.Nname, Erv|Easgn) 3504 t := n.Nname.Type 3505 if t == nil { 3506 return 3507 } 3508 n.Type = t 3509 t.Nname = n.Nname 3510 rcvr := getthisx(t).Type 3511 if rcvr != nil && n.Func.Shortname != nil && !isblank(n.Func.Shortname) { 3512 addmethod(n.Func.Shortname.Sym, t, true, n.Nname.Nointerface) 3513 } 3514 3515 for l := n.Func.Dcl; l != nil; l = l.Next { 3516 if l.N.Op == ONAME && (l.N.Class == PPARAM || l.N.Class == PPARAMOUT) { 3517 l.N.Decldepth = 1 3518 } 3519 } 3520 } 3521 3522 func stringtoarraylit(np **Node) { 3523 n := *np 3524 if n.Left.Op != OLITERAL || n.Left.Val.Ctype != CTSTR { 3525 Fatal("stringtoarraylit %N", n) 3526 } 3527 3528 s := n.Left.Val.U.Sval 3529 var l *NodeList 3530 if n.Type.Type.Etype == TUINT8 { 3531 // []byte 3532 for i := 0; i < len(s); i++ { 3533 l = list(l, Nod(OKEY, Nodintconst(int64(i)), Nodintconst(int64(s[0])))) 3534 } 3535 } else { 3536 // []rune 3537 i := 0 3538 for _, r := range s { 3539 l = list(l, Nod(OKEY, Nodintconst(int64(i)), Nodintconst(int64(r)))) 3540 i++ 3541 } 3542 } 3543 3544 nn := Nod(OCOMPLIT, nil, typenod(n.Type)) 3545 nn.List = l 3546 typecheck(&nn, Erv) 3547 *np = nn 3548 } 3549 3550 var ntypecheckdeftype int 3551 3552 var methodqueue *NodeList 3553 3554 func domethod(n *Node) { 3555 nt := n.Type.Nname 3556 typecheck(&nt, Etype) 3557 if nt.Type == nil { 3558 // type check failed; leave empty func 3559 n.Type.Etype = TFUNC 3560 3561 n.Type.Nod = nil 3562 return 3563 } 3564 3565 // If we have 3566 // type I interface { 3567 // M(_ int) 3568 // } 3569 // then even though I.M looks like it doesn't care about the 3570 // value of its argument, a specific implementation of I may 3571 // care. The _ would suppress the assignment to that argument 3572 // while generating a call, so remove it. 3573 for t := getinargx(nt.Type).Type; t != nil; t = t.Down { 3574 if t.Sym != nil && t.Sym.Name == "_" { 3575 t.Sym = nil 3576 } 3577 } 3578 3579 *n.Type = *nt.Type 3580 n.Type.Nod = nil 3581 checkwidth(n.Type) 3582 } 3583 3584 var mapqueue *NodeList 3585 3586 func copytype(n *Node, t *Type) { 3587 if t.Etype == TFORW { 3588 // This type isn't computed yet; when it is, update n. 3589 t.Copyto = list(t.Copyto, n) 3590 3591 return 3592 } 3593 3594 maplineno := int(n.Type.Maplineno) 3595 embedlineno := int(n.Type.Embedlineno) 3596 3597 l := n.Type.Copyto 3598 *n.Type = *t 3599 3600 t = n.Type 3601 t.Sym = n.Sym 3602 t.Local = n.Local 3603 t.Vargen = n.Vargen 3604 t.Siggen = 0 3605 t.Method = nil 3606 t.Xmethod = nil 3607 t.Nod = nil 3608 t.Printed = 0 3609 t.Deferwidth = 0 3610 t.Copyto = nil 3611 3612 // Update nodes waiting on this type. 3613 for ; l != nil; l = l.Next { 3614 copytype(l.N, t) 3615 } 3616 3617 // Double-check use of type as embedded type. 3618 lno := int(lineno) 3619 3620 if embedlineno != 0 { 3621 lineno = int32(embedlineno) 3622 if Isptr[t.Etype] { 3623 Yyerror("embedded type cannot be a pointer") 3624 } 3625 } 3626 3627 lineno = int32(lno) 3628 3629 // Queue check for map until all the types are done settling. 3630 if maplineno != 0 { 3631 t.Maplineno = int32(maplineno) 3632 mapqueue = list(mapqueue, n) 3633 } 3634 } 3635 3636 func typecheckdeftype(n *Node) { 3637 ntypecheckdeftype++ 3638 lno := int(lineno) 3639 setlineno(n) 3640 n.Type.Sym = n.Sym 3641 n.Typecheck = 1 3642 typecheck(&n.Ntype, Etype) 3643 t := n.Ntype.Type 3644 if t == nil { 3645 n.Diag = 1 3646 n.Type = nil 3647 goto ret 3648 } 3649 3650 if n.Type == nil { 3651 n.Diag = 1 3652 goto ret 3653 } 3654 3655 // copy new type and clear fields 3656 // that don't come along. 3657 // anything zeroed here must be zeroed in 3658 // typedcl2 too. 3659 copytype(n, t) 3660 3661 ret: 3662 lineno = int32(lno) 3663 3664 // if there are no type definitions going on, it's safe to 3665 // try to resolve the method types for the interfaces 3666 // we just read. 3667 if ntypecheckdeftype == 1 { 3668 var l *NodeList 3669 for { 3670 l = methodqueue 3671 if l == nil { 3672 break 3673 } 3674 methodqueue = nil 3675 for ; l != nil; l = l.Next { 3676 domethod(l.N) 3677 } 3678 } 3679 3680 for l := mapqueue; l != nil; l = l.Next { 3681 lineno = l.N.Type.Maplineno 3682 maptype(l.N.Type, Types[TBOOL]) 3683 } 3684 3685 lineno = int32(lno) 3686 } 3687 3688 ntypecheckdeftype-- 3689 } 3690 3691 func queuemethod(n *Node) { 3692 if ntypecheckdeftype == 0 { 3693 domethod(n) 3694 return 3695 } 3696 3697 methodqueue = list(methodqueue, n) 3698 } 3699 3700 func typecheckdef(n *Node) *Node { 3701 lno := int(lineno) 3702 setlineno(n) 3703 3704 if n.Op == ONONAME { 3705 if n.Diag == 0 { 3706 n.Diag = 1 3707 if n.Lineno != 0 { 3708 lineno = n.Lineno 3709 } 3710 3711 // Note: adderrorname looks for this string and 3712 // adds context about the outer expression 3713 Yyerror("undefined: %v", Sconv(n.Sym, 0)) 3714 } 3715 3716 return n 3717 } 3718 3719 if n.Walkdef == 1 { 3720 return n 3721 } 3722 3723 l := new(NodeList) 3724 l.N = n 3725 l.Next = typecheckdefstack 3726 typecheckdefstack = l 3727 3728 if n.Walkdef == 2 { 3729 Flusherrors() 3730 fmt.Printf("typecheckdef loop:") 3731 for l := typecheckdefstack; l != nil; l = l.Next { 3732 fmt.Printf(" %v", Sconv(l.N.Sym, 0)) 3733 } 3734 fmt.Printf("\n") 3735 Fatal("typecheckdef loop") 3736 } 3737 3738 n.Walkdef = 2 3739 3740 if n.Type != nil || n.Sym == nil { // builtin or no name 3741 goto ret 3742 } 3743 3744 switch n.Op { 3745 default: 3746 Fatal("typecheckdef %v", Oconv(int(n.Op), 0)) 3747 3748 // not really syms 3749 case OGOTO, OLABEL: 3750 break 3751 3752 case OLITERAL: 3753 if n.Ntype != nil { 3754 typecheck(&n.Ntype, Etype) 3755 n.Type = n.Ntype.Type 3756 n.Ntype = nil 3757 if n.Type == nil { 3758 n.Diag = 1 3759 goto ret 3760 } 3761 } 3762 3763 e := n.Defn 3764 n.Defn = nil 3765 if e == nil { 3766 lineno = n.Lineno 3767 Dump("typecheckdef nil defn", n) 3768 Yyerror("xxx") 3769 } 3770 3771 typecheck(&e, Erv|Eiota) 3772 if Isconst(e, CTNIL) { 3773 Yyerror("const initializer cannot be nil") 3774 goto ret 3775 } 3776 3777 if e.Type != nil && e.Op != OLITERAL || !isgoconst(e) { 3778 if e.Diag == 0 { 3779 Yyerror("const initializer %v is not a constant", Nconv(e, 0)) 3780 e.Diag = 1 3781 } 3782 3783 goto ret 3784 } 3785 3786 t := n.Type 3787 if t != nil { 3788 if !okforconst[t.Etype] { 3789 Yyerror("invalid constant type %v", Tconv(t, 0)) 3790 goto ret 3791 } 3792 3793 if !isideal(e.Type) && !Eqtype(t, e.Type) { 3794 Yyerror("cannot use %v as type %v in const initializer", Nconv(e, obj.FmtLong), Tconv(t, 0)) 3795 goto ret 3796 } 3797 3798 Convlit(&e, t) 3799 } 3800 3801 n.Val = e.Val 3802 n.Type = e.Type 3803 3804 case ONAME: 3805 if n.Ntype != nil { 3806 typecheck(&n.Ntype, Etype) 3807 n.Type = n.Ntype.Type 3808 3809 if n.Type == nil { 3810 n.Diag = 1 3811 goto ret 3812 } 3813 } 3814 3815 if n.Type != nil { 3816 break 3817 } 3818 if n.Defn == nil { 3819 if n.Etype != 0 { // like OPRINTN 3820 break 3821 } 3822 if nsavederrors+nerrors > 0 { 3823 // Can have undefined variables in x := foo 3824 // that make x have an n->ndefn == nil. 3825 // If there are other errors anyway, don't 3826 // bother adding to the noise. 3827 break 3828 } 3829 3830 Fatal("var without type, init: %v", Sconv(n.Sym, 0)) 3831 } 3832 3833 if n.Defn.Op == ONAME { 3834 typecheck(&n.Defn, Erv) 3835 n.Type = n.Defn.Type 3836 break 3837 } 3838 3839 typecheck(&n.Defn, Etop) // fills in n->type 3840 3841 case OTYPE: 3842 if Curfn != nil { 3843 defercheckwidth() 3844 } 3845 n.Walkdef = 1 3846 n.Type = typ(TFORW) 3847 n.Type.Sym = n.Sym 3848 nerrors0 := nerrors 3849 typecheckdeftype(n) 3850 if n.Type.Etype == TFORW && nerrors > nerrors0 { 3851 // Something went wrong during type-checking, 3852 // but it was reported. Silence future errors. 3853 n.Type.Broke = 1 3854 } 3855 3856 if Curfn != nil { 3857 resumecheckwidth() 3858 } 3859 3860 // nothing to see here 3861 case OPACK: 3862 break 3863 } 3864 3865 ret: 3866 if n.Op != OLITERAL && n.Type != nil && isideal(n.Type) { 3867 Fatal("got %v for %v", Tconv(n.Type, 0), Nconv(n, 0)) 3868 } 3869 if typecheckdefstack.N != n { 3870 Fatal("typecheckdefstack mismatch") 3871 } 3872 l = typecheckdefstack 3873 typecheckdefstack = l.Next 3874 3875 lineno = int32(lno) 3876 n.Walkdef = 1 3877 return n 3878 } 3879 3880 func checkmake(t *Type, arg string, n *Node) int { 3881 if n.Op == OLITERAL { 3882 switch n.Val.Ctype { 3883 case CTINT, CTRUNE, CTFLT, CTCPLX: 3884 n.Val = toint(n.Val) 3885 if mpcmpfixc(n.Val.U.Xval, 0) < 0 { 3886 Yyerror("negative %s argument in make(%v)", arg, Tconv(t, 0)) 3887 return -1 3888 } 3889 3890 if Mpcmpfixfix(n.Val.U.Xval, Maxintval[TINT]) > 0 { 3891 Yyerror("%s argument too large in make(%v)", arg, Tconv(t, 0)) 3892 return -1 3893 } 3894 3895 // Delay defaultlit until after we've checked range, to avoid 3896 // a redundant "constant NNN overflows int" error. 3897 defaultlit(&n, Types[TINT]) 3898 3899 return 0 3900 3901 default: 3902 break 3903 } 3904 } 3905 3906 if !Isint[n.Type.Etype] && n.Type.Etype != TIDEAL { 3907 Yyerror("non-integer %s argument in make(%v) - %v", arg, Tconv(t, 0), Tconv(n.Type, 0)) 3908 return -1 3909 } 3910 3911 // Defaultlit still necessary for non-constant: n might be 1<<k. 3912 defaultlit(&n, Types[TINT]) 3913 3914 return 0 3915 } 3916 3917 func markbreak(n *Node, implicit *Node) { 3918 if n == nil { 3919 return 3920 } 3921 3922 switch n.Op { 3923 case OBREAK: 3924 if n.Left == nil { 3925 if implicit != nil { 3926 implicit.Hasbreak = true 3927 } 3928 } else { 3929 lab := n.Left.Sym.Label 3930 if lab != nil { 3931 lab.Def.Hasbreak = true 3932 } 3933 } 3934 3935 case OFOR, 3936 OSWITCH, 3937 OTYPESW, 3938 OSELECT, 3939 ORANGE: 3940 implicit = n 3941 fallthrough 3942 3943 // fall through 3944 default: 3945 markbreak(n.Left, implicit) 3946 3947 markbreak(n.Right, implicit) 3948 markbreak(n.Ntest, implicit) 3949 markbreak(n.Nincr, implicit) 3950 markbreaklist(n.Ninit, implicit) 3951 markbreaklist(n.Nbody, implicit) 3952 markbreaklist(n.Nelse, implicit) 3953 markbreaklist(n.List, implicit) 3954 markbreaklist(n.Rlist, implicit) 3955 } 3956 } 3957 3958 func markbreaklist(l *NodeList, implicit *Node) { 3959 var n *Node 3960 var lab *Label 3961 3962 for ; l != nil; l = l.Next { 3963 n = l.N 3964 if n.Op == OLABEL && l.Next != nil && n.Defn == l.Next.N { 3965 switch n.Defn.Op { 3966 case OFOR, 3967 OSWITCH, 3968 OTYPESW, 3969 OSELECT, 3970 ORANGE: 3971 lab = new(Label) 3972 lab.Def = n.Defn 3973 n.Left.Sym.Label = lab 3974 markbreak(n.Defn, n.Defn) 3975 n.Left.Sym.Label = nil 3976 l = l.Next 3977 continue 3978 } 3979 } 3980 3981 markbreak(n, implicit) 3982 } 3983 } 3984 3985 func isterminating(l *NodeList, top int) bool { 3986 if l == nil { 3987 return false 3988 } 3989 if top != 0 { 3990 for l.Next != nil && l.N.Op != OLABEL { 3991 l = l.Next 3992 } 3993 markbreaklist(l, nil) 3994 } 3995 3996 for l.Next != nil { 3997 l = l.Next 3998 } 3999 n := l.N 4000 4001 if n == nil { 4002 return false 4003 } 4004 4005 switch n.Op { 4006 // NOTE: OLABEL is treated as a separate statement, 4007 // not a separate prefix, so skipping to the last statement 4008 // in the block handles the labeled statement case by 4009 // skipping over the label. No case OLABEL here. 4010 4011 case OBLOCK: 4012 return isterminating(n.List, 0) 4013 4014 case OGOTO, 4015 ORETURN, 4016 ORETJMP, 4017 OPANIC, 4018 OXFALL: 4019 return true 4020 4021 case OFOR: 4022 if n.Ntest != nil { 4023 return false 4024 } 4025 if n.Hasbreak { 4026 return false 4027 } 4028 return true 4029 4030 case OIF: 4031 return isterminating(n.Nbody, 0) && isterminating(n.Nelse, 0) 4032 4033 case OSWITCH, OTYPESW, OSELECT: 4034 if n.Hasbreak { 4035 return false 4036 } 4037 def := 0 4038 for l = n.List; l != nil; l = l.Next { 4039 if !isterminating(l.N.Nbody, 0) { 4040 return false 4041 } 4042 if l.N.List == nil { // default 4043 def = 1 4044 } 4045 } 4046 4047 if n.Op != OSELECT && def == 0 { 4048 return false 4049 } 4050 return true 4051 } 4052 4053 return false 4054 } 4055 4056 func checkreturn(fn *Node) { 4057 if fn.Type.Outtuple != 0 && fn.Nbody != nil { 4058 if !isterminating(fn.Nbody, 1) { 4059 yyerrorl(int(fn.Func.Endlineno), "missing return at end of function") 4060 } 4061 } 4062 }