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