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