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