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