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