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