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