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