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