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