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