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