github.com/tidwall/go@v0.0.0-20170415222209-6694a6888b7d/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/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 int8 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 %v 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 -1 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 rv.U.(*Mpcplx).Real.CmpFloat64(0) == 0 && rv.U.(*Mpcplx).Imag.CmpFloat64(0) == 0 { 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 cmplxdiv(v.U.(*Mpcplx), rv.U.(*Mpcplx)) 1048 1049 case OEQ_ | CTNIL_: 1050 goto settrue 1051 1052 case ONE_ | CTNIL_: 1053 goto setfalse 1054 1055 case OEQ_ | CTINT_: 1056 if v.U.(*Mpint).Cmp(rv.U.(*Mpint)) == 0 { 1057 goto settrue 1058 } 1059 goto setfalse 1060 1061 case ONE_ | CTINT_: 1062 if v.U.(*Mpint).Cmp(rv.U.(*Mpint)) != 0 { 1063 goto settrue 1064 } 1065 goto setfalse 1066 1067 case OLT_ | CTINT_: 1068 if v.U.(*Mpint).Cmp(rv.U.(*Mpint)) < 0 { 1069 goto settrue 1070 } 1071 goto setfalse 1072 1073 case OLE_ | CTINT_: 1074 if v.U.(*Mpint).Cmp(rv.U.(*Mpint)) <= 0 { 1075 goto settrue 1076 } 1077 goto setfalse 1078 1079 case OGE_ | CTINT_: 1080 if v.U.(*Mpint).Cmp(rv.U.(*Mpint)) >= 0 { 1081 goto settrue 1082 } 1083 goto setfalse 1084 1085 case OGT_ | CTINT_: 1086 if v.U.(*Mpint).Cmp(rv.U.(*Mpint)) > 0 { 1087 goto settrue 1088 } 1089 goto setfalse 1090 1091 case OEQ_ | CTFLT_: 1092 if v.U.(*Mpflt).Cmp(rv.U.(*Mpflt)) == 0 { 1093 goto settrue 1094 } 1095 goto setfalse 1096 1097 case ONE_ | CTFLT_: 1098 if v.U.(*Mpflt).Cmp(rv.U.(*Mpflt)) != 0 { 1099 goto settrue 1100 } 1101 goto setfalse 1102 1103 case OLT_ | CTFLT_: 1104 if v.U.(*Mpflt).Cmp(rv.U.(*Mpflt)) < 0 { 1105 goto settrue 1106 } 1107 goto setfalse 1108 1109 case OLE_ | CTFLT_: 1110 if v.U.(*Mpflt).Cmp(rv.U.(*Mpflt)) <= 0 { 1111 goto settrue 1112 } 1113 goto setfalse 1114 1115 case OGE_ | CTFLT_: 1116 if v.U.(*Mpflt).Cmp(rv.U.(*Mpflt)) >= 0 { 1117 goto settrue 1118 } 1119 goto setfalse 1120 1121 case OGT_ | CTFLT_: 1122 if v.U.(*Mpflt).Cmp(rv.U.(*Mpflt)) > 0 { 1123 goto settrue 1124 } 1125 goto setfalse 1126 1127 case OEQ_ | CTCPLX_: 1128 if v.U.(*Mpcplx).Real.Cmp(&rv.U.(*Mpcplx).Real) == 0 && v.U.(*Mpcplx).Imag.Cmp(&rv.U.(*Mpcplx).Imag) == 0 { 1129 goto settrue 1130 } 1131 goto setfalse 1132 1133 case ONE_ | CTCPLX_: 1134 if v.U.(*Mpcplx).Real.Cmp(&rv.U.(*Mpcplx).Real) != 0 || v.U.(*Mpcplx).Imag.Cmp(&rv.U.(*Mpcplx).Imag) != 0 { 1135 goto settrue 1136 } 1137 goto setfalse 1138 1139 case OEQ_ | CTSTR_: 1140 if strlit(nl) == strlit(nr) { 1141 goto settrue 1142 } 1143 goto setfalse 1144 1145 case ONE_ | CTSTR_: 1146 if strlit(nl) != strlit(nr) { 1147 goto settrue 1148 } 1149 goto setfalse 1150 1151 case OLT_ | CTSTR_: 1152 if strlit(nl) < strlit(nr) { 1153 goto settrue 1154 } 1155 goto setfalse 1156 1157 case OLE_ | CTSTR_: 1158 if strlit(nl) <= strlit(nr) { 1159 goto settrue 1160 } 1161 goto setfalse 1162 1163 case OGE_ | CTSTR_: 1164 if strlit(nl) >= strlit(nr) { 1165 goto settrue 1166 } 1167 goto setfalse 1168 1169 case OGT_ | CTSTR_: 1170 if strlit(nl) > strlit(nr) { 1171 goto settrue 1172 } 1173 goto setfalse 1174 1175 case OOROR_ | CTBOOL_: 1176 if v.U.(bool) || rv.U.(bool) { 1177 goto settrue 1178 } 1179 goto setfalse 1180 1181 case OANDAND_ | CTBOOL_: 1182 if v.U.(bool) && rv.U.(bool) { 1183 goto settrue 1184 } 1185 goto setfalse 1186 1187 case OEQ_ | CTBOOL_: 1188 if v.U.(bool) == rv.U.(bool) { 1189 goto settrue 1190 } 1191 goto setfalse 1192 1193 case ONE_ | CTBOOL_: 1194 if v.U.(bool) != rv.U.(bool) { 1195 goto settrue 1196 } 1197 goto setfalse 1198 } 1199 1200 goto ret 1201 1202 ret: 1203 norig = saveorig(n) 1204 *n = *nl 1205 1206 // restore value of n->orig. 1207 n.Orig = norig 1208 1209 n.SetVal(v) 1210 1211 // check range. 1212 lno = setlineno(n) 1213 overflow(v, n.Type) 1214 lineno = lno 1215 1216 // truncate precision for non-ideal float. 1217 if v.Ctype() == CTFLT && n.Type.Etype != TIDEAL { 1218 n.SetVal(Val{truncfltlit(v.U.(*Mpflt), n.Type)}) 1219 } 1220 return 1221 1222 settrue: 1223 nn = nodbool(true) 1224 nn.Orig = saveorig(n) 1225 if !iscmp[n.Op] { 1226 nn.Type = nl.Type 1227 } 1228 *n = *nn 1229 return 1230 1231 setfalse: 1232 nn = nodbool(false) 1233 nn.Orig = saveorig(n) 1234 if !iscmp[n.Op] { 1235 nn.Type = nl.Type 1236 } 1237 *n = *nn 1238 return 1239 1240 illegal: 1241 if !n.Diag() { 1242 yyerror("illegal constant expression: %v %v %v", nl.Type, n.Op, nr.Type) 1243 n.SetDiag(true) 1244 } 1245 } 1246 1247 func nodlit(v Val) *Node { 1248 n := nod(OLITERAL, nil, nil) 1249 n.SetVal(v) 1250 switch v.Ctype() { 1251 default: 1252 Fatalf("nodlit ctype %d", v.Ctype()) 1253 1254 case CTSTR: 1255 n.Type = types.Idealstring 1256 1257 case CTBOOL: 1258 n.Type = types.Idealbool 1259 1260 case CTINT, CTRUNE, CTFLT, CTCPLX: 1261 n.Type = types.Types[TIDEAL] 1262 1263 case CTNIL: 1264 n.Type = types.Types[TNIL] 1265 } 1266 1267 return n 1268 } 1269 1270 func nodcplxlit(r Val, i Val) *Node { 1271 r = toflt(r) 1272 i = toflt(i) 1273 1274 c := new(Mpcplx) 1275 n := nod(OLITERAL, nil, nil) 1276 n.Type = types.Types[TIDEAL] 1277 n.SetVal(Val{c}) 1278 1279 if r.Ctype() != CTFLT || i.Ctype() != CTFLT { 1280 Fatalf("nodcplxlit ctype %d/%d", r.Ctype(), i.Ctype()) 1281 } 1282 1283 c.Real.Set(r.U.(*Mpflt)) 1284 c.Imag.Set(i.U.(*Mpflt)) 1285 return n 1286 } 1287 1288 // idealkind returns a constant kind like consttype 1289 // but for an arbitrary "ideal" (untyped constant) expression. 1290 func idealkind(n *Node) Ctype { 1291 if n == nil || !n.Type.IsUntyped() { 1292 return CTxxx 1293 } 1294 1295 switch n.Op { 1296 default: 1297 return CTxxx 1298 1299 case OLITERAL: 1300 return n.Val().Ctype() 1301 1302 // numeric kinds. 1303 case OADD, 1304 OAND, 1305 OANDNOT, 1306 OCOM, 1307 ODIV, 1308 OMINUS, 1309 OMOD, 1310 OMUL, 1311 OSUB, 1312 OXOR, 1313 OOR, 1314 OPLUS: 1315 k1 := idealkind(n.Left) 1316 1317 k2 := idealkind(n.Right) 1318 if k1 > k2 { 1319 return k1 1320 } else { 1321 return k2 1322 } 1323 1324 case OREAL, OIMAG: 1325 return CTFLT 1326 1327 case OCOMPLEX: 1328 return CTCPLX 1329 1330 case OADDSTR: 1331 return CTSTR 1332 1333 case OANDAND, 1334 OEQ, 1335 OGE, 1336 OGT, 1337 OLE, 1338 OLT, 1339 ONE, 1340 ONOT, 1341 OOROR, 1342 OCMPSTR, 1343 OCMPIFACE: 1344 return CTBOOL 1345 1346 // shifts (beware!). 1347 case OLSH, ORSH: 1348 return idealkind(n.Left) 1349 } 1350 } 1351 1352 // The result of defaultlit MUST be assigned back to n, e.g. 1353 // n.Left = defaultlit(n.Left, t) 1354 func defaultlit(n *Node, t *types.Type) *Node { 1355 return defaultlitreuse(n, t, noReuse) 1356 } 1357 1358 // The result of defaultlitreuse MUST be assigned back to n, e.g. 1359 // n.Left = defaultlitreuse(n.Left, t, reuse) 1360 func defaultlitreuse(n *Node, t *types.Type, reuse canReuseNode) *Node { 1361 if n == nil || !n.Type.IsUntyped() { 1362 return n 1363 } 1364 1365 if n.Op == OLITERAL && !reuse { 1366 nn := *n 1367 n = &nn 1368 reuse = true 1369 } 1370 1371 lno := setlineno(n) 1372 ctype := idealkind(n) 1373 var t1 *types.Type 1374 switch ctype { 1375 default: 1376 if t != nil { 1377 return convlit(n, t) 1378 } 1379 1380 if n.Val().Ctype() == CTNIL { 1381 lineno = lno 1382 if !n.Diag() { 1383 yyerror("use of untyped nil") 1384 n.SetDiag(true) 1385 } 1386 1387 n.Type = nil 1388 break 1389 } 1390 1391 if n.Val().Ctype() == CTSTR { 1392 t1 := types.Types[TSTRING] 1393 n = convlit1(n, t1, false, reuse) 1394 break 1395 } 1396 1397 yyerror("defaultlit: unknown literal: %v", n) 1398 1399 case CTxxx: 1400 Fatalf("defaultlit: idealkind is CTxxx: %+v", n) 1401 1402 case CTBOOL: 1403 t1 := types.Types[TBOOL] 1404 if t != nil && t.IsBoolean() { 1405 t1 = t 1406 } 1407 n = convlit1(n, t1, false, reuse) 1408 1409 case CTINT: 1410 t1 = types.Types[TINT] 1411 goto num 1412 1413 case CTRUNE: 1414 t1 = types.Runetype 1415 goto num 1416 1417 case CTFLT: 1418 t1 = types.Types[TFLOAT64] 1419 goto num 1420 1421 case CTCPLX: 1422 t1 = types.Types[TCOMPLEX128] 1423 goto num 1424 } 1425 1426 lineno = lno 1427 return n 1428 1429 num: 1430 // Note: n.Val().Ctype() can be CTxxx (not a constant) here 1431 // in the case of an untyped non-constant value, like 1<<i. 1432 v1 := n.Val() 1433 if t != nil { 1434 if t.IsInteger() { 1435 t1 = t 1436 v1 = toint(n.Val()) 1437 } else if t.IsFloat() { 1438 t1 = t 1439 v1 = toflt(n.Val()) 1440 } else if t.IsComplex() { 1441 t1 = t 1442 v1 = tocplx(n.Val()) 1443 } 1444 if n.Val().Ctype() != CTxxx { 1445 n.SetVal(v1) 1446 } 1447 } 1448 1449 if n.Val().Ctype() != CTxxx { 1450 overflow(n.Val(), t1) 1451 } 1452 n = convlit1(n, t1, false, reuse) 1453 lineno = lno 1454 return n 1455 } 1456 1457 // defaultlit on both nodes simultaneously; 1458 // if they're both ideal going in they better 1459 // get the same type going out. 1460 // force means must assign concrete (non-ideal) type. 1461 // The results of defaultlit2 MUST be assigned back to l and r, e.g. 1462 // n.Left, n.Right = defaultlit2(n.Left, n.Right, force) 1463 func defaultlit2(l *Node, r *Node, force bool) (*Node, *Node) { 1464 if l.Type == nil || r.Type == nil { 1465 return l, r 1466 } 1467 if !l.Type.IsUntyped() { 1468 r = convlit(r, l.Type) 1469 return l, r 1470 } 1471 1472 if !r.Type.IsUntyped() { 1473 l = convlit(l, r.Type) 1474 return l, r 1475 } 1476 1477 if !force { 1478 return l, r 1479 } 1480 1481 if l.Type.IsBoolean() { 1482 l = convlit(l, types.Types[TBOOL]) 1483 r = convlit(r, types.Types[TBOOL]) 1484 } 1485 1486 lkind := idealkind(l) 1487 rkind := idealkind(r) 1488 if lkind == CTCPLX || rkind == CTCPLX { 1489 l = convlit(l, types.Types[TCOMPLEX128]) 1490 r = convlit(r, types.Types[TCOMPLEX128]) 1491 return l, r 1492 } 1493 1494 if lkind == CTFLT || rkind == CTFLT { 1495 l = convlit(l, types.Types[TFLOAT64]) 1496 r = convlit(r, types.Types[TFLOAT64]) 1497 return l, r 1498 } 1499 1500 if lkind == CTRUNE || rkind == CTRUNE { 1501 l = convlit(l, types.Runetype) 1502 r = convlit(r, types.Runetype) 1503 return l, r 1504 } 1505 1506 l = convlit(l, types.Types[TINT]) 1507 r = convlit(r, types.Types[TINT]) 1508 1509 return l, r 1510 } 1511 1512 // strlit returns the value of a literal string Node as a string. 1513 func strlit(n *Node) string { 1514 return n.Val().U.(string) 1515 } 1516 1517 func smallintconst(n *Node) bool { 1518 if n.Op == OLITERAL && Isconst(n, CTINT) && n.Type != nil { 1519 switch simtype[n.Type.Etype] { 1520 case TINT8, 1521 TUINT8, 1522 TINT16, 1523 TUINT16, 1524 TINT32, 1525 TUINT32, 1526 TBOOL, 1527 TPTR32: 1528 return true 1529 1530 case TIDEAL, TINT64, TUINT64, TPTR64: 1531 v, ok := n.Val().U.(*Mpint) 1532 if ok && v.Cmp(minintval[TINT32]) > 0 && v.Cmp(maxintval[TINT32]) < 0 { 1533 return true 1534 } 1535 } 1536 } 1537 1538 return false 1539 } 1540 1541 // nonnegintconst checks if Node n contains a constant expression 1542 // representable as a non-negative small integer, and returns its 1543 // (integer) value if that's the case. Otherwise, it returns -1. 1544 func nonnegintconst(n *Node) int64 { 1545 if n.Op != OLITERAL { 1546 return -1 1547 } 1548 1549 // toint will leave n.Val unchanged if it's not castable to an 1550 // Mpint, so we still have to guard the conversion. 1551 v := toint(n.Val()) 1552 vi, ok := v.U.(*Mpint) 1553 if !ok || vi.CmpInt64(0) < 0 || vi.Cmp(maxintval[TINT32]) > 0 { 1554 return -1 1555 } 1556 1557 return vi.Int64() 1558 } 1559 1560 // complex multiply v *= rv 1561 // (a, b) * (c, d) = (a*c - b*d, b*c + a*d) 1562 func cmplxmpy(v *Mpcplx, rv *Mpcplx) { 1563 var ac Mpflt 1564 var bd Mpflt 1565 var bc Mpflt 1566 var ad Mpflt 1567 1568 ac.Set(&v.Real) 1569 ac.Mul(&rv.Real) // ac 1570 1571 bd.Set(&v.Imag) 1572 1573 bd.Mul(&rv.Imag) // bd 1574 1575 bc.Set(&v.Imag) 1576 1577 bc.Mul(&rv.Real) // bc 1578 1579 ad.Set(&v.Real) 1580 1581 ad.Mul(&rv.Imag) // ad 1582 1583 v.Real.Set(&ac) 1584 1585 v.Real.Sub(&bd) // ac-bd 1586 1587 v.Imag.Set(&bc) 1588 1589 v.Imag.Add(&ad) // bc+ad 1590 } 1591 1592 // complex divide v /= rv 1593 // (a, b) / (c, d) = ((a*c + b*d), (b*c - a*d))/(c*c + d*d) 1594 func cmplxdiv(v *Mpcplx, rv *Mpcplx) { 1595 var ac Mpflt 1596 var bd Mpflt 1597 var bc Mpflt 1598 var ad Mpflt 1599 var cc_plus_dd Mpflt 1600 1601 cc_plus_dd.Set(&rv.Real) 1602 cc_plus_dd.Mul(&rv.Real) // cc 1603 1604 ac.Set(&rv.Imag) 1605 1606 ac.Mul(&rv.Imag) // dd 1607 1608 cc_plus_dd.Add(&ac) // cc+dd 1609 1610 ac.Set(&v.Real) 1611 1612 ac.Mul(&rv.Real) // ac 1613 1614 bd.Set(&v.Imag) 1615 1616 bd.Mul(&rv.Imag) // bd 1617 1618 bc.Set(&v.Imag) 1619 1620 bc.Mul(&rv.Real) // bc 1621 1622 ad.Set(&v.Real) 1623 1624 ad.Mul(&rv.Imag) // ad 1625 1626 v.Real.Set(&ac) 1627 1628 v.Real.Add(&bd) // ac+bd 1629 v.Real.Quo(&cc_plus_dd) // (ac+bd)/(cc+dd) 1630 1631 v.Imag.Set(&bc) 1632 1633 v.Imag.Sub(&ad) // bc-ad 1634 v.Imag.Quo(&cc_plus_dd) // (bc+ad)/(cc+dd) 1635 } 1636 1637 // Is n a Go language constant (as opposed to a compile-time constant)? 1638 // Expressions derived from nil, like string([]byte(nil)), while they 1639 // may be known at compile time, are not Go language constants. 1640 // Only called for expressions known to evaluated to compile-time 1641 // constants. 1642 func isgoconst(n *Node) bool { 1643 if n.Orig != nil { 1644 n = n.Orig 1645 } 1646 1647 switch n.Op { 1648 case OADD, 1649 OADDSTR, 1650 OAND, 1651 OANDAND, 1652 OANDNOT, 1653 OCOM, 1654 ODIV, 1655 OEQ, 1656 OGE, 1657 OGT, 1658 OLE, 1659 OLSH, 1660 OLT, 1661 OMINUS, 1662 OMOD, 1663 OMUL, 1664 ONE, 1665 ONOT, 1666 OOR, 1667 OOROR, 1668 OPLUS, 1669 ORSH, 1670 OSUB, 1671 OXOR, 1672 OIOTA, 1673 OCOMPLEX, 1674 OREAL, 1675 OIMAG: 1676 if isgoconst(n.Left) && (n.Right == nil || isgoconst(n.Right)) { 1677 return true 1678 } 1679 1680 case OCONV: 1681 if okforconst[n.Type.Etype] && isgoconst(n.Left) { 1682 return true 1683 } 1684 1685 case OLEN, OCAP: 1686 l := n.Left 1687 if isgoconst(l) { 1688 return true 1689 } 1690 1691 // Special case: len/cap is constant when applied to array or 1692 // pointer to array when the expression does not contain 1693 // function calls or channel receive operations. 1694 t := l.Type 1695 1696 if t != nil && t.IsPtr() { 1697 t = t.Elem() 1698 } 1699 if t != nil && t.IsArray() && !hascallchan(l) { 1700 return true 1701 } 1702 1703 case OLITERAL: 1704 if n.Val().Ctype() != CTNIL { 1705 return true 1706 } 1707 1708 case ONAME: 1709 l := asNode(n.Sym.Def) 1710 if l != nil && l.Op == OLITERAL && n.Val().Ctype() != CTNIL { 1711 return true 1712 } 1713 1714 case ONONAME: 1715 if asNode(n.Sym.Def) != nil && asNode(n.Sym.Def).Op == OIOTA { 1716 return true 1717 } 1718 1719 case OALIGNOF, OOFFSETOF, OSIZEOF: 1720 return true 1721 } 1722 1723 //dump("nonconst", n); 1724 return false 1725 } 1726 1727 func hascallchan(n *Node) bool { 1728 if n == nil { 1729 return false 1730 } 1731 switch n.Op { 1732 case OAPPEND, 1733 OCALL, 1734 OCALLFUNC, 1735 OCALLINTER, 1736 OCALLMETH, 1737 OCAP, 1738 OCLOSE, 1739 OCOMPLEX, 1740 OCOPY, 1741 ODELETE, 1742 OIMAG, 1743 OLEN, 1744 OMAKE, 1745 ONEW, 1746 OPANIC, 1747 OPRINT, 1748 OPRINTN, 1749 OREAL, 1750 ORECOVER, 1751 ORECV: 1752 return true 1753 } 1754 1755 if hascallchan(n.Left) || hascallchan(n.Right) { 1756 return true 1757 } 1758 for _, n1 := range n.List.Slice() { 1759 if hascallchan(n1) { 1760 return true 1761 } 1762 } 1763 for _, n2 := range n.Rlist.Slice() { 1764 if hascallchan(n2) { 1765 return true 1766 } 1767 } 1768 1769 return false 1770 }