github.com/rsc/tmp@v0.0.0-20240517235954-6deaab19748b/bootstrap/internal/gc/const.go (about) 1 // Do not edit. Bootstrap copy of /Users/rsc/g/go/src/cmd/internal/gc/const.go 2 3 // Copyright 2009 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 package gc 8 9 import ( 10 "rsc.io/tmp/bootstrap/internal/obj" 11 "strings" 12 ) 13 14 /* 15 * truncate float literal fv to 32-bit or 64-bit precision 16 * according to type; return truncated value. 17 */ 18 func truncfltlit(oldv *Mpflt, t *Type) *Mpflt { 19 if t == nil { 20 return oldv 21 } 22 23 var v Val 24 v.Ctype = CTFLT 25 v.U.Fval = oldv 26 overflow(v, t) 27 28 fv := newMpflt() 29 mpmovefltflt(fv, oldv) 30 31 // convert large precision literal floating 32 // into limited precision (float64 or float32) 33 switch t.Etype { 34 case TFLOAT64: 35 d := mpgetflt(fv) 36 Mpmovecflt(fv, d) 37 38 case TFLOAT32: 39 d := mpgetflt32(fv) 40 Mpmovecflt(fv, d) 41 } 42 43 return fv 44 } 45 46 /* 47 * convert n, if literal, to type t. 48 * implicit conversion. 49 */ 50 func Convlit(np **Node, t *Type) { 51 convlit1(np, t, false) 52 } 53 54 /* 55 * convert n, if literal, to type t. 56 * return a new node if necessary 57 * (if n is a named constant, can't edit n->type directly). 58 */ 59 func convlit1(np **Node, t *Type, explicit bool) { 60 n := *np 61 if n == nil || t == nil || n.Type == nil || isideal(t) || n.Type == t { 62 return 63 } 64 if !explicit && !isideal(n.Type) { 65 return 66 } 67 68 if n.Op == OLITERAL { 69 nn := Nod(OXXX, nil, nil) 70 *nn = *n 71 n = nn 72 *np = n 73 } 74 75 switch n.Op { 76 default: 77 if n.Type == idealbool { 78 if t.Etype == TBOOL { 79 n.Type = t 80 } else { 81 n.Type = Types[TBOOL] 82 } 83 } 84 85 if n.Type.Etype == TIDEAL { 86 Convlit(&n.Left, t) 87 Convlit(&n.Right, t) 88 n.Type = t 89 } 90 91 return 92 93 // target is invalid type for a constant? leave alone. 94 case OLITERAL: 95 if !okforconst[t.Etype] && n.Type.Etype != TNIL { 96 defaultlit(&n, nil) 97 *np = n 98 return 99 } 100 101 case OLSH, ORSH: 102 convlit1(&n.Left, t, explicit && isideal(n.Left.Type)) 103 t = n.Left.Type 104 if t != nil && t.Etype == TIDEAL && n.Val.Ctype != CTINT { 105 n.Val = toint(n.Val) 106 } 107 if t != nil && !Isint[t.Etype] { 108 Yyerror("invalid operation: %v (shift of type %v)", n, t) 109 t = nil 110 } 111 112 n.Type = t 113 return 114 115 case OCOMPLEX: 116 if n.Type.Etype == TIDEAL { 117 switch t.Etype { 118 // If trying to convert to non-complex type, 119 // leave as complex128 and let typechecker complain. 120 default: 121 t = Types[TCOMPLEX128] 122 fallthrough 123 124 //fallthrough 125 case TCOMPLEX128: 126 n.Type = t 127 128 Convlit(&n.Left, Types[TFLOAT64]) 129 Convlit(&n.Right, Types[TFLOAT64]) 130 131 case TCOMPLEX64: 132 n.Type = t 133 Convlit(&n.Left, Types[TFLOAT32]) 134 Convlit(&n.Right, Types[TFLOAT32]) 135 } 136 } 137 138 return 139 } 140 141 // avoided repeated calculations, errors 142 if Eqtype(n.Type, t) { 143 return 144 } 145 146 ct := consttype(n) 147 var et int 148 if ct < 0 { 149 goto bad 150 } 151 152 et = int(t.Etype) 153 if et == TINTER { 154 if ct == CTNIL && n.Type == Types[TNIL] { 155 n.Type = t 156 return 157 } 158 159 defaultlit(np, nil) 160 return 161 } 162 163 switch ct { 164 default: 165 goto bad 166 167 case CTNIL: 168 switch et { 169 default: 170 n.Type = nil 171 goto bad 172 173 // let normal conversion code handle it 174 case TSTRING: 175 return 176 177 case TARRAY: 178 if !Isslice(t) { 179 goto bad 180 } 181 182 case TPTR32, 183 TPTR64, 184 TINTER, 185 TMAP, 186 TCHAN, 187 TFUNC, 188 TUNSAFEPTR: 189 break 190 191 // A nil literal may be converted to uintptr 192 // if it is an unsafe.Pointer 193 case TUINTPTR: 194 if n.Type.Etype == TUNSAFEPTR { 195 n.Val.U.Xval = new(Mpint) 196 Mpmovecfix(n.Val.U.Xval, 0) 197 n.Val.Ctype = CTINT 198 } else { 199 goto bad 200 } 201 } 202 203 case CTSTR, CTBOOL: 204 if et != int(n.Type.Etype) { 205 goto bad 206 } 207 208 case CTINT, CTRUNE, CTFLT, CTCPLX: 209 ct := int(n.Val.Ctype) 210 if Isint[et] { 211 switch ct { 212 default: 213 goto bad 214 215 case CTCPLX, CTFLT, CTRUNE: 216 n.Val = toint(n.Val) 217 fallthrough 218 219 // flowthrough 220 case CTINT: 221 overflow(n.Val, t) 222 } 223 } else if Isfloat[et] { 224 switch ct { 225 default: 226 goto bad 227 228 case CTCPLX, CTINT, CTRUNE: 229 n.Val = toflt(n.Val) 230 fallthrough 231 232 // flowthrough 233 case CTFLT: 234 n.Val.U.Fval = truncfltlit(n.Val.U.Fval, t) 235 } 236 } else if Iscomplex[et] { 237 switch ct { 238 default: 239 goto bad 240 241 case CTFLT, CTINT, CTRUNE: 242 n.Val = tocplx(n.Val) 243 244 case CTCPLX: 245 overflow(n.Val, t) 246 } 247 } else if et == TSTRING && (ct == CTINT || ct == CTRUNE) && explicit { 248 n.Val = tostr(n.Val) 249 } else { 250 goto bad 251 } 252 } 253 254 n.Type = t 255 return 256 257 bad: 258 if n.Diag == 0 { 259 if t.Broke == 0 { 260 Yyerror("cannot convert %v to type %v", n, t) 261 } 262 n.Diag = 1 263 } 264 265 if isideal(n.Type) { 266 defaultlit(&n, nil) 267 *np = n 268 } 269 270 return 271 } 272 273 func copyval(v Val) Val { 274 switch v.Ctype { 275 case CTINT, CTRUNE: 276 i := new(Mpint) 277 mpmovefixfix(i, v.U.Xval) 278 v.U.Xval = i 279 280 case CTFLT: 281 f := newMpflt() 282 mpmovefltflt(f, v.U.Fval) 283 v.U.Fval = f 284 285 case CTCPLX: 286 c := new(Mpcplx) 287 mpmovefltflt(&c.Real, &v.U.Cval.Real) 288 mpmovefltflt(&c.Imag, &v.U.Cval.Imag) 289 v.U.Cval = c 290 } 291 292 return v 293 } 294 295 func tocplx(v Val) Val { 296 switch v.Ctype { 297 case CTINT, CTRUNE: 298 c := new(Mpcplx) 299 Mpmovefixflt(&c.Real, v.U.Xval) 300 Mpmovecflt(&c.Imag, 0.0) 301 v.Ctype = CTCPLX 302 v.U.Cval = c 303 304 case CTFLT: 305 c := new(Mpcplx) 306 mpmovefltflt(&c.Real, v.U.Fval) 307 Mpmovecflt(&c.Imag, 0.0) 308 v.Ctype = CTCPLX 309 v.U.Cval = c 310 } 311 312 return v 313 } 314 315 func toflt(v Val) Val { 316 switch v.Ctype { 317 case CTINT, CTRUNE: 318 f := newMpflt() 319 Mpmovefixflt(f, v.U.Xval) 320 v.Ctype = CTFLT 321 v.U.Fval = f 322 323 case CTCPLX: 324 f := newMpflt() 325 mpmovefltflt(f, &v.U.Cval.Real) 326 if mpcmpfltc(&v.U.Cval.Imag, 0) != 0 { 327 Yyerror("constant %v%vi truncated to real", Fconv(&v.U.Cval.Real, obj.FmtSharp), Fconv(&v.U.Cval.Imag, obj.FmtSharp|obj.FmtSign)) 328 } 329 v.Ctype = CTFLT 330 v.U.Fval = f 331 } 332 333 return v 334 } 335 336 func toint(v Val) Val { 337 switch v.Ctype { 338 case CTRUNE: 339 v.Ctype = CTINT 340 341 case CTFLT: 342 i := new(Mpint) 343 if mpmovefltfix(i, v.U.Fval) < 0 { 344 Yyerror("constant %v truncated to integer", Fconv(v.U.Fval, obj.FmtSharp)) 345 } 346 v.Ctype = CTINT 347 v.U.Xval = i 348 349 case CTCPLX: 350 i := new(Mpint) 351 if mpmovefltfix(i, &v.U.Cval.Real) < 0 { 352 Yyerror("constant %v%vi truncated to integer", Fconv(&v.U.Cval.Real, obj.FmtSharp), Fconv(&v.U.Cval.Imag, obj.FmtSharp|obj.FmtSign)) 353 } 354 if mpcmpfltc(&v.U.Cval.Imag, 0) != 0 { 355 Yyerror("constant %v%vi truncated to real", Fconv(&v.U.Cval.Real, obj.FmtSharp), Fconv(&v.U.Cval.Imag, obj.FmtSharp|obj.FmtSign)) 356 } 357 v.Ctype = CTINT 358 v.U.Xval = i 359 } 360 361 return v 362 } 363 364 func doesoverflow(v Val, t *Type) bool { 365 switch v.Ctype { 366 case CTINT, CTRUNE: 367 if !Isint[t.Etype] { 368 Fatal("overflow: %v integer constant", t) 369 } 370 if Mpcmpfixfix(v.U.Xval, Minintval[t.Etype]) < 0 || Mpcmpfixfix(v.U.Xval, Maxintval[t.Etype]) > 0 { 371 return true 372 } 373 374 case CTFLT: 375 if !Isfloat[t.Etype] { 376 Fatal("overflow: %v floating-point constant", t) 377 } 378 if mpcmpfltflt(v.U.Fval, minfltval[t.Etype]) <= 0 || mpcmpfltflt(v.U.Fval, maxfltval[t.Etype]) >= 0 { 379 return true 380 } 381 382 case CTCPLX: 383 if !Iscomplex[t.Etype] { 384 Fatal("overflow: %v complex constant", t) 385 } 386 if mpcmpfltflt(&v.U.Cval.Real, minfltval[t.Etype]) <= 0 || mpcmpfltflt(&v.U.Cval.Real, maxfltval[t.Etype]) >= 0 || mpcmpfltflt(&v.U.Cval.Imag, minfltval[t.Etype]) <= 0 || mpcmpfltflt(&v.U.Cval.Imag, maxfltval[t.Etype]) >= 0 { 387 return true 388 } 389 } 390 391 return false 392 } 393 394 func overflow(v Val, t *Type) { 395 // v has already been converted 396 // to appropriate form for t. 397 if t == nil || t.Etype == TIDEAL { 398 return 399 } 400 401 if !doesoverflow(v, t) { 402 return 403 } 404 405 switch v.Ctype { 406 case CTINT, CTRUNE: 407 Yyerror("constant %v overflows %v", v.U.Xval, t) 408 409 case CTFLT: 410 Yyerror("constant %v overflows %v", Fconv(v.U.Fval, obj.FmtSharp), t) 411 412 case CTCPLX: 413 Yyerror("constant %v overflows %v", Fconv(v.U.Fval, obj.FmtSharp), t) 414 } 415 } 416 417 func tostr(v Val) Val { 418 switch v.Ctype { 419 case CTINT, CTRUNE: 420 if Mpcmpfixfix(v.U.Xval, Minintval[TINT]) < 0 || Mpcmpfixfix(v.U.Xval, Maxintval[TINT]) > 0 { 421 Yyerror("overflow in int -> string") 422 } 423 r := uint(Mpgetfix(v.U.Xval)) 424 v = Val{} 425 v.Ctype = CTSTR 426 v.U.Sval = string(r) 427 428 case CTFLT: 429 Yyerror("no float -> string") 430 fallthrough 431 432 case CTNIL: 433 v = Val{} 434 v.Ctype = CTSTR 435 v.U.Sval = "" 436 } 437 438 return v 439 } 440 441 func consttype(n *Node) int { 442 if n == nil || n.Op != OLITERAL { 443 return -1 444 } 445 return int(n.Val.Ctype) 446 } 447 448 func Isconst(n *Node, ct int) bool { 449 t := consttype(n) 450 451 // If the caller is asking for CTINT, allow CTRUNE too. 452 // Makes life easier for back ends. 453 return t == ct || (ct == CTINT && t == CTRUNE) 454 } 455 456 func saveorig(n *Node) *Node { 457 if n == n.Orig { 458 // duplicate node for n->orig. 459 n1 := Nod(OLITERAL, nil, nil) 460 461 n.Orig = n1 462 *n1 = *n 463 } 464 465 return n.Orig 466 } 467 468 /* 469 * if n is constant, rewrite as OLITERAL node. 470 */ 471 func evconst(n *Node) { 472 // pick off just the opcodes that can be 473 // constant evaluated. 474 switch n.Op { 475 default: 476 return 477 478 case OADD, 479 OAND, 480 OANDAND, 481 OANDNOT, 482 OARRAYBYTESTR, 483 OCOM, 484 ODIV, 485 OEQ, 486 OGE, 487 OGT, 488 OLE, 489 OLSH, 490 OLT, 491 OMINUS, 492 OMOD, 493 OMUL, 494 ONE, 495 ONOT, 496 OOR, 497 OOROR, 498 OPLUS, 499 ORSH, 500 OSUB, 501 OXOR: 502 break 503 504 case OCONV: 505 if n.Type == nil { 506 return 507 } 508 if !okforconst[n.Type.Etype] && n.Type.Etype != TNIL { 509 return 510 } 511 512 // merge adjacent constants in the argument list. 513 case OADDSTR: 514 var nr *Node 515 var nl *Node 516 var l2 *NodeList 517 for l1 := n.List; l1 != nil; l1 = l1.Next { 518 if Isconst(l1.N, CTSTR) && l1.Next != nil && Isconst(l1.Next.N, CTSTR) { 519 // merge from l1 up to but not including l2 520 var strs []string 521 l2 = l1 522 for l2 != nil && Isconst(l2.N, CTSTR) { 523 nr = l2.N 524 strs = append(strs, nr.Val.U.Sval) 525 l2 = l2.Next 526 } 527 528 nl = Nod(OXXX, nil, nil) 529 *nl = *l1.N 530 nl.Orig = nl 531 nl.Val.Ctype = CTSTR 532 nl.Val.U.Sval = strings.Join(strs, "") 533 l1.N = nl 534 l1.Next = l2 535 } 536 } 537 538 // fix list end pointer. 539 for l2 := n.List; l2 != nil; l2 = l2.Next { 540 n.List.End = l2 541 } 542 543 // collapse single-constant list to single constant. 544 if count(n.List) == 1 && Isconst(n.List.N, CTSTR) { 545 n.Op = OLITERAL 546 n.Val = n.List.N.Val 547 } 548 549 return 550 } 551 552 nl := n.Left 553 if nl == nil || nl.Type == nil { 554 return 555 } 556 if consttype(nl) < 0 { 557 return 558 } 559 wl := int(nl.Type.Etype) 560 if Isint[wl] || Isfloat[wl] || Iscomplex[wl] { 561 wl = TIDEAL 562 } 563 564 nr := n.Right 565 var rv Val 566 var lno int 567 var wr int 568 var v Val 569 var norig *Node 570 if nr == nil { 571 // copy numeric value to avoid modifying 572 // nl, in case someone still refers to it (e.g. iota). 573 v = nl.Val 574 575 if wl == TIDEAL { 576 v = copyval(v) 577 } 578 579 switch uint32(n.Op)<<16 | uint32(v.Ctype) { 580 default: 581 if n.Diag == 0 { 582 Yyerror("illegal constant expression %v %v", Oconv(int(n.Op), 0), nl.Type) 583 n.Diag = 1 584 } 585 586 return 587 588 case OCONV<<16 | CTNIL, 589 OARRAYBYTESTR<<16 | CTNIL: 590 if n.Type.Etype == TSTRING { 591 v = tostr(v) 592 nl.Type = n.Type 593 break 594 } 595 fallthrough 596 597 // fall through 598 case OCONV<<16 | CTINT, 599 OCONV<<16 | CTRUNE, 600 OCONV<<16 | CTFLT, 601 OCONV<<16 | CTSTR: 602 convlit1(&nl, n.Type, true) 603 604 v = nl.Val 605 606 case OPLUS<<16 | CTINT, 607 OPLUS<<16 | CTRUNE: 608 break 609 610 case OMINUS<<16 | CTINT, 611 OMINUS<<16 | CTRUNE: 612 mpnegfix(v.U.Xval) 613 614 case OCOM<<16 | CTINT, 615 OCOM<<16 | CTRUNE: 616 et := Txxx 617 if nl.Type != nil { 618 et = int(nl.Type.Etype) 619 } 620 621 // calculate the mask in b 622 // result will be (a ^ mask) 623 var b Mpint 624 switch et { 625 // signed guys change sign 626 default: 627 Mpmovecfix(&b, -1) 628 629 // unsigned guys invert their bits 630 case TUINT8, 631 TUINT16, 632 TUINT32, 633 TUINT64, 634 TUINT, 635 TUINTPTR: 636 mpmovefixfix(&b, Maxintval[et]) 637 } 638 639 mpxorfixfix(v.U.Xval, &b) 640 641 case OPLUS<<16 | CTFLT: 642 break 643 644 case OMINUS<<16 | CTFLT: 645 mpnegflt(v.U.Fval) 646 647 case OPLUS<<16 | CTCPLX: 648 break 649 650 case OMINUS<<16 | CTCPLX: 651 mpnegflt(&v.U.Cval.Real) 652 mpnegflt(&v.U.Cval.Imag) 653 654 case ONOT<<16 | CTBOOL: 655 if !v.U.Bval { 656 goto settrue 657 } 658 goto setfalse 659 } 660 goto ret 661 } 662 if nr.Type == nil { 663 return 664 } 665 if consttype(nr) < 0 { 666 return 667 } 668 wr = int(nr.Type.Etype) 669 if Isint[wr] || Isfloat[wr] || Iscomplex[wr] { 670 wr = TIDEAL 671 } 672 673 // check for compatible general types (numeric, string, etc) 674 if wl != wr { 675 goto illegal 676 } 677 678 // check for compatible types. 679 switch n.Op { 680 // ideal const mixes with anything but otherwise must match. 681 default: 682 if nl.Type.Etype != TIDEAL { 683 defaultlit(&nr, nl.Type) 684 n.Right = nr 685 } 686 687 if nr.Type.Etype != TIDEAL { 688 defaultlit(&nl, nr.Type) 689 n.Left = nl 690 } 691 692 if nl.Type.Etype != nr.Type.Etype { 693 goto illegal 694 } 695 696 // right must be unsigned. 697 // left can be ideal. 698 case OLSH, ORSH: 699 defaultlit(&nr, Types[TUINT]) 700 701 n.Right = nr 702 if nr.Type != nil && (Issigned[nr.Type.Etype] || !Isint[nr.Type.Etype]) { 703 goto illegal 704 } 705 if nl.Val.Ctype != CTRUNE { 706 nl.Val = toint(nl.Val) 707 } 708 nr.Val = toint(nr.Val) 709 } 710 711 // copy numeric value to avoid modifying 712 // n->left, in case someone still refers to it (e.g. iota). 713 v = nl.Val 714 715 if wl == TIDEAL { 716 v = copyval(v) 717 } 718 719 rv = nr.Val 720 721 // convert to common ideal 722 if v.Ctype == CTCPLX || rv.Ctype == CTCPLX { 723 v = tocplx(v) 724 rv = tocplx(rv) 725 } 726 727 if v.Ctype == CTFLT || rv.Ctype == CTFLT { 728 v = toflt(v) 729 rv = toflt(rv) 730 } 731 732 // Rune and int turns into rune. 733 if v.Ctype == CTRUNE && rv.Ctype == CTINT { 734 rv.Ctype = CTRUNE 735 } 736 if v.Ctype == CTINT && rv.Ctype == CTRUNE { 737 if n.Op == OLSH || n.Op == ORSH { 738 rv.Ctype = CTINT 739 } else { 740 v.Ctype = CTRUNE 741 } 742 } 743 744 if v.Ctype != rv.Ctype { 745 // Use of undefined name as constant? 746 if (v.Ctype == 0 || rv.Ctype == 0) && nerrors > 0 { 747 return 748 } 749 Fatal("constant type mismatch %v(%d) %v(%d)", nl.Type, v.Ctype, nr.Type, rv.Ctype) 750 } 751 752 // run op 753 switch uint32(n.Op)<<16 | uint32(v.Ctype) { 754 default: 755 goto illegal 756 757 case OADD<<16 | CTINT, 758 OADD<<16 | CTRUNE: 759 mpaddfixfix(v.U.Xval, rv.U.Xval, 0) 760 761 case OSUB<<16 | CTINT, 762 OSUB<<16 | CTRUNE: 763 mpsubfixfix(v.U.Xval, rv.U.Xval) 764 765 case OMUL<<16 | CTINT, 766 OMUL<<16 | CTRUNE: 767 mpmulfixfix(v.U.Xval, rv.U.Xval) 768 769 case ODIV<<16 | CTINT, 770 ODIV<<16 | CTRUNE: 771 if mpcmpfixc(rv.U.Xval, 0) == 0 { 772 Yyerror("division by zero") 773 Mpmovecfix(v.U.Xval, 1) 774 break 775 } 776 777 mpdivfixfix(v.U.Xval, rv.U.Xval) 778 779 case OMOD<<16 | CTINT, 780 OMOD<<16 | CTRUNE: 781 if mpcmpfixc(rv.U.Xval, 0) == 0 { 782 Yyerror("division by zero") 783 Mpmovecfix(v.U.Xval, 1) 784 break 785 } 786 787 mpmodfixfix(v.U.Xval, rv.U.Xval) 788 789 case OLSH<<16 | CTINT, 790 OLSH<<16 | CTRUNE: 791 mplshfixfix(v.U.Xval, rv.U.Xval) 792 793 case ORSH<<16 | CTINT, 794 ORSH<<16 | CTRUNE: 795 mprshfixfix(v.U.Xval, rv.U.Xval) 796 797 case OOR<<16 | CTINT, 798 OOR<<16 | CTRUNE: 799 mporfixfix(v.U.Xval, rv.U.Xval) 800 801 case OAND<<16 | CTINT, 802 OAND<<16 | CTRUNE: 803 mpandfixfix(v.U.Xval, rv.U.Xval) 804 805 case OANDNOT<<16 | CTINT, 806 OANDNOT<<16 | CTRUNE: 807 mpandnotfixfix(v.U.Xval, rv.U.Xval) 808 809 case OXOR<<16 | CTINT, 810 OXOR<<16 | CTRUNE: 811 mpxorfixfix(v.U.Xval, rv.U.Xval) 812 813 case OADD<<16 | CTFLT: 814 mpaddfltflt(v.U.Fval, rv.U.Fval) 815 816 case OSUB<<16 | CTFLT: 817 mpsubfltflt(v.U.Fval, rv.U.Fval) 818 819 case OMUL<<16 | CTFLT: 820 mpmulfltflt(v.U.Fval, rv.U.Fval) 821 822 case ODIV<<16 | CTFLT: 823 if mpcmpfltc(rv.U.Fval, 0) == 0 { 824 Yyerror("division by zero") 825 Mpmovecflt(v.U.Fval, 1.0) 826 break 827 } 828 829 mpdivfltflt(v.U.Fval, rv.U.Fval) 830 831 // The default case above would print 'ideal % ideal', 832 // which is not quite an ideal error. 833 case OMOD<<16 | CTFLT: 834 if n.Diag == 0 { 835 Yyerror("illegal constant expression: floating-point %% operation") 836 n.Diag = 1 837 } 838 839 return 840 841 case OADD<<16 | CTCPLX: 842 mpaddfltflt(&v.U.Cval.Real, &rv.U.Cval.Real) 843 mpaddfltflt(&v.U.Cval.Imag, &rv.U.Cval.Imag) 844 845 case OSUB<<16 | CTCPLX: 846 mpsubfltflt(&v.U.Cval.Real, &rv.U.Cval.Real) 847 mpsubfltflt(&v.U.Cval.Imag, &rv.U.Cval.Imag) 848 849 case OMUL<<16 | CTCPLX: 850 cmplxmpy(v.U.Cval, rv.U.Cval) 851 852 case ODIV<<16 | CTCPLX: 853 if mpcmpfltc(&rv.U.Cval.Real, 0) == 0 && mpcmpfltc(&rv.U.Cval.Imag, 0) == 0 { 854 Yyerror("complex division by zero") 855 Mpmovecflt(&rv.U.Cval.Real, 1.0) 856 Mpmovecflt(&rv.U.Cval.Imag, 0.0) 857 break 858 } 859 860 cmplxdiv(v.U.Cval, rv.U.Cval) 861 862 case OEQ<<16 | CTNIL: 863 goto settrue 864 865 case ONE<<16 | CTNIL: 866 goto setfalse 867 868 case OEQ<<16 | CTINT, 869 OEQ<<16 | CTRUNE: 870 if Mpcmpfixfix(v.U.Xval, rv.U.Xval) == 0 { 871 goto settrue 872 } 873 goto setfalse 874 875 case ONE<<16 | CTINT, 876 ONE<<16 | CTRUNE: 877 if Mpcmpfixfix(v.U.Xval, rv.U.Xval) != 0 { 878 goto settrue 879 } 880 goto setfalse 881 882 case OLT<<16 | CTINT, 883 OLT<<16 | CTRUNE: 884 if Mpcmpfixfix(v.U.Xval, rv.U.Xval) < 0 { 885 goto settrue 886 } 887 goto setfalse 888 889 case OLE<<16 | CTINT, 890 OLE<<16 | CTRUNE: 891 if Mpcmpfixfix(v.U.Xval, rv.U.Xval) <= 0 { 892 goto settrue 893 } 894 goto setfalse 895 896 case OGE<<16 | CTINT, 897 OGE<<16 | CTRUNE: 898 if Mpcmpfixfix(v.U.Xval, rv.U.Xval) >= 0 { 899 goto settrue 900 } 901 goto setfalse 902 903 case OGT<<16 | CTINT, 904 OGT<<16 | CTRUNE: 905 if Mpcmpfixfix(v.U.Xval, rv.U.Xval) > 0 { 906 goto settrue 907 } 908 goto setfalse 909 910 case OEQ<<16 | CTFLT: 911 if mpcmpfltflt(v.U.Fval, rv.U.Fval) == 0 { 912 goto settrue 913 } 914 goto setfalse 915 916 case ONE<<16 | CTFLT: 917 if mpcmpfltflt(v.U.Fval, rv.U.Fval) != 0 { 918 goto settrue 919 } 920 goto setfalse 921 922 case OLT<<16 | CTFLT: 923 if mpcmpfltflt(v.U.Fval, rv.U.Fval) < 0 { 924 goto settrue 925 } 926 goto setfalse 927 928 case OLE<<16 | CTFLT: 929 if mpcmpfltflt(v.U.Fval, rv.U.Fval) <= 0 { 930 goto settrue 931 } 932 goto setfalse 933 934 case OGE<<16 | CTFLT: 935 if mpcmpfltflt(v.U.Fval, rv.U.Fval) >= 0 { 936 goto settrue 937 } 938 goto setfalse 939 940 case OGT<<16 | CTFLT: 941 if mpcmpfltflt(v.U.Fval, rv.U.Fval) > 0 { 942 goto settrue 943 } 944 goto setfalse 945 946 case OEQ<<16 | CTCPLX: 947 if mpcmpfltflt(&v.U.Cval.Real, &rv.U.Cval.Real) == 0 && mpcmpfltflt(&v.U.Cval.Imag, &rv.U.Cval.Imag) == 0 { 948 goto settrue 949 } 950 goto setfalse 951 952 case ONE<<16 | CTCPLX: 953 if mpcmpfltflt(&v.U.Cval.Real, &rv.U.Cval.Real) != 0 || mpcmpfltflt(&v.U.Cval.Imag, &rv.U.Cval.Imag) != 0 { 954 goto settrue 955 } 956 goto setfalse 957 958 case OEQ<<16 | CTSTR: 959 if cmpslit(nl, nr) == 0 { 960 goto settrue 961 } 962 goto setfalse 963 964 case ONE<<16 | CTSTR: 965 if cmpslit(nl, nr) != 0 { 966 goto settrue 967 } 968 goto setfalse 969 970 case OLT<<16 | CTSTR: 971 if cmpslit(nl, nr) < 0 { 972 goto settrue 973 } 974 goto setfalse 975 976 case OLE<<16 | CTSTR: 977 if cmpslit(nl, nr) <= 0 { 978 goto settrue 979 } 980 goto setfalse 981 982 case OGE<<16 | CTSTR: 983 if cmpslit(nl, nr) >= 0 { 984 goto settrue 985 } 986 goto setfalse 987 988 case OGT<<16 | CTSTR: 989 if cmpslit(nl, nr) > 0 { 990 goto settrue 991 } 992 goto setfalse 993 994 case OOROR<<16 | CTBOOL: 995 if v.U.Bval || rv.U.Bval { 996 goto settrue 997 } 998 goto setfalse 999 1000 case OANDAND<<16 | CTBOOL: 1001 if v.U.Bval && rv.U.Bval { 1002 goto settrue 1003 } 1004 goto setfalse 1005 1006 case OEQ<<16 | CTBOOL: 1007 if v.U.Bval == rv.U.Bval { 1008 goto settrue 1009 } 1010 goto setfalse 1011 1012 case ONE<<16 | CTBOOL: 1013 if v.U.Bval != rv.U.Bval { 1014 goto settrue 1015 } 1016 goto setfalse 1017 } 1018 1019 goto ret 1020 1021 ret: 1022 norig = saveorig(n) 1023 *n = *nl 1024 1025 // restore value of n->orig. 1026 n.Orig = norig 1027 1028 n.Val = v 1029 1030 // check range. 1031 lno = int(setlineno(n)) 1032 1033 overflow(v, n.Type) 1034 lineno = int32(lno) 1035 1036 // truncate precision for non-ideal float. 1037 if v.Ctype == CTFLT && n.Type.Etype != TIDEAL { 1038 n.Val.U.Fval = truncfltlit(v.U.Fval, n.Type) 1039 } 1040 return 1041 1042 settrue: 1043 norig = saveorig(n) 1044 *n = *Nodbool(true) 1045 n.Orig = norig 1046 return 1047 1048 setfalse: 1049 norig = saveorig(n) 1050 *n = *Nodbool(false) 1051 n.Orig = norig 1052 return 1053 1054 illegal: 1055 if n.Diag == 0 { 1056 Yyerror("illegal constant expression: %v %v %v", nl.Type, Oconv(int(n.Op), 0), nr.Type) 1057 n.Diag = 1 1058 } 1059 1060 return 1061 } 1062 1063 func nodlit(v Val) *Node { 1064 n := Nod(OLITERAL, nil, nil) 1065 n.Val = v 1066 switch v.Ctype { 1067 default: 1068 Fatal("nodlit ctype %d", v.Ctype) 1069 1070 case CTSTR: 1071 n.Type = idealstring 1072 1073 case CTBOOL: 1074 n.Type = idealbool 1075 1076 case CTINT, CTRUNE, CTFLT, CTCPLX: 1077 n.Type = Types[TIDEAL] 1078 1079 case CTNIL: 1080 n.Type = Types[TNIL] 1081 } 1082 1083 return n 1084 } 1085 1086 func nodcplxlit(r Val, i Val) *Node { 1087 r = toflt(r) 1088 i = toflt(i) 1089 1090 c := new(Mpcplx) 1091 n := Nod(OLITERAL, nil, nil) 1092 n.Type = Types[TIDEAL] 1093 n.Val.U.Cval = c 1094 n.Val.Ctype = CTCPLX 1095 1096 if r.Ctype != CTFLT || i.Ctype != CTFLT { 1097 Fatal("nodcplxlit ctype %d/%d", r.Ctype, i.Ctype) 1098 } 1099 1100 mpmovefltflt(&c.Real, r.U.Fval) 1101 mpmovefltflt(&c.Imag, i.U.Fval) 1102 return n 1103 } 1104 1105 // idealkind returns a constant kind like consttype 1106 // but for an arbitrary "ideal" (untyped constant) expression. 1107 func idealkind(n *Node) int { 1108 if n == nil || !isideal(n.Type) { 1109 return CTxxx 1110 } 1111 1112 switch n.Op { 1113 default: 1114 return CTxxx 1115 1116 case OLITERAL: 1117 return int(n.Val.Ctype) 1118 1119 // numeric kinds. 1120 case OADD, 1121 OAND, 1122 OANDNOT, 1123 OCOM, 1124 ODIV, 1125 OMINUS, 1126 OMOD, 1127 OMUL, 1128 OSUB, 1129 OXOR, 1130 OOR, 1131 OPLUS: 1132 k1 := idealkind(n.Left) 1133 1134 k2 := idealkind(n.Right) 1135 if k1 > k2 { 1136 return k1 1137 } else { 1138 return k2 1139 } 1140 1141 case OREAL, OIMAG: 1142 return CTFLT 1143 1144 case OCOMPLEX: 1145 return CTCPLX 1146 1147 case OADDSTR: 1148 return CTSTR 1149 1150 case OANDAND, 1151 OEQ, 1152 OGE, 1153 OGT, 1154 OLE, 1155 OLT, 1156 ONE, 1157 ONOT, 1158 OOROR, 1159 OCMPSTR, 1160 OCMPIFACE: 1161 return CTBOOL 1162 1163 // shifts (beware!). 1164 case OLSH, ORSH: 1165 return idealkind(n.Left) 1166 } 1167 } 1168 1169 func defaultlit(np **Node, t *Type) { 1170 n := *np 1171 if n == nil || !isideal(n.Type) { 1172 return 1173 } 1174 1175 if n.Op == OLITERAL { 1176 nn := Nod(OXXX, nil, nil) 1177 *nn = *n 1178 n = nn 1179 *np = n 1180 } 1181 1182 lno := int(setlineno(n)) 1183 ctype := idealkind(n) 1184 var t1 *Type 1185 switch ctype { 1186 default: 1187 if t != nil { 1188 Convlit(np, t) 1189 return 1190 } 1191 1192 if n.Val.Ctype == CTNIL { 1193 lineno = int32(lno) 1194 if n.Diag == 0 { 1195 Yyerror("use of untyped nil") 1196 n.Diag = 1 1197 } 1198 1199 n.Type = nil 1200 break 1201 } 1202 1203 if n.Val.Ctype == CTSTR { 1204 t1 := Types[TSTRING] 1205 Convlit(np, t1) 1206 break 1207 } 1208 1209 Yyerror("defaultlit: unknown literal: %v", n) 1210 1211 case CTxxx: 1212 Fatal("defaultlit: idealkind is CTxxx: %v", Nconv(n, obj.FmtSign)) 1213 1214 case CTBOOL: 1215 t1 := Types[TBOOL] 1216 if t != nil && t.Etype == TBOOL { 1217 t1 = t 1218 } 1219 Convlit(np, t1) 1220 1221 case CTINT: 1222 t1 = Types[TINT] 1223 goto num 1224 1225 case CTRUNE: 1226 t1 = runetype 1227 goto num 1228 1229 case CTFLT: 1230 t1 = Types[TFLOAT64] 1231 goto num 1232 1233 case CTCPLX: 1234 t1 = Types[TCOMPLEX128] 1235 goto num 1236 } 1237 1238 lineno = int32(lno) 1239 return 1240 1241 num: 1242 if t != nil { 1243 if Isint[t.Etype] { 1244 t1 = t 1245 n.Val = toint(n.Val) 1246 } else if Isfloat[t.Etype] { 1247 t1 = t 1248 n.Val = toflt(n.Val) 1249 } else if Iscomplex[t.Etype] { 1250 t1 = t 1251 n.Val = tocplx(n.Val) 1252 } 1253 } 1254 1255 overflow(n.Val, t1) 1256 Convlit(np, t1) 1257 lineno = int32(lno) 1258 return 1259 } 1260 1261 /* 1262 * defaultlit on both nodes simultaneously; 1263 * if they're both ideal going in they better 1264 * get the same type going out. 1265 * force means must assign concrete (non-ideal) type. 1266 */ 1267 func defaultlit2(lp **Node, rp **Node, force int) { 1268 l := *lp 1269 r := *rp 1270 if l.Type == nil || r.Type == nil { 1271 return 1272 } 1273 if !isideal(l.Type) { 1274 Convlit(rp, l.Type) 1275 return 1276 } 1277 1278 if !isideal(r.Type) { 1279 Convlit(lp, r.Type) 1280 return 1281 } 1282 1283 if force == 0 { 1284 return 1285 } 1286 if l.Type.Etype == TBOOL { 1287 Convlit(lp, Types[TBOOL]) 1288 Convlit(rp, Types[TBOOL]) 1289 } 1290 1291 lkind := idealkind(l) 1292 rkind := idealkind(r) 1293 if lkind == CTCPLX || rkind == CTCPLX { 1294 Convlit(lp, Types[TCOMPLEX128]) 1295 Convlit(rp, Types[TCOMPLEX128]) 1296 return 1297 } 1298 1299 if lkind == CTFLT || rkind == CTFLT { 1300 Convlit(lp, Types[TFLOAT64]) 1301 Convlit(rp, Types[TFLOAT64]) 1302 return 1303 } 1304 1305 if lkind == CTRUNE || rkind == CTRUNE { 1306 Convlit(lp, runetype) 1307 Convlit(rp, runetype) 1308 return 1309 } 1310 1311 Convlit(lp, Types[TINT]) 1312 Convlit(rp, Types[TINT]) 1313 } 1314 1315 func cmpslit(l, r *Node) int { 1316 return stringsCompare(l.Val.U.Sval, r.Val.U.Sval) 1317 } 1318 1319 func Smallintconst(n *Node) bool { 1320 if n.Op == OLITERAL && Isconst(n, CTINT) && n.Type != nil { 1321 switch Simtype[n.Type.Etype] { 1322 case TINT8, 1323 TUINT8, 1324 TINT16, 1325 TUINT16, 1326 TINT32, 1327 TUINT32, 1328 TBOOL, 1329 TPTR32: 1330 return true 1331 1332 case TIDEAL, TINT64, TUINT64, TPTR64: 1333 if Mpcmpfixfix(n.Val.U.Xval, Minintval[TINT32]) < 0 || Mpcmpfixfix(n.Val.U.Xval, Maxintval[TINT32]) > 0 { 1334 break 1335 } 1336 return true 1337 } 1338 } 1339 1340 return false 1341 } 1342 1343 func nonnegconst(n *Node) int { 1344 if n.Op == OLITERAL && n.Type != nil { 1345 switch Simtype[n.Type.Etype] { 1346 // check negative and 2^31 1347 case TINT8, 1348 TUINT8, 1349 TINT16, 1350 TUINT16, 1351 TINT32, 1352 TUINT32, 1353 TINT64, 1354 TUINT64, 1355 TIDEAL: 1356 if Mpcmpfixfix(n.Val.U.Xval, Minintval[TUINT32]) < 0 || Mpcmpfixfix(n.Val.U.Xval, Maxintval[TINT32]) > 0 { 1357 break 1358 } 1359 return int(Mpgetfix(n.Val.U.Xval)) 1360 } 1361 } 1362 1363 return -1 1364 } 1365 1366 /* 1367 * convert x to type et and back to int64 1368 * for sign extension and truncation. 1369 */ 1370 func iconv(x int64, et int) int64 { 1371 switch et { 1372 case TINT8: 1373 x = int64(int8(x)) 1374 1375 case TUINT8: 1376 x = int64(uint8(x)) 1377 1378 case TINT16: 1379 x = int64(int16(x)) 1380 1381 case TUINT16: 1382 x = int64(uint64(x)) 1383 1384 case TINT32: 1385 x = int64(int32(x)) 1386 1387 case TUINT32: 1388 x = int64(uint32(x)) 1389 1390 case TINT64, TUINT64: 1391 break 1392 } 1393 1394 return x 1395 } 1396 1397 /* 1398 * convert constant val to type t; leave in con. 1399 * for back end. 1400 */ 1401 func Convconst(con *Node, t *Type, val *Val) { 1402 tt := Simsimtype(t) 1403 1404 // copy the constant for conversion 1405 Nodconst(con, Types[TINT8], 0) 1406 1407 con.Type = t 1408 con.Val = *val 1409 1410 if Isint[tt] { 1411 con.Val.Ctype = CTINT 1412 con.Val.U.Xval = new(Mpint) 1413 var i int64 1414 switch val.Ctype { 1415 default: 1416 Fatal("convconst ctype=%d %v", val.Ctype, Tconv(t, obj.FmtLong)) 1417 1418 case CTINT, CTRUNE: 1419 i = Mpgetfix(val.U.Xval) 1420 1421 case CTBOOL: 1422 i = int64(obj.Bool2int(val.U.Bval)) 1423 1424 case CTNIL: 1425 i = 0 1426 } 1427 1428 i = iconv(i, tt) 1429 Mpmovecfix(con.Val.U.Xval, i) 1430 return 1431 } 1432 1433 if Isfloat[tt] { 1434 con.Val = toflt(con.Val) 1435 if con.Val.Ctype != CTFLT { 1436 Fatal("convconst ctype=%d %v", con.Val.Ctype, t) 1437 } 1438 if tt == TFLOAT32 { 1439 con.Val.U.Fval = truncfltlit(con.Val.U.Fval, t) 1440 } 1441 return 1442 } 1443 1444 if Iscomplex[tt] { 1445 con.Val = tocplx(con.Val) 1446 if tt == TCOMPLEX64 { 1447 con.Val.U.Cval.Real = *truncfltlit(&con.Val.U.Cval.Real, Types[TFLOAT32]) 1448 con.Val.U.Cval.Imag = *truncfltlit(&con.Val.U.Cval.Imag, Types[TFLOAT32]) 1449 } 1450 1451 return 1452 } 1453 1454 Fatal("convconst %v constant", Tconv(t, obj.FmtLong)) 1455 } 1456 1457 // complex multiply v *= rv 1458 // (a, b) * (c, d) = (a*c - b*d, b*c + a*d) 1459 func cmplxmpy(v *Mpcplx, rv *Mpcplx) { 1460 var ac Mpflt 1461 var bd Mpflt 1462 var bc Mpflt 1463 var ad Mpflt 1464 1465 mpmovefltflt(&ac, &v.Real) 1466 mpmulfltflt(&ac, &rv.Real) // ac 1467 1468 mpmovefltflt(&bd, &v.Imag) 1469 1470 mpmulfltflt(&bd, &rv.Imag) // bd 1471 1472 mpmovefltflt(&bc, &v.Imag) 1473 1474 mpmulfltflt(&bc, &rv.Real) // bc 1475 1476 mpmovefltflt(&ad, &v.Real) 1477 1478 mpmulfltflt(&ad, &rv.Imag) // ad 1479 1480 mpmovefltflt(&v.Real, &ac) 1481 1482 mpsubfltflt(&v.Real, &bd) // ac-bd 1483 1484 mpmovefltflt(&v.Imag, &bc) 1485 1486 mpaddfltflt(&v.Imag, &ad) // bc+ad 1487 } 1488 1489 // complex divide v /= rv 1490 // (a, b) / (c, d) = ((a*c + b*d), (b*c - a*d))/(c*c + d*d) 1491 func cmplxdiv(v *Mpcplx, rv *Mpcplx) { 1492 var ac Mpflt 1493 var bd Mpflt 1494 var bc Mpflt 1495 var ad Mpflt 1496 var cc_plus_dd Mpflt 1497 1498 mpmovefltflt(&cc_plus_dd, &rv.Real) 1499 mpmulfltflt(&cc_plus_dd, &rv.Real) // cc 1500 1501 mpmovefltflt(&ac, &rv.Imag) 1502 1503 mpmulfltflt(&ac, &rv.Imag) // dd 1504 1505 mpaddfltflt(&cc_plus_dd, &ac) // cc+dd 1506 1507 mpmovefltflt(&ac, &v.Real) 1508 1509 mpmulfltflt(&ac, &rv.Real) // ac 1510 1511 mpmovefltflt(&bd, &v.Imag) 1512 1513 mpmulfltflt(&bd, &rv.Imag) // bd 1514 1515 mpmovefltflt(&bc, &v.Imag) 1516 1517 mpmulfltflt(&bc, &rv.Real) // bc 1518 1519 mpmovefltflt(&ad, &v.Real) 1520 1521 mpmulfltflt(&ad, &rv.Imag) // ad 1522 1523 mpmovefltflt(&v.Real, &ac) 1524 1525 mpaddfltflt(&v.Real, &bd) // ac+bd 1526 mpdivfltflt(&v.Real, &cc_plus_dd) // (ac+bd)/(cc+dd) 1527 1528 mpmovefltflt(&v.Imag, &bc) 1529 1530 mpsubfltflt(&v.Imag, &ad) // bc-ad 1531 mpdivfltflt(&v.Imag, &cc_plus_dd) // (bc+ad)/(cc+dd) 1532 } 1533 1534 // Is n a Go language constant (as opposed to a compile-time constant)? 1535 // Expressions derived from nil, like string([]byte(nil)), while they 1536 // may be known at compile time, are not Go language constants. 1537 // Only called for expressions known to evaluated to compile-time 1538 // constants. 1539 func isgoconst(n *Node) bool { 1540 if n.Orig != nil { 1541 n = n.Orig 1542 } 1543 1544 switch n.Op { 1545 case OADD, 1546 OADDSTR, 1547 OAND, 1548 OANDAND, 1549 OANDNOT, 1550 OCOM, 1551 ODIV, 1552 OEQ, 1553 OGE, 1554 OGT, 1555 OLE, 1556 OLSH, 1557 OLT, 1558 OMINUS, 1559 OMOD, 1560 OMUL, 1561 ONE, 1562 ONOT, 1563 OOR, 1564 OOROR, 1565 OPLUS, 1566 ORSH, 1567 OSUB, 1568 OXOR, 1569 OIOTA, 1570 OCOMPLEX, 1571 OREAL, 1572 OIMAG: 1573 if isgoconst(n.Left) && (n.Right == nil || isgoconst(n.Right)) { 1574 return true 1575 } 1576 1577 case OCONV: 1578 if okforconst[n.Type.Etype] && isgoconst(n.Left) { 1579 return true 1580 } 1581 1582 case OLEN, OCAP: 1583 l := n.Left 1584 if isgoconst(l) { 1585 return true 1586 } 1587 1588 // Special case: len/cap is constant when applied to array or 1589 // pointer to array when the expression does not contain 1590 // function calls or channel receive operations. 1591 t := l.Type 1592 1593 if t != nil && Isptr[t.Etype] { 1594 t = t.Type 1595 } 1596 if Isfixedarray(t) && !hascallchan(l) { 1597 return true 1598 } 1599 1600 case OLITERAL: 1601 if n.Val.Ctype != CTNIL { 1602 return true 1603 } 1604 1605 case ONAME: 1606 l := n.Sym.Def 1607 if l != nil && l.Op == OLITERAL && n.Val.Ctype != CTNIL { 1608 return true 1609 } 1610 1611 case ONONAME: 1612 if n.Sym.Def != nil && n.Sym.Def.Op == OIOTA { 1613 return true 1614 } 1615 1616 // Only constant calls are unsafe.Alignof, Offsetof, and Sizeof. 1617 case OCALL: 1618 l := n.Left 1619 1620 for l.Op == OPAREN { 1621 l = l.Left 1622 } 1623 if l.Op != ONAME || l.Sym.Pkg != unsafepkg { 1624 break 1625 } 1626 if l.Sym.Name == "Alignof" || l.Sym.Name == "Offsetof" || l.Sym.Name == "Sizeof" { 1627 return true 1628 } 1629 } 1630 1631 //dump("nonconst", n); 1632 return false 1633 } 1634 1635 func hascallchan(n *Node) bool { 1636 if n == nil { 1637 return false 1638 } 1639 switch n.Op { 1640 case OAPPEND, 1641 OCALL, 1642 OCALLFUNC, 1643 OCALLINTER, 1644 OCALLMETH, 1645 OCAP, 1646 OCLOSE, 1647 OCOMPLEX, 1648 OCOPY, 1649 ODELETE, 1650 OIMAG, 1651 OLEN, 1652 OMAKE, 1653 ONEW, 1654 OPANIC, 1655 OPRINT, 1656 OPRINTN, 1657 OREAL, 1658 ORECOVER, 1659 ORECV: 1660 return true 1661 } 1662 1663 if hascallchan(n.Left) || hascallchan(n.Right) { 1664 return true 1665 } 1666 1667 for l := n.List; l != nil; l = l.Next { 1668 if hascallchan(l.N) { 1669 return true 1670 } 1671 } 1672 for l := n.Rlist; l != nil; l = l.Next { 1673 if hascallchan(l.N) { 1674 return true 1675 } 1676 } 1677 1678 return false 1679 }