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