1// Copyright 2009 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package gc 6 7import ( 8 "cmd/compile/internal/types" 9 "cmd/internal/objabi" 10 "cmd/internal/src" 11 "crypto/md5" 12 "encoding/binary" 13 "fmt" 14 "os" 15 "runtime/debug" 16 "sort" 17 "strconv" 18 "strings" 19 "sync" 20 "unicode" 21 "unicode/utf8" 22) 23 24type Error struct { 25 pos src.XPos 26 msg string 27} 28 29var errors []Error 30 31// largeStack is info about a function whose stack frame is too large (rare). 32type largeStack struct { 33 locals int64 34 args int64 35 callee int64 36 pos src.XPos 37} 38 39var ( 40 largeStackFramesMu sync.Mutex // protects largeStackFrames 41 largeStackFrames []largeStack 42) 43 44func errorexit() { 45 flusherrors() 46 if outfile != "" { 47 os.Remove(outfile) 48 } 49 os.Exit(2) 50} 51 52func adderrorname(n *Node) { 53 if n.Op != ODOT { 54 return 55 } 56 old := fmt.Sprintf("%v: undefined: %v\n", n.Line(), n.Left) 57 if len(errors) > 0 && errors[len(errors)-1].pos.Line() == n.Pos.Line() && errors[len(errors)-1].msg == old { 58 errors[len(errors)-1].msg = fmt.Sprintf("%v: undefined: %v in %v\n", n.Line(), n.Left, n) 59 } 60} 61 62func adderr(pos src.XPos, format string, args ...interface{}) { 63 errors = append(errors, Error{ 64 pos: pos, 65 msg: fmt.Sprintf("%v: %s\n", linestr(pos), fmt.Sprintf(format, args...)), 66 }) 67} 68 69// byPos sorts errors by source position. 70type byPos []Error 71 72func (x byPos) Len() int { return len(x) } 73func (x byPos) Less(i, j int) bool { return x[i].pos.Before(x[j].pos) } 74func (x byPos) Swap(i, j int) { x[i], x[j] = x[j], x[i] } 75 76// flusherrors sorts errors seen so far by line number, prints them to stdout, 77// and empties the errors array. 78func flusherrors() { 79 Ctxt.Bso.Flush() 80 if len(errors) == 0 { 81 return 82 } 83 sort.Stable(byPos(errors)) 84 for i, err := range errors { 85 if i == 0 || err.msg != errors[i-1].msg { 86 fmt.Printf("%s", err.msg) 87 } 88 } 89 errors = errors[:0] 90} 91 92func hcrash() { 93 if Debug['h'] != 0 { 94 flusherrors() 95 if outfile != "" { 96 os.Remove(outfile) 97 } 98 var x *int 99 *x = 0 100 } 101} 102 103func linestr(pos src.XPos) string { 104 return Ctxt.OutermostPos(pos).Format(Debug['C'] == 0, Debug['L'] == 1) 105} 106 107// lasterror keeps track of the most recently issued error. 108// It is used to avoid multiple error messages on the same 109// line. 110var lasterror struct { 111 syntax src.XPos // source position of last syntax error 112 other src.XPos // source position of last non-syntax error 113 msg string // error message of last non-syntax error 114} 115 116// sameline reports whether two positions a, b are on the same line. 117func sameline(a, b src.XPos) bool { 118 p := Ctxt.PosTable.Pos(a) 119 q := Ctxt.PosTable.Pos(b) 120 return p.Base() == q.Base() && p.Line() == q.Line() 121} 122 123func yyerrorl(pos src.XPos, format string, args ...interface{}) { 124 msg := fmt.Sprintf(format, args...) 125 126 if strings.HasPrefix(msg, "syntax error") { 127 nsyntaxerrors++ 128 // only one syntax error per line, no matter what error 129 if sameline(lasterror.syntax, pos) { 130 return 131 } 132 lasterror.syntax = pos 133 } else { 134 // only one of multiple equal non-syntax errors per line 135 // (flusherrors shows only one of them, so we filter them 136 // here as best as we can (they may not appear in order) 137 // so that we don't count them here and exit early, and 138 // then have nothing to show for.) 139 if sameline(lasterror.other, pos) && lasterror.msg == msg { 140 return 141 } 142 lasterror.other = pos 143 lasterror.msg = msg 144 } 145 146 adderr(pos, "%s", msg) 147 148 hcrash() 149 nerrors++ 150 if nsavederrors+nerrors >= 10 && Debug['e'] == 0 { 151 flusherrors() 152 fmt.Printf("%v: too many errors\n", linestr(pos)) 153 errorexit() 154 } 155} 156 157func yyerrorv(lang string, format string, args ...interface{}) { 158 what := fmt.Sprintf(format, args...) 159 yyerrorl(lineno, "%s requires %s or later (-lang was set to %s; check go.mod)", what, lang, flag_lang) 160} 161 162func yyerror(format string, args ...interface{}) { 163 yyerrorl(lineno, format, args...) 164} 165 166func Warn(fmt_ string, args ...interface{}) { 167 Warnl(lineno, fmt_, args...) 168} 169 170func Warnl(line src.XPos, fmt_ string, args ...interface{}) { 171 adderr(line, fmt_, args...) 172 if Debug['m'] != 0 { 173 flusherrors() 174 } 175} 176 177func Fatalf(fmt_ string, args ...interface{}) { 178 flusherrors() 179 180 if Debug_panic != 0 || nsavederrors+nerrors == 0 { 181 fmt.Printf("%v: internal compiler error: ", linestr(lineno)) 182 fmt.Printf(fmt_, args...) 183 fmt.Printf("\n") 184 185 // If this is a released compiler version, ask for a bug report. 186 if strings.HasPrefix(objabi.Version, "go") { 187 fmt.Printf("\n") 188 fmt.Printf("Please file a bug report including a short program that triggers the error.\n") 189 fmt.Printf("https://golang.org/issue/new\n") 190 } else { 191 // Not a release; dump a stack trace, too. 192 fmt.Println() 193 os.Stdout.Write(debug.Stack()) 194 fmt.Println() 195 } 196 } 197 198 hcrash() 199 errorexit() 200} 201 202// hasUniquePos reports whether n has a unique position that can be 203// used for reporting error messages. 204// 205// It's primarily used to distinguish references to named objects, 206// whose Pos will point back to their declaration position rather than 207// their usage position. 208func hasUniquePos(n *Node) bool { 209 switch n.Op { 210 case ONAME, OPACK: 211 return false 212 case OLITERAL, OTYPE: 213 if n.Sym != nil { 214 return false 215 } 216 } 217 218 if !n.Pos.IsKnown() { 219 if Debug['K'] != 0 { 220 Warn("setlineno: unknown position (line 0)") 221 } 222 return false 223 } 224 225 return true 226} 227 228func setlineno(n *Node) src.XPos { 229 lno := lineno 230 if n != nil && hasUniquePos(n) { 231 lineno = n.Pos 232 } 233 return lno 234} 235 236func lookup(name string) *types.Sym { 237 return localpkg.Lookup(name) 238} 239 240// lookupN looks up the symbol starting with prefix and ending with 241// the decimal n. If prefix is too long, lookupN panics. 242func lookupN(prefix string, n int) *types.Sym { 243 var buf [20]byte // plenty long enough for all current users 244 copy(buf[:], prefix) 245 b := strconv.AppendInt(buf[:len(prefix)], int64(n), 10) 246 return localpkg.LookupBytes(b) 247} 248 249// autolabel generates a new Name node for use with 250// an automatically generated label. 251// prefix is a short mnemonic (e.g. ".s" for switch) 252// to help with debugging. 253// It should begin with "." to avoid conflicts with 254// user labels. 255func autolabel(prefix string) *types.Sym { 256 if prefix[0] != '.' { 257 Fatalf("autolabel prefix must start with '.', have %q", prefix) 258 } 259 fn := Curfn 260 if Curfn == nil { 261 Fatalf("autolabel outside function") 262 } 263 n := fn.Func.Label 264 fn.Func.Label++ 265 return lookupN(prefix, int(n)) 266} 267 268func restrictlookup(name string, pkg *types.Pkg) *types.Sym { 269 if !types.IsExported(name) && pkg != localpkg { 270 yyerror("cannot refer to unexported name %s.%s", pkg.Name, name) 271 } 272 return pkg.Lookup(name) 273} 274 275// find all the exported symbols in package opkg 276// and make them available in the current package 277func importdot(opkg *types.Pkg, pack *Node) { 278 n := 0 279 for _, s := range opkg.Syms { 280 if s.Def == nil { 281 continue 282 } 283 if !types.IsExported(s.Name) || strings.ContainsRune(s.Name, 0xb7) { // 0xb7 = center dot 284 continue 285 } 286 s1 := lookup(s.Name) 287 if s1.Def != nil { 288 pkgerror := fmt.Sprintf("during import %q", opkg.Path) 289 redeclare(lineno, s1, pkgerror) 290 continue 291 } 292 293 s1.Def = s.Def 294 s1.Block = s.Block 295 if asNode(s1.Def).Name == nil { 296 Dump("s1def", asNode(s1.Def)) 297 Fatalf("missing Name") 298 } 299 asNode(s1.Def).Name.Pack = pack 300 s1.Origpkg = opkg 301 n++ 302 } 303 304 if n == 0 { 305 // can't possibly be used - there were no symbols 306 yyerrorl(pack.Pos, "imported and not used: %q", opkg.Path) 307 } 308} 309 310func nod(op Op, nleft, nright *Node) *Node { 311 return nodl(lineno, op, nleft, nright) 312} 313 314func nodl(pos src.XPos, op Op, nleft, nright *Node) *Node { 315 var n *Node 316 switch op { 317 case OCLOSURE, ODCLFUNC: 318 var x struct { 319 n Node 320 f Func 321 } 322 n = &x.n 323 n.Func = &x.f 324 case ONAME: 325 Fatalf("use newname instead") 326 case OLABEL, OPACK: 327 var x struct { 328 n Node 329 m Name 330 } 331 n = &x.n 332 n.Name = &x.m 333 default: 334 n = new(Node) 335 } 336 n.Op = op 337 n.Left = nleft 338 n.Right = nright 339 n.Pos = pos 340 n.Xoffset = BADWIDTH 341 n.Orig = n 342 return n 343} 344 345// newname returns a new ONAME Node associated with symbol s. 346func newname(s *types.Sym) *Node { 347 n := newnamel(lineno, s) 348 n.Name.Curfn = Curfn 349 return n 350} 351 352// newname returns a new ONAME Node associated with symbol s at position pos. 353// The caller is responsible for setting n.Name.Curfn. 354func newnamel(pos src.XPos, s *types.Sym) *Node { 355 if s == nil { 356 Fatalf("newnamel nil") 357 } 358 359 var x struct { 360 n Node 361 m Name 362 p Param 363 } 364 n := &x.n 365 n.Name = &x.m 366 n.Name.Param = &x.p 367 368 n.Op = ONAME 369 n.Pos = pos 370 n.Orig = n 371 372 n.Sym = s 373 return n 374} 375 376// nodSym makes a Node with Op op and with the Left field set to left 377// and the Sym field set to sym. This is for ODOT and friends. 378func nodSym(op Op, left *Node, sym *types.Sym) *Node { 379 n := nod(op, left, nil) 380 n.Sym = sym 381 return n 382} 383 384// rawcopy returns a shallow copy of n. 385// Note: copy or sepcopy (rather than rawcopy) is usually the 386// correct choice (see comment with Node.copy, below). 387func (n *Node) rawcopy() *Node { 388 copy := *n 389 return © 390} 391 392// sepcopy returns a separate shallow copy of n, with the copy's 393// Orig pointing to itself. 394func (n *Node) sepcopy() *Node { 395 copy := *n 396 copy.Orig = © 397 return © 398} 399 400// copy returns shallow copy of n and adjusts the copy's Orig if 401// necessary: In general, if n.Orig points to itself, the copy's 402// Orig should point to itself as well. Otherwise, if n is modified, 403// the copy's Orig node appears modified, too, and then doesn't 404// represent the original node anymore. 405// (This caused the wrong complit Op to be used when printing error 406// messages; see issues #26855, #27765). 407func (n *Node) copy() *Node { 408 copy := *n 409 if n.Orig == n { 410 copy.Orig = © 411 } 412 return © 413} 414 415// methcmp sorts methods by symbol. 416type methcmp []*types.Field 417 418func (x methcmp) Len() int { return len(x) } 419func (x methcmp) Swap(i, j int) { x[i], x[j] = x[j], x[i] } 420func (x methcmp) Less(i, j int) bool { return x[i].Sym.Less(x[j].Sym) } 421 422func nodintconst(v int64) *Node { 423 u := new(Mpint) 424 u.SetInt64(v) 425 return nodlit(Val{u}) 426} 427 428func nodnil() *Node { 429 return nodlit(Val{new(NilVal)}) 430} 431 432func nodbool(b bool) *Node { 433 return nodlit(Val{b}) 434} 435 436func nodstr(s string) *Node { 437 return nodlit(Val{s}) 438} 439 440// treecopy recursively copies n, with the exception of 441// ONAME, OLITERAL, OTYPE, and ONONAME leaves. 442// If pos.IsKnown(), it sets the source position of newly 443// allocated nodes to pos. 444func treecopy(n *Node, pos src.XPos) *Node { 445 if n == nil { 446 return nil 447 } 448 449 switch n.Op { 450 default: 451 m := n.sepcopy() 452 m.Left = treecopy(n.Left, pos) 453 m.Right = treecopy(n.Right, pos) 454 m.List.Set(listtreecopy(n.List.Slice(), pos)) 455 if pos.IsKnown() { 456 m.Pos = pos 457 } 458 if m.Name != nil && n.Op != ODCLFIELD { 459 Dump("treecopy", n) 460 Fatalf("treecopy Name") 461 } 462 return m 463 464 case OPACK: 465 // OPACK nodes are never valid in const value declarations, 466 // but allow them like any other declared symbol to avoid 467 // crashing (golang.org/issue/11361). 468 fallthrough 469 470 case ONAME, ONONAME, OLITERAL, OTYPE: 471 return n 472 473 } 474} 475 476// isNil reports whether n represents the universal untyped zero value "nil". 477func (n *Node) isNil() bool { 478 // Check n.Orig because constant propagation may produce typed nil constants, 479 // which don't exist in the Go spec. 480 return Isconst(n.Orig, CTNIL) 481} 482 483func isptrto(t *types.Type, et types.EType) bool { 484 if t == nil { 485 return false 486 } 487 if !t.IsPtr() { 488 return false 489 } 490 t = t.Elem() 491 if t == nil { 492 return false 493 } 494 if t.Etype != et { 495 return false 496 } 497 return true 498} 499 500func (n *Node) isBlank() bool { 501 if n == nil { 502 return false 503 } 504 return n.Sym.IsBlank() 505} 506 507// methtype returns the underlying type, if any, 508// that owns methods with receiver parameter t. 509// The result is either a named type or an anonymous struct. 510func methtype(t *types.Type) *types.Type { 511 if t == nil { 512 return nil 513 } 514 515 // Strip away pointer if it's there. 516 if t.IsPtr() { 517 if t.Sym != nil { 518 return nil 519 } 520 t = t.Elem() 521 if t == nil { 522 return nil 523 } 524 } 525 526 // Must be a named type or anonymous struct. 527 if t.Sym == nil && !t.IsStruct() { 528 return nil 529 } 530 531 // Check types. 532 if issimple[t.Etype] { 533 return t 534 } 535 switch t.Etype { 536 case TARRAY, TCHAN, TFUNC, TMAP, TSLICE, TSTRING, TSTRUCT: 537 return t 538 } 539 return nil 540} 541 542// Is type src assignment compatible to type dst? 543// If so, return op code to use in conversion. 544// If not, return 0. 545func assignop(src *types.Type, dst *types.Type, why *string) Op { 546 if why != nil { 547 *why = "" 548 } 549 550 if src == dst { 551 return OCONVNOP 552 } 553 if src == nil || dst == nil || src.Etype == TFORW || dst.Etype == TFORW || src.Orig == nil || dst.Orig == nil { 554 return 0 555 } 556 557 // 1. src type is identical to dst. 558 if types.Identical(src, dst) { 559 return OCONVNOP 560 } 561 562 // 2. src and dst have identical underlying types 563 // and either src or dst is not a named type or 564 // both are empty interface types. 565 // For assignable but different non-empty interface types, 566 // we want to recompute the itab. Recomputing the itab ensures 567 // that itabs are unique (thus an interface with a compile-time 568 // type I has an itab with interface type I). 569 if types.Identical(src.Orig, dst.Orig) { 570 if src.IsEmptyInterface() { 571 // Conversion between two empty interfaces 572 // requires no code. 573 return OCONVNOP 574 } 575 if (src.Sym == nil || dst.Sym == nil) && !src.IsInterface() { 576 // Conversion between two types, at least one unnamed, 577 // needs no conversion. The exception is nonempty interfaces 578 // which need to have their itab updated. 579 return OCONVNOP 580 } 581 } 582 583 // 3. dst is an interface type and src implements dst. 584 if dst.IsInterface() && src.Etype != TNIL { 585 var missing, have *types.Field 586 var ptr int 587 if implements(src, dst, &missing, &have, &ptr) { 588 return OCONVIFACE 589 } 590 591 // we'll have complained about this method anyway, suppress spurious messages. 592 if have != nil && have.Sym == missing.Sym && (have.Type.Broke() || missing.Type.Broke()) { 593 return OCONVIFACE 594 } 595 596 if why != nil { 597 if isptrto(src, TINTER) { 598 *why = fmt.Sprintf(":\n\t%v is pointer to interface, not interface", src) 599 } else if have != nil && have.Sym == missing.Sym && have.Nointerface() { 600 *why = fmt.Sprintf(":\n\t%v does not implement %v (%v method is marked 'nointerface')", src, dst, missing.Sym) 601 } else if have != nil && have.Sym == missing.Sym { 602 *why = fmt.Sprintf(":\n\t%v does not implement %v (wrong type for %v method)\n"+ 603 "\t\thave %v%0S\n\t\twant %v%0S", src, dst, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type) 604 } else if ptr != 0 { 605 *why = fmt.Sprintf(":\n\t%v does not implement %v (%v method has pointer receiver)", src, dst, missing.Sym) 606 } else if have != nil { 607 *why = fmt.Sprintf(":\n\t%v does not implement %v (missing %v method)\n"+ 608 "\t\thave %v%0S\n\t\twant %v%0S", src, dst, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type) 609 } else { 610 *why = fmt.Sprintf(":\n\t%v does not implement %v (missing %v method)", src, dst, missing.Sym) 611 } 612 } 613 614 return 0 615 } 616 617 if isptrto(dst, TINTER) { 618 if why != nil { 619 *why = fmt.Sprintf(":\n\t%v is pointer to interface, not interface", dst) 620 } 621 return 0 622 } 623 624 if src.IsInterface() && dst.Etype != TBLANK { 625 var missing, have *types.Field 626 var ptr int 627 if why != nil && implements(dst, src, &missing, &have, &ptr) { 628 *why = ": need type assertion" 629 } 630 return 0 631 } 632 633 // 4. src is a bidirectional channel value, dst is a channel type, 634 // src and dst have identical element types, and 635 // either src or dst is not a named type. 636 if src.IsChan() && src.ChanDir() == types.Cboth && dst.IsChan() { 637 if types.Identical(src.Elem(), dst.Elem()) && (src.Sym == nil || dst.Sym == nil) { 638 return OCONVNOP 639 } 640 } 641 642 // 5. src is the predeclared identifier nil and dst is a nillable type. 643 if src.Etype == TNIL { 644 switch dst.Etype { 645 case TPTR, 646 TFUNC, 647 TMAP, 648 TCHAN, 649 TINTER, 650 TSLICE: 651 return OCONVNOP 652 } 653 } 654 655 // 6. rule about untyped constants - already converted by defaultlit. 656 657 // 7. Any typed value can be assigned to the blank identifier. 658 if dst.Etype == TBLANK { 659 return OCONVNOP 660 } 661 662 return 0 663} 664 665// Can we convert a value of type src to a value of type dst? 666// If so, return op code to use in conversion (maybe OCONVNOP). 667// If not, return 0. 668func convertop(src *types.Type, dst *types.Type, why *string) Op { 669 if why != nil { 670 *why = "" 671 } 672 673 if src == dst { 674 return OCONVNOP 675 } 676 if src == nil || dst == nil { 677 return 0 678 } 679 680 // Conversions from regular to go:notinheap are not allowed 681 // (unless it's unsafe.Pointer). These are runtime-specific 682 // rules. 683 // (a) Disallow (*T) to (*U) where T is go:notinheap but U isn't. 684 if src.IsPtr() && dst.IsPtr() && dst.Elem().NotInHeap() && !src.Elem().NotInHeap() { 685 if why != nil { 686 *why = fmt.Sprintf(":\n\t%v is go:notinheap, but %v is not", dst.Elem(), src.Elem()) 687 } 688 return 0 689 } 690 // (b) Disallow string to []T where T is go:notinheap. 691 if src.IsString() && dst.IsSlice() && dst.Elem().NotInHeap() && (dst.Elem().Etype == types.Bytetype.Etype || dst.Elem().Etype == types.Runetype.Etype) { 692 if why != nil { 693 *why = fmt.Sprintf(":\n\t%v is go:notinheap", dst.Elem()) 694 } 695 return 0 696 } 697 698 // 1. src can be assigned to dst. 699 op := assignop(src, dst, why) 700 if op != 0 { 701 return op 702 } 703 704 // The rules for interfaces are no different in conversions 705 // than assignments. If interfaces are involved, stop now 706 // with the good message from assignop. 707 // Otherwise clear the error. 708 if src.IsInterface() || dst.IsInterface() { 709 return 0 710 } 711 if why != nil { 712 *why = "" 713 } 714 715 // 2. Ignoring struct tags, src and dst have identical underlying types. 716 if types.IdenticalIgnoreTags(src.Orig, dst.Orig) { 717 return OCONVNOP 718 } 719 720 // 3. src and dst are unnamed pointer types and, ignoring struct tags, 721 // their base types have identical underlying types. 722 if src.IsPtr() && dst.IsPtr() && src.Sym == nil && dst.Sym == nil { 723 if types.IdenticalIgnoreTags(src.Elem().Orig, dst.Elem().Orig) { 724 return OCONVNOP 725 } 726 } 727 728 // 4. src and dst are both integer or floating point types. 729 if (src.IsInteger() || src.IsFloat()) && (dst.IsInteger() || dst.IsFloat()) { 730 if simtype[src.Etype] == simtype[dst.Etype] { 731 return OCONVNOP 732 } 733 return OCONV 734 } 735 736 // 5. src and dst are both complex types. 737 if src.IsComplex() && dst.IsComplex() { 738 if simtype[src.Etype] == simtype[dst.Etype] { 739 return OCONVNOP 740 } 741 return OCONV 742 } 743 744 // 6. src is an integer or has type []byte or []rune 745 // and dst is a string type. 746 if src.IsInteger() && dst.IsString() { 747 return ORUNESTR 748 } 749 750 if src.IsSlice() && dst.IsString() { 751 if src.Elem().Etype == types.Bytetype.Etype { 752 return OBYTES2STR 753 } 754 if src.Elem().Etype == types.Runetype.Etype { 755 return ORUNES2STR 756 } 757 } 758 759 // 7. src is a string and dst is []byte or []rune. 760 // String to slice. 761 if src.IsString() && dst.IsSlice() { 762 if dst.Elem().Etype == types.Bytetype.Etype { 763 return OSTR2BYTES 764 } 765 if dst.Elem().Etype == types.Runetype.Etype { 766 return OSTR2RUNES 767 } 768 } 769 770 // 8. src is a pointer or uintptr and dst is unsafe.Pointer. 771 if (src.IsPtr() || src.Etype == TUINTPTR) && dst.Etype == TUNSAFEPTR { 772 return OCONVNOP 773 } 774 775 // 9. src is unsafe.Pointer and dst is a pointer or uintptr. 776 if src.Etype == TUNSAFEPTR && (dst.IsPtr() || dst.Etype == TUINTPTR) { 777 return OCONVNOP 778 } 779 780 // src is map and dst is a pointer to corresponding hmap. 781 // This rule is needed for the implementation detail that 782 // go gc maps are implemented as a pointer to a hmap struct. 783 if src.Etype == TMAP && dst.IsPtr() && 784 src.MapType().Hmap == dst.Elem() { 785 return OCONVNOP 786 } 787 788 return 0 789} 790 791func assignconv(n *Node, t *types.Type, context string) *Node { 792 return assignconvfn(n, t, func() string { return context }) 793} 794 795// Convert node n for assignment to type t. 796func assignconvfn(n *Node, t *types.Type, context func() string) *Node { 797 if n == nil || n.Type == nil || n.Type.Broke() { 798 return n 799 } 800 801 if t.Etype == TBLANK && n.Type.Etype == TNIL { 802 yyerror("use of untyped nil") 803 } 804 805 n = convlit1(n, t, false, context) 806 if n.Type == nil { 807 return n 808 } 809 if t.Etype == TBLANK { 810 return n 811 } 812 813 // Convert ideal bool from comparison to plain bool 814 // if the next step is non-bool (like interface{}). 815 if n.Type == types.Idealbool && !t.IsBoolean() { 816 if n.Op == ONAME || n.Op == OLITERAL { 817 r := nod(OCONVNOP, n, nil) 818 r.Type = types.Types[TBOOL] 819 r.SetTypecheck(1) 820 r.SetImplicit(true) 821 n = r 822 } 823 } 824 825 if types.Identical(n.Type, t) { 826 return n 827 } 828 829 var why string 830 op := assignop(n.Type, t, &why) 831 if op == 0 { 832 yyerror("cannot use %L as type %v in %s%s", n, t, context(), why) 833 op = OCONV 834 } 835 836 r := nod(op, n, nil) 837 r.Type = t 838 r.SetTypecheck(1) 839 r.SetImplicit(true) 840 r.Orig = n.Orig 841 return r 842} 843 844// IsMethod reports whether n is a method. 845// n must be a function or a method. 846func (n *Node) IsMethod() bool { 847 return n.Type.Recv() != nil 848} 849 850// SliceBounds returns n's slice bounds: low, high, and max in expr[low:high:max]. 851// n must be a slice expression. max is nil if n is a simple slice expression. 852func (n *Node) SliceBounds() (low, high, max *Node) { 853 if n.List.Len() == 0 { 854 return nil, nil, nil 855 } 856 857 switch n.Op { 858 case OSLICE, OSLICEARR, OSLICESTR: 859 s := n.List.Slice() 860 return s[0], s[1], nil 861 case OSLICE3, OSLICE3ARR: 862 s := n.List.Slice() 863 return s[0], s[1], s[2] 864 } 865 Fatalf("SliceBounds op %v: %v", n.Op, n) 866 return nil, nil, nil 867} 868 869// SetSliceBounds sets n's slice bounds, where n is a slice expression. 870// n must be a slice expression. If max is non-nil, n must be a full slice expression. 871func (n *Node) SetSliceBounds(low, high, max *Node) { 872 switch n.Op { 873 case OSLICE, OSLICEARR, OSLICESTR: 874 if max != nil { 875 Fatalf("SetSliceBounds %v given three bounds", n.Op) 876 } 877 s := n.List.Slice() 878 if s == nil { 879 if low == nil && high == nil { 880 return 881 } 882 n.List.Set2(low, high) 883 return 884 } 885 s[0] = low 886 s[1] = high 887 return 888 case OSLICE3, OSLICE3ARR: 889 s := n.List.Slice() 890 if s == nil { 891 if low == nil && high == nil && max == nil { 892 return 893 } 894 n.List.Set3(low, high, max) 895 return 896 } 897 s[0] = low 898 s[1] = high 899 s[2] = max 900 return 901 } 902 Fatalf("SetSliceBounds op %v: %v", n.Op, n) 903} 904 905// IsSlice3 reports whether o is a slice3 op (OSLICE3, OSLICE3ARR). 906// o must be a slicing op. 907func (o Op) IsSlice3() bool { 908 switch o { 909 case OSLICE, OSLICEARR, OSLICESTR: 910 return false 911 case OSLICE3, OSLICE3ARR: 912 return true 913 } 914 Fatalf("IsSlice3 op %v", o) 915 return false 916} 917 918// labeledControl returns the control flow Node (for, switch, select) 919// associated with the label n, if any. 920func (n *Node) labeledControl() *Node { 921 if n.Op != OLABEL { 922 Fatalf("labeledControl %v", n.Op) 923 } 924 ctl := n.Name.Defn 925 if ctl == nil { 926 return nil 927 } 928 switch ctl.Op { 929 case OFOR, OFORUNTIL, OSWITCH, OSELECT: 930 return ctl 931 } 932 return nil 933} 934 935func syslook(name string) *Node { 936 s := Runtimepkg.Lookup(name) 937 if s == nil || s.Def == nil { 938 Fatalf("syslook: can't find runtime.%s", name) 939 } 940 return asNode(s.Def) 941} 942 943// typehash computes a hash value for type t to use in type switch statements. 944func typehash(t *types.Type) uint32 { 945 p := t.LongString() 946 947 // Using MD5 is overkill, but reduces accidental collisions. 948 h := md5.Sum([]byte(p)) 949 return binary.LittleEndian.Uint32(h[:4]) 950} 951 952// updateHasCall checks whether expression n contains any function 953// calls and sets the n.HasCall flag if so. 954func updateHasCall(n *Node) { 955 if n == nil { 956 return 957 } 958 n.SetHasCall(calcHasCall(n)) 959} 960 961func calcHasCall(n *Node) bool { 962 if n.Ninit.Len() != 0 { 963 // TODO(mdempsky): This seems overly conservative. 964 return true 965 } 966 967 switch n.Op { 968 case OLITERAL, ONAME, OTYPE: 969 if n.HasCall() { 970 Fatalf("OLITERAL/ONAME/OTYPE should never have calls: %+v", n) 971 } 972 return false 973 case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER: 974 return true 975 case OANDAND, OOROR: 976 // hard with instrumented code 977 if instrumenting { 978 return true 979 } 980 case OINDEX, OSLICE, OSLICEARR, OSLICE3, OSLICE3ARR, OSLICESTR, 981 ODEREF, ODOTPTR, ODOTTYPE, ODIV, OMOD: 982 // These ops might panic, make sure they are done 983 // before we start marshaling args for a call. See issue 16760. 984 return true 985 986 // When using soft-float, these ops might be rewritten to function calls 987 // so we ensure they are evaluated first. 988 case OADD, OSUB, ONEG, OMUL: 989 if thearch.SoftFloat && (isFloat[n.Type.Etype] || isComplex[n.Type.Etype]) { 990 return true 991 } 992 case OLT, OEQ, ONE, OLE, OGE, OGT: 993 if thearch.SoftFloat && (isFloat[n.Left.Type.Etype] || isComplex[n.Left.Type.Etype]) { 994 return true 995 } 996 case OCONV: 997 if thearch.SoftFloat && ((isFloat[n.Type.Etype] || isComplex[n.Type.Etype]) || (isFloat[n.Left.Type.Etype] || isComplex[n.Left.Type.Etype])) { 998 return true 999 } 1000 } 1001 1002 if n.Left != nil && n.Left.HasCall() { 1003 return true 1004 } 1005 if n.Right != nil && n.Right.HasCall() { 1006 return true 1007 } 1008 return false 1009} 1010 1011func badtype(op Op, tl *types.Type, tr *types.Type) { 1012 fmt_ := "" 1013 if tl != nil { 1014 fmt_ += fmt.Sprintf("\n\t%v", tl) 1015 } 1016 if tr != nil { 1017 fmt_ += fmt.Sprintf("\n\t%v", tr) 1018 } 1019 1020 // common mistake: *struct and *interface. 1021 if tl != nil && tr != nil && tl.IsPtr() && tr.IsPtr() { 1022 if tl.Elem().IsStruct() && tr.Elem().IsInterface() { 1023 fmt_ += "\n\t(*struct vs *interface)" 1024 } else if tl.Elem().IsInterface() && tr.Elem().IsStruct() { 1025 fmt_ += "\n\t(*interface vs *struct)" 1026 } 1027 } 1028 1029 s := fmt_ 1030 yyerror("illegal types for operand: %v%s", op, s) 1031} 1032 1033// brcom returns !(op). 1034// For example, brcom(==) is !=. 1035func brcom(op Op) Op { 1036 switch op { 1037 case OEQ: 1038 return ONE 1039 case ONE: 1040 return OEQ 1041 case OLT: 1042 return OGE 1043 case OGT: 1044 return OLE 1045 case OLE: 1046 return OGT 1047 case OGE: 1048 return OLT 1049 } 1050 Fatalf("brcom: no com for %v\n", op) 1051 return op 1052} 1053 1054// brrev returns reverse(op). 1055// For example, Brrev(<) is >. 1056func brrev(op Op) Op { 1057 switch op { 1058 case OEQ: 1059 return OEQ 1060 case ONE: 1061 return ONE 1062 case OLT: 1063 return OGT 1064 case OGT: 1065 return OLT 1066 case OLE: 1067 return OGE 1068 case OGE: 1069 return OLE 1070 } 1071 Fatalf("brrev: no rev for %v\n", op) 1072 return op 1073} 1074 1075// return side effect-free n, appending side effects to init. 1076// result is assignable if n is. 1077func safeexpr(n *Node, init *Nodes) *Node { 1078 if n == nil { 1079 return nil 1080 } 1081 1082 if n.Ninit.Len() != 0 { 1083 walkstmtlist(n.Ninit.Slice()) 1084 init.AppendNodes(&n.Ninit) 1085 } 1086 1087 switch n.Op { 1088 case ONAME, OLITERAL: 1089 return n 1090 1091 case ODOT, OLEN, OCAP: 1092 l := safeexpr(n.Left, init) 1093 if l == n.Left { 1094 return n 1095 } 1096 r := n.copy() 1097 r.Left = l 1098 r = typecheck(r, ctxExpr) 1099 r = walkexpr(r, init) 1100 return r 1101 1102 case ODOTPTR, ODEREF: 1103 l := safeexpr(n.Left, init) 1104 if l == n.Left { 1105 return n 1106 } 1107 a := n.copy() 1108 a.Left = l 1109 a = walkexpr(a, init) 1110 return a 1111 1112 case OINDEX, OINDEXMAP: 1113 l := safeexpr(n.Left, init) 1114 r := safeexpr(n.Right, init) 1115 if l == n.Left && r == n.Right { 1116 return n 1117 } 1118 a := n.copy() 1119 a.Left = l 1120 a.Right = r 1121 a = walkexpr(a, init) 1122 return a 1123 1124 case OSTRUCTLIT, OARRAYLIT, OSLICELIT: 1125 if isStaticCompositeLiteral(n) { 1126 return n 1127 } 1128 } 1129 1130 // make a copy; must not be used as an lvalue 1131 if islvalue(n) { 1132 Fatalf("missing lvalue case in safeexpr: %v", n) 1133 } 1134 return cheapexpr(n, init) 1135} 1136 1137func copyexpr(n *Node, t *types.Type, init *Nodes) *Node { 1138 l := temp(t) 1139 a := nod(OAS, l, n) 1140 a = typecheck(a, ctxStmt) 1141 a = walkexpr(a, init) 1142 init.Append(a) 1143 return l 1144} 1145 1146// return side-effect free and cheap n, appending side effects to init. 1147// result may not be assignable. 1148func cheapexpr(n *Node, init *Nodes) *Node { 1149 switch n.Op { 1150 case ONAME, OLITERAL: 1151 return n 1152 } 1153 1154 return copyexpr(n, n.Type, init) 1155} 1156 1157// Code to resolve elided DOTs in embedded types. 1158 1159// A Dlist stores a pointer to a TFIELD Type embedded within 1160// a TSTRUCT or TINTER Type. 1161type Dlist struct { 1162 field *types.Field 1163} 1164 1165// dotlist is used by adddot1 to record the path of embedded fields 1166// used to access a target field or method. 1167// Must be non-nil so that dotpath returns a non-nil slice even if d is zero. 1168var dotlist = make([]Dlist, 10) 1169 1170// lookdot0 returns the number of fields or methods named s associated 1171// with Type t. If exactly one exists, it will be returned in *save 1172// (if save is not nil). 1173func lookdot0(s *types.Sym, t *types.Type, save **types.Field, ignorecase bool) int { 1174 u := t 1175 if u.IsPtr() { 1176 u = u.Elem() 1177 } 1178 1179 c := 0 1180 if u.IsStruct() || u.IsInterface() { 1181 for _, f := range u.Fields().Slice() { 1182 if f.Sym == s || (ignorecase && f.IsMethod() && strings.EqualFold(f.Sym.Name, s.Name)) { 1183 if save != nil { 1184 *save = f 1185 } 1186 c++ 1187 } 1188 } 1189 } 1190 1191 u = t 1192 if t.Sym != nil && t.IsPtr() && !t.Elem().IsPtr() { 1193 // If t is a defined pointer type, then x.m is shorthand for (*x).m. 1194 u = t.Elem() 1195 } 1196 u = methtype(u) 1197 if u != nil { 1198 for _, f := range u.Methods().Slice() { 1199 if f.Embedded == 0 && (f.Sym == s || (ignorecase && strings.EqualFold(f.Sym.Name, s.Name))) { 1200 if save != nil { 1201 *save = f 1202 } 1203 c++ 1204 } 1205 } 1206 } 1207 1208 return c 1209} 1210 1211// adddot1 returns the number of fields or methods named s at depth d in Type t. 1212// If exactly one exists, it will be returned in *save (if save is not nil), 1213// and dotlist will contain the path of embedded fields traversed to find it, 1214// in reverse order. If none exist, more will indicate whether t contains any 1215// embedded fields at depth d, so callers can decide whether to retry at 1216// a greater depth. 1217func adddot1(s *types.Sym, t *types.Type, d int, save **types.Field, ignorecase bool) (c int, more bool) { 1218 if t.Recur() { 1219 return 1220 } 1221 t.SetRecur(true) 1222 defer t.SetRecur(false) 1223 1224 var u *types.Type 1225 d-- 1226 if d < 0 { 1227 // We've reached our target depth. If t has any fields/methods 1228 // named s, then we're done. Otherwise, we still need to check 1229 // below for embedded fields. 1230 c = lookdot0(s, t, save, ignorecase) 1231 if c != 0 { 1232 return c, false 1233 } 1234 } 1235 1236 u = t 1237 if u.IsPtr() { 1238 u = u.Elem() 1239 } 1240 if !u.IsStruct() && !u.IsInterface() { 1241 return c, false 1242 } 1243 1244 for _, f := range u.Fields().Slice() { 1245 if f.Embedded == 0 || f.Sym == nil { 1246 continue 1247 } 1248 if d < 0 { 1249 // Found an embedded field at target depth. 1250 return c, true 1251 } 1252 a, more1 := adddot1(s, f.Type, d, save, ignorecase) 1253 if a != 0 && c == 0 { 1254 dotlist[d].field = f 1255 } 1256 c += a 1257 if more1 { 1258 more = true 1259 } 1260 } 1261 1262 return c, more 1263} 1264 1265// dotpath computes the unique shortest explicit selector path to fully qualify 1266// a selection expression x.f, where x is of type t and f is the symbol s. 1267// If no such path exists, dotpath returns nil. 1268// If there are multiple shortest paths to the same depth, ambig is true. 1269func dotpath(s *types.Sym, t *types.Type, save **types.Field, ignorecase bool) (path []Dlist, ambig bool) { 1270 // The embedding of types within structs imposes a tree structure onto 1271 // types: structs parent the types they embed, and types parent their 1272 // fields or methods. Our goal here is to find the shortest path to 1273 // a field or method named s in the subtree rooted at t. To accomplish 1274 // that, we iteratively perform depth-first searches of increasing depth 1275 // until we either find the named field/method or exhaust the tree. 1276 for d := 0; ; d++ { 1277 if d > len(dotlist) { 1278 dotlist = append(dotlist, Dlist{}) 1279 } 1280 if c, more := adddot1(s, t, d, save, ignorecase); c == 1 { 1281 return dotlist[:d], false 1282 } else if c > 1 { 1283 return nil, true 1284 } else if !more { 1285 return nil, false 1286 } 1287 } 1288} 1289 1290// in T.field 1291// find missing fields that 1292// will give shortest unique addressing. 1293// modify the tree with missing type names. 1294func adddot(n *Node) *Node { 1295 n.Left = typecheck(n.Left, ctxType|ctxExpr) 1296 if n.Left.Diag() { 1297 n.SetDiag(true) 1298 } 1299 t := n.Left.Type 1300 if t == nil { 1301 return n 1302 } 1303 1304 if n.Left.Op == OTYPE { 1305 return n 1306 } 1307 1308 s := n.Sym 1309 if s == nil { 1310 return n 1311 } 1312 1313 switch path, ambig := dotpath(s, t, nil, false); { 1314 case path != nil: 1315 // rebuild elided dots 1316 for c := len(path) - 1; c >= 0; c-- { 1317 n.Left = nodSym(ODOT, n.Left, path[c].field.Sym) 1318 n.Left.SetImplicit(true) 1319 } 1320 case ambig: 1321 yyerror("ambiguous selector %v", n) 1322 n.Left = nil 1323 } 1324 1325 return n 1326} 1327 1328// Code to help generate trampoline functions for methods on embedded 1329// types. These are approx the same as the corresponding adddot 1330// routines except that they expect to be called with unique tasks and 1331// they return the actual methods. 1332 1333type Symlink struct { 1334 field *types.Field 1335} 1336 1337var slist []Symlink 1338 1339func expand0(t *types.Type) { 1340 u := t 1341 if u.IsPtr() { 1342 u = u.Elem() 1343 } 1344 1345 if u.IsInterface() { 1346 for _, f := range u.Fields().Slice() { 1347 if f.Sym.Uniq() { 1348 continue 1349 } 1350 f.Sym.SetUniq(true) 1351 slist = append(slist, Symlink{field: f}) 1352 } 1353 1354 return 1355 } 1356 1357 u = methtype(t) 1358 if u != nil { 1359 for _, f := range u.Methods().Slice() { 1360 if f.Sym.Uniq() { 1361 continue 1362 } 1363 f.Sym.SetUniq(true) 1364 slist = append(slist, Symlink{field: f}) 1365 } 1366 } 1367} 1368 1369func expand1(t *types.Type, top bool) { 1370 if t.Recur() { 1371 return 1372 } 1373 t.SetRecur(true) 1374 1375 if !top { 1376 expand0(t) 1377 } 1378 1379 u := t 1380 if u.IsPtr() { 1381 u = u.Elem() 1382 } 1383 1384 if u.IsStruct() || u.IsInterface() { 1385 for _, f := range u.Fields().Slice() { 1386 if f.Embedded == 0 { 1387 continue 1388 } 1389 if f.Sym == nil { 1390 continue 1391 } 1392 expand1(f.Type, false) 1393 } 1394 } 1395 1396 t.SetRecur(false) 1397} 1398 1399func expandmeth(t *types.Type) { 1400 if t == nil || t.AllMethods().Len() != 0 { 1401 return 1402 } 1403 1404 // mark top-level method symbols 1405 // so that expand1 doesn't consider them. 1406 for _, f := range t.Methods().Slice() { 1407 f.Sym.SetUniq(true) 1408 } 1409 1410 // generate all reachable methods 1411 slist = slist[:0] 1412 expand1(t, true) 1413 1414 // check each method to be uniquely reachable 1415 var ms []*types.Field 1416 for i, sl := range slist { 1417 slist[i].field = nil 1418 sl.field.Sym.SetUniq(false) 1419 1420 var f *types.Field 1421 path, _ := dotpath(sl.field.Sym, t, &f, false) 1422 if path == nil { 1423 continue 1424 } 1425 1426 // dotpath may have dug out arbitrary fields, we only want methods. 1427 if !f.IsMethod() { 1428 continue 1429 } 1430 1431 // add it to the base type method list 1432 f = f.Copy() 1433 f.Embedded = 1 // needs a trampoline 1434 for _, d := range path { 1435 if d.field.Type.IsPtr() { 1436 f.Embedded = 2 1437 break 1438 } 1439 } 1440 ms = append(ms, f) 1441 } 1442 1443 for _, f := range t.Methods().Slice() { 1444 f.Sym.SetUniq(false) 1445 } 1446 1447 ms = append(ms, t.Methods().Slice()...) 1448 sort.Sort(methcmp(ms)) 1449 t.AllMethods().Set(ms) 1450} 1451 1452// Given funarg struct list, return list of ODCLFIELD Node fn args. 1453func structargs(tl *types.Type, mustname bool) []*Node { 1454 var args []*Node 1455 gen := 0 1456 for _, t := range tl.Fields().Slice() { 1457 s := t.Sym 1458 if mustname && (s == nil || s.Name == "_") { 1459 // invent a name so that we can refer to it in the trampoline 1460 s = lookupN(".anon", gen) 1461 gen++ 1462 } 1463 a := symfield(s, t.Type) 1464 a.Pos = t.Pos 1465 a.SetIsDDD(t.IsDDD()) 1466 args = append(args, a) 1467 } 1468 1469 return args 1470} 1471 1472// Generate a wrapper function to convert from 1473// a receiver of type T to a receiver of type U. 1474// That is, 1475// 1476// func (t T) M() { 1477// ... 1478// } 1479// 1480// already exists; this function generates 1481// 1482// func (u U) M() { 1483// u.M() 1484// } 1485// 1486// where the types T and U are such that u.M() is valid 1487// and calls the T.M method. 1488// The resulting function is for use in method tables. 1489// 1490// rcvr - U 1491// method - M func (t T)(), a TFIELD type struct 1492// newnam - the eventual mangled name of this function 1493func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) { 1494 if false && Debug['r'] != 0 { 1495 fmt.Printf("genwrapper rcvrtype=%v method=%v newnam=%v\n", rcvr, method, newnam) 1496 } 1497 1498 // Only generate (*T).M wrappers for T.M in T's own package. 1499 if rcvr.IsPtr() && rcvr.Elem() == method.Type.Recv().Type && 1500 rcvr.Elem().Sym != nil && rcvr.Elem().Sym.Pkg != localpkg { 1501 return 1502 } 1503 1504 // Only generate I.M wrappers for I in I's own package 1505 // but keep doing it for error.Error (was issue #29304). 1506 if rcvr.IsInterface() && rcvr.Sym != nil && rcvr.Sym.Pkg != localpkg && rcvr != types.Errortype { 1507 return 1508 } 1509 1510 lineno = autogeneratedPos 1511 dclcontext = PEXTERN 1512 1513 tfn := nod(OTFUNC, nil, nil) 1514 tfn.Left = namedfield(".this", rcvr) 1515 tfn.List.Set(structargs(method.Type.Params(), true)) 1516 tfn.Rlist.Set(structargs(method.Type.Results(), false)) 1517 1518 disableExport(newnam) 1519 fn := dclfunc(newnam, tfn) 1520 fn.Func.SetDupok(true) 1521 1522 nthis := asNode(tfn.Type.Recv().Nname) 1523 1524 methodrcvr := method.Type.Recv().Type 1525 1526 // generate nil pointer check for better error 1527 if rcvr.IsPtr() && rcvr.Elem() == methodrcvr { 1528 // generating wrapper from *T to T. 1529 n := nod(OIF, nil, nil) 1530 n.Left = nod(OEQ, nthis, nodnil()) 1531 call := nod(OCALL, syslook("panicwrap"), nil) 1532 n.Nbody.Set1(call) 1533 fn.Nbody.Append(n) 1534 } 1535 1536 dot := adddot(nodSym(OXDOT, nthis, method.Sym)) 1537 1538 // generate call 1539 // It's not possible to use a tail call when dynamic linking on ppc64le. The 1540 // bad scenario is when a local call is made to the wrapper: the wrapper will 1541 // call the implementation, which might be in a different module and so set 1542 // the TOC to the appropriate value for that module. But if it returns 1543 // directly to the wrapper's caller, nothing will reset it to the correct 1544 // value for that function. 1545 if !instrumenting && rcvr.IsPtr() && methodrcvr.IsPtr() && method.Embedded != 0 && !isifacemethod(method.Type) && !(thearch.LinkArch.Name == "ppc64le" && Ctxt.Flag_dynlink) { 1546 // generate tail call: adjust pointer receiver and jump to embedded method. 1547 dot = dot.Left // skip final .M 1548 // TODO(mdempsky): Remove dependency on dotlist. 1549 if !dotlist[0].field.Type.IsPtr() { 1550 dot = nod(OADDR, dot, nil) 1551 } 1552 as := nod(OAS, nthis, convnop(dot, rcvr)) 1553 fn.Nbody.Append(as) 1554 fn.Nbody.Append(nodSym(ORETJMP, nil, methodSym(methodrcvr, method.Sym))) 1555 } else { 1556 fn.Func.SetWrapper(true) // ignore frame for panic+recover matching 1557 call := nod(OCALL, dot, nil) 1558 call.List.Set(paramNnames(tfn.Type)) 1559 call.SetIsDDD(tfn.Type.IsVariadic()) 1560 if method.Type.NumResults() > 0 { 1561 n := nod(ORETURN, nil, nil) 1562 n.List.Set1(call) 1563 call = n 1564 } 1565 fn.Nbody.Append(call) 1566 } 1567 1568 if false && Debug['r'] != 0 { 1569 dumplist("genwrapper body", fn.Nbody) 1570 } 1571 1572 funcbody() 1573 if debug_dclstack != 0 { 1574 testdclstack() 1575 } 1576 1577 fn = typecheck(fn, ctxStmt) 1578 1579 Curfn = fn 1580 typecheckslice(fn.Nbody.Slice(), ctxStmt) 1581 1582 // Inline calls within (*T).M wrappers. This is safe because we only 1583 // generate those wrappers within the same compilation unit as (T).M. 1584 // TODO(mdempsky): Investigate why we can't enable this more generally. 1585 if rcvr.IsPtr() && rcvr.Elem() == method.Type.Recv().Type && rcvr.Elem().Sym != nil { 1586 inlcalls(fn) 1587 } 1588 escapeFuncs([]*Node{fn}, false) 1589 1590 Curfn = nil 1591 funccompile(fn) 1592} 1593 1594func paramNnames(ft *types.Type) []*Node { 1595 args := make([]*Node, ft.NumParams()) 1596 for i, f := range ft.Params().FieldSlice() { 1597 args[i] = asNode(f.Nname) 1598 } 1599 return args 1600} 1601 1602func hashmem(t *types.Type) *Node { 1603 sym := Runtimepkg.Lookup("memhash") 1604 1605 n := newname(sym) 1606 n.SetClass(PFUNC) 1607 n.Sym.SetFunc(true) 1608 n.Type = functype(nil, []*Node{ 1609 anonfield(types.NewPtr(t)), 1610 anonfield(types.Types[TUINTPTR]), 1611 anonfield(types.Types[TUINTPTR]), 1612 }, []*Node{ 1613 anonfield(types.Types[TUINTPTR]), 1614 }) 1615 return n 1616} 1617 1618func ifacelookdot(s *types.Sym, t *types.Type, ignorecase bool) (m *types.Field, followptr bool) { 1619 if t == nil { 1620 return nil, false 1621 } 1622 1623 path, ambig := dotpath(s, t, &m, ignorecase) 1624 if path == nil { 1625 if ambig { 1626 yyerror("%v.%v is ambiguous", t, s) 1627 } 1628 return nil, false 1629 } 1630 1631 for _, d := range path { 1632 if d.field.Type.IsPtr() { 1633 followptr = true 1634 break 1635 } 1636 } 1637 1638 if !m.IsMethod() { 1639 yyerror("%v.%v is a field, not a method", t, s) 1640 return nil, followptr 1641 } 1642 1643 return m, followptr 1644} 1645 1646func implements(t, iface *types.Type, m, samename **types.Field, ptr *int) bool { 1647 t0 := t 1648 if t == nil { 1649 return false 1650 } 1651 1652 if t.IsInterface() { 1653 i := 0 1654 tms := t.Fields().Slice() 1655 for _, im := range iface.Fields().Slice() { 1656 for i < len(tms) && tms[i].Sym != im.Sym { 1657 i++ 1658 } 1659 if i == len(tms) { 1660 *m = im 1661 *samename = nil 1662 *ptr = 0 1663 return false 1664 } 1665 tm := tms[i] 1666 if !types.Identical(tm.Type, im.Type) { 1667 *m = im 1668 *samename = tm 1669 *ptr = 0 1670 return false 1671 } 1672 } 1673 1674 return true 1675 } 1676 1677 t = methtype(t) 1678 var tms []*types.Field 1679 if t != nil { 1680 expandmeth(t) 1681 tms = t.AllMethods().Slice() 1682 } 1683 i := 0 1684 for _, im := range iface.Fields().Slice() { 1685 if im.Broke() { 1686 continue 1687 } 1688 for i < len(tms) && tms[i].Sym != im.Sym { 1689 i++ 1690 } 1691 if i == len(tms) { 1692 *m = im 1693 *samename, _ = ifacelookdot(im.Sym, t, true) 1694 *ptr = 0 1695 return false 1696 } 1697 tm := tms[i] 1698 if tm.Nointerface() || !types.Identical(tm.Type, im.Type) { 1699 *m = im 1700 *samename = tm 1701 *ptr = 0 1702 return false 1703 } 1704 followptr := tm.Embedded == 2 1705 1706 // if pointer receiver in method, 1707 // the method does not exist for value types. 1708 rcvr := tm.Type.Recv().Type 1709 if rcvr.IsPtr() && !t0.IsPtr() && !followptr && !isifacemethod(tm.Type) { 1710 if false && Debug['r'] != 0 { 1711 yyerror("interface pointer mismatch") 1712 } 1713 1714 *m = im 1715 *samename = nil 1716 *ptr = 1 1717 return false 1718 } 1719 } 1720 1721 // We're going to emit an OCONVIFACE. 1722 // Call itabname so that (t, iface) 1723 // gets added to itabs early, which allows 1724 // us to de-virtualize calls through this 1725 // type/interface pair later. See peekitabs in reflect.go 1726 if isdirectiface(t0) && !iface.IsEmptyInterface() { 1727 itabname(t0, iface) 1728 } 1729 return true 1730} 1731 1732func listtreecopy(l []*Node, pos src.XPos) []*Node { 1733 var out []*Node 1734 for _, n := range l { 1735 out = append(out, treecopy(n, pos)) 1736 } 1737 return out 1738} 1739 1740func liststmt(l []*Node) *Node { 1741 n := nod(OBLOCK, nil, nil) 1742 n.List.Set(l) 1743 if len(l) != 0 { 1744 n.Pos = l[0].Pos 1745 } 1746 return n 1747} 1748 1749func (l Nodes) asblock() *Node { 1750 n := nod(OBLOCK, nil, nil) 1751 n.List = l 1752 if l.Len() != 0 { 1753 n.Pos = l.First().Pos 1754 } 1755 return n 1756} 1757 1758func ngotype(n *Node) *types.Sym { 1759 if n.Type != nil { 1760 return typenamesym(n.Type) 1761 } 1762 return nil 1763} 1764 1765// The result of addinit MUST be assigned back to n, e.g. 1766// n.Left = addinit(n.Left, init) 1767func addinit(n *Node, init []*Node) *Node { 1768 if len(init) == 0 { 1769 return n 1770 } 1771 if n.mayBeShared() { 1772 // Introduce OCONVNOP to hold init list. 1773 n = nod(OCONVNOP, n, nil) 1774 n.Type = n.Left.Type 1775 n.SetTypecheck(1) 1776 } 1777 1778 n.Ninit.Prepend(init...) 1779 n.SetHasCall(true) 1780 return n 1781} 1782 1783// The linker uses the magic symbol prefixes "go." and "type." 1784// Avoid potential confusion between import paths and symbols 1785// by rejecting these reserved imports for now. Also, people 1786// "can do weird things in GOPATH and we'd prefer they didn't 1787// do _that_ weird thing" (per rsc). See also #4257. 1788var reservedimports = []string{ 1789 "go", 1790 "type", 1791} 1792 1793func isbadimport(path string, allowSpace bool) bool { 1794 if strings.Contains(path, "\x00") { 1795 yyerror("import path contains NUL") 1796 return true 1797 } 1798 1799 for _, ri := range reservedimports { 1800 if path == ri { 1801 yyerror("import path %q is reserved and cannot be used", path) 1802 return true 1803 } 1804 } 1805 1806 for _, r := range path { 1807 if r == utf8.RuneError { 1808 yyerror("import path contains invalid UTF-8 sequence: %q", path) 1809 return true 1810 } 1811 1812 if r < 0x20 || r == 0x7f { 1813 yyerror("import path contains control character: %q", path) 1814 return true 1815 } 1816 1817 if r == '\\' { 1818 yyerror("import path contains backslash; use slash: %q", path) 1819 return true 1820 } 1821 1822 if !allowSpace && unicode.IsSpace(r) { 1823 yyerror("import path contains space character: %q", path) 1824 return true 1825 } 1826 1827 if strings.ContainsRune("!\"#$%&'()*,:;<=>?[]^`{|}", r) { 1828 yyerror("import path contains invalid character '%c': %q", r, path) 1829 return true 1830 } 1831 } 1832 1833 return false 1834} 1835 1836// Can this type be stored directly in an interface word? 1837// Yes, if the representation is a single pointer. 1838func isdirectiface(t *types.Type) bool { 1839 if t.Broke() { 1840 return false 1841 } 1842 1843 switch t.Etype { 1844 case TPTR, 1845 TCHAN, 1846 TMAP, 1847 TFUNC, 1848 TUNSAFEPTR: 1849 return true 1850 1851 case TARRAY: 1852 // Array of 1 direct iface type can be direct. 1853 return t.NumElem() == 1 && isdirectiface(t.Elem()) 1854 1855 case TSTRUCT: 1856 // Struct with 1 field of direct iface type can be direct. 1857 return t.NumFields() == 1 && isdirectiface(t.Field(0).Type) 1858 } 1859 1860 return false 1861} 1862 1863// itabType loads the _type field from a runtime.itab struct. 1864func itabType(itab *Node) *Node { 1865 typ := nodSym(ODOTPTR, itab, nil) 1866 typ.Type = types.NewPtr(types.Types[TUINT8]) 1867 typ.SetTypecheck(1) 1868 typ.Xoffset = int64(Widthptr) // offset of _type in runtime.itab 1869 typ.SetBounded(true) // guaranteed not to fault 1870 return typ 1871} 1872 1873// ifaceData loads the data field from an interface. 1874// The concrete type must be known to have type t. 1875// It follows the pointer if !isdirectiface(t). 1876func ifaceData(n *Node, t *types.Type) *Node { 1877 ptr := nodSym(OIDATA, n, nil) 1878 if isdirectiface(t) { 1879 ptr.Type = t 1880 ptr.SetTypecheck(1) 1881 return ptr 1882 } 1883 ptr.Type = types.NewPtr(t) 1884 ptr.SetBounded(true) 1885 ptr.SetTypecheck(1) 1886 ind := nod(ODEREF, ptr, nil) 1887 ind.Type = t 1888 ind.SetTypecheck(1) 1889 return ind 1890} 1891