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