github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/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 "math/big" 10 "strings" 11 ) 12 13 // Ctype describes the constant kind of an "ideal" (untyped) constant. 14 type Ctype uint8 15 16 const ( 17 CTxxx Ctype = iota 18 19 CTINT 20 CTRUNE 21 CTFLT 22 CTCPLX 23 CTSTR 24 CTBOOL 25 CTNIL 26 ) 27 28 type Val struct { 29 // U contains one of: 30 // bool bool when n.ValCtype() == CTBOOL 31 // *Mpint int when n.ValCtype() == CTINT, rune when n.ValCtype() == CTRUNE 32 // *Mpflt float when n.ValCtype() == CTFLT 33 // *Mpcplx pair of floats when n.ValCtype() == CTCPLX 34 // string string when n.ValCtype() == CTSTR 35 // *Nilval when n.ValCtype() == CTNIL 36 U interface{} 37 } 38 39 func (v Val) Ctype() Ctype { 40 switch x := v.U.(type) { 41 default: 42 Fatalf("unexpected Ctype for %T", v.U) 43 panic("unreachable") 44 case nil: 45 return 0 46 case *NilVal: 47 return CTNIL 48 case bool: 49 return CTBOOL 50 case *Mpint: 51 if x.Rune { 52 return CTRUNE 53 } 54 return CTINT 55 case *Mpflt: 56 return CTFLT 57 case *Mpcplx: 58 return CTCPLX 59 case string: 60 return CTSTR 61 } 62 } 63 64 func eqval(a, b Val) bool { 65 if a.Ctype() != b.Ctype() { 66 return false 67 } 68 switch x := a.U.(type) { 69 default: 70 Fatalf("unexpected Ctype for %T", a.U) 71 panic("unreachable") 72 case *NilVal: 73 return true 74 case bool: 75 y := b.U.(bool) 76 return x == y 77 case *Mpint: 78 y := b.U.(*Mpint) 79 return x.Cmp(y) == 0 80 case *Mpflt: 81 y := b.U.(*Mpflt) 82 return x.Cmp(y) == 0 83 case *Mpcplx: 84 y := b.U.(*Mpcplx) 85 return x.Real.Cmp(&y.Real) == 0 && x.Imag.Cmp(&y.Imag) == 0 86 case string: 87 y := b.U.(string) 88 return x == y 89 } 90 } 91 92 // Interface returns the constant value stored in v as an interface{}. 93 // It returns int64s for ints and runes, float64s for floats, 94 // complex128s for complex values, and nil for constant nils. 95 func (v Val) Interface() interface{} { 96 switch x := v.U.(type) { 97 default: 98 Fatalf("unexpected Interface for %T", v.U) 99 panic("unreachable") 100 case *NilVal: 101 return nil 102 case bool, string: 103 return x 104 case *Mpint: 105 return x.Int64() 106 case *Mpflt: 107 return x.Float64() 108 case *Mpcplx: 109 return complex(x.Real.Float64(), x.Imag.Float64()) 110 } 111 } 112 113 type NilVal struct{} 114 115 // Int64 returns n as an int64. 116 // n must be an integer or rune constant. 117 func (n *Node) Int64() int64 { 118 if !Isconst(n, CTINT) { 119 Fatalf("Int64(%v)", n) 120 } 121 return n.Val().U.(*Mpint).Int64() 122 } 123 124 // CanInt64 reports whether it is safe to call Int64() on n. 125 func (n *Node) CanInt64() bool { 126 if !Isconst(n, CTINT) { 127 return false 128 } 129 130 // if the value inside n cannot be represented as an int64, the 131 // return value of Int64 is undefined 132 return n.Val().U.(*Mpint).CmpInt64(n.Int64()) == 0 133 } 134 135 // Bool returns n as a bool. 136 // n must be a boolean constant. 137 func (n *Node) Bool() bool { 138 if !Isconst(n, CTBOOL) { 139 Fatalf("Bool(%v)", n) 140 } 141 return n.Val().U.(bool) 142 } 143 144 // truncate float literal fv to 32-bit or 64-bit precision 145 // according to type; return truncated value. 146 func truncfltlit(oldv *Mpflt, t *types.Type) *Mpflt { 147 if t == nil { 148 return oldv 149 } 150 151 if overflow(Val{oldv}, t) { 152 // If there was overflow, simply continuing would set the 153 // value to Inf which in turn would lead to spurious follow-on 154 // errors. Avoid this by returning the existing value. 155 return oldv 156 } 157 158 fv := newMpflt() 159 160 // convert large precision literal floating 161 // into limited precision (float64 or float32) 162 switch t.Etype { 163 case types.TFLOAT32: 164 fv.SetFloat64(oldv.Float32()) 165 case types.TFLOAT64: 166 fv.SetFloat64(oldv.Float64()) 167 default: 168 Fatalf("truncfltlit: unexpected Etype %v", t.Etype) 169 } 170 171 return fv 172 } 173 174 // truncate Real and Imag parts of Mpcplx to 32-bit or 64-bit 175 // precision, according to type; return truncated value. In case of 176 // overflow, calls yyerror but does not truncate the input value. 177 func trunccmplxlit(oldv *Mpcplx, t *types.Type) *Mpcplx { 178 if t == nil { 179 return oldv 180 } 181 182 if overflow(Val{oldv}, t) { 183 // If there was overflow, simply continuing would set the 184 // value to Inf which in turn would lead to spurious follow-on 185 // errors. Avoid this by returning the existing value. 186 return oldv 187 } 188 189 cv := newMpcmplx() 190 191 switch t.Etype { 192 case types.TCOMPLEX64: 193 cv.Real.SetFloat64(oldv.Real.Float32()) 194 cv.Imag.SetFloat64(oldv.Imag.Float32()) 195 case types.TCOMPLEX128: 196 cv.Real.SetFloat64(oldv.Real.Float64()) 197 cv.Imag.SetFloat64(oldv.Imag.Float64()) 198 default: 199 Fatalf("trunccplxlit: unexpected Etype %v", t.Etype) 200 } 201 202 return cv 203 } 204 205 // canReuseNode indicates whether it is known to be safe 206 // to reuse a Node. 207 type canReuseNode bool 208 209 const ( 210 noReuse canReuseNode = false // not necessarily safe to reuse 211 reuseOK canReuseNode = true // safe to reuse 212 ) 213 214 // convert n, if literal, to type t. 215 // implicit conversion. 216 // The result of convlit MUST be assigned back to n, e.g. 217 // n.Left = convlit(n.Left, t) 218 func convlit(n *Node, t *types.Type) *Node { 219 return convlit1(n, t, false, noReuse) 220 } 221 222 // convlit1 converts n, if literal, to type t. 223 // It returns a new node if necessary. 224 // The result of convlit1 MUST be assigned back to n, e.g. 225 // n.Left = convlit1(n.Left, t, explicit, reuse) 226 func convlit1(n *Node, t *types.Type, explicit bool, reuse canReuseNode) *Node { 227 if n == nil || t == nil || n.Type == nil || t.IsUntyped() || n.Type == t { 228 return n 229 } 230 if !explicit && !n.Type.IsUntyped() { 231 return n 232 } 233 234 if n.Op == OLITERAL && !reuse { 235 // Can't always set n.Type directly on OLITERAL nodes. 236 // See discussion on CL 20813. 237 n = n.rawcopy() 238 reuse = true 239 } 240 241 switch n.Op { 242 default: 243 if n.Type == types.Idealbool { 244 if !t.IsBoolean() { 245 t = types.Types[TBOOL] 246 } 247 switch n.Op { 248 case ONOT: 249 n.Left = convlit(n.Left, t) 250 case OANDAND, OOROR: 251 n.Left = convlit(n.Left, t) 252 n.Right = convlit(n.Right, t) 253 } 254 n.Type = t 255 } 256 257 if n.Type.IsUntyped() { 258 if t.IsInterface() { 259 n.Left, n.Right = defaultlit2(n.Left, n.Right, true) 260 n.Type = n.Left.Type // same as n.Right.Type per defaultlit2 261 } else { 262 n.Left = convlit(n.Left, t) 263 n.Right = convlit(n.Right, t) 264 n.Type = t 265 } 266 } 267 268 return n 269 270 // target is invalid type for a constant? leave alone. 271 case OLITERAL: 272 if !okforconst[t.Etype] && n.Type.Etype != TNIL { 273 return defaultlitreuse(n, nil, reuse) 274 } 275 276 case OLSH, ORSH: 277 n.Left = convlit1(n.Left, t, explicit && n.Left.Type.IsUntyped(), noReuse) 278 t = n.Left.Type 279 if t != nil && t.Etype == TIDEAL && n.Val().Ctype() != CTINT { 280 n.SetVal(toint(n.Val())) 281 } 282 if t != nil && !t.IsInteger() { 283 yyerror("invalid operation: %v (shift of type %v)", n, t) 284 t = nil 285 } 286 287 n.Type = t 288 return n 289 290 case OCOMPLEX: 291 if n.Type.Etype == TIDEAL { 292 switch t.Etype { 293 default: 294 // If trying to convert to non-complex type, 295 // leave as complex128 and let typechecker complain. 296 t = types.Types[TCOMPLEX128] 297 fallthrough 298 case types.TCOMPLEX128: 299 n.Type = t 300 n.Left = convlit(n.Left, types.Types[TFLOAT64]) 301 n.Right = convlit(n.Right, types.Types[TFLOAT64]) 302 303 case TCOMPLEX64: 304 n.Type = t 305 n.Left = convlit(n.Left, types.Types[TFLOAT32]) 306 n.Right = convlit(n.Right, types.Types[TFLOAT32]) 307 } 308 } 309 310 return n 311 } 312 313 // avoid repeated calculations, errors 314 if types.Identical(n.Type, t) { 315 return n 316 } 317 318 ct := consttype(n) 319 var et types.EType 320 if ct == 0 { 321 goto bad 322 } 323 324 et = t.Etype 325 if et == TINTER { 326 if ct == CTNIL && n.Type == types.Types[TNIL] { 327 n.Type = t 328 return n 329 } 330 return defaultlitreuse(n, nil, reuse) 331 } 332 333 switch ct { 334 default: 335 goto bad 336 337 case CTNIL: 338 switch et { 339 default: 340 n.Type = nil 341 goto bad 342 343 // let normal conversion code handle it 344 case TSTRING: 345 return n 346 347 case TARRAY: 348 goto bad 349 350 case TPTR, TUNSAFEPTR: 351 n.SetVal(Val{new(Mpint)}) 352 353 case TCHAN, TFUNC, TINTER, TMAP, TSLICE: 354 break 355 } 356 357 case CTSTR, CTBOOL: 358 if et != n.Type.Etype { 359 goto bad 360 } 361 362 case CTINT, CTRUNE, CTFLT, CTCPLX: 363 if n.Type.Etype == TUNSAFEPTR && t.Etype != TUINTPTR { 364 goto bad 365 } 366 ct := n.Val().Ctype() 367 if isInt[et] { 368 switch ct { 369 default: 370 goto bad 371 372 case CTCPLX, CTFLT, CTRUNE: 373 n.SetVal(toint(n.Val())) 374 fallthrough 375 376 case CTINT: 377 overflow(n.Val(), t) 378 } 379 } else if isFloat[et] { 380 switch ct { 381 default: 382 goto bad 383 384 case CTCPLX, CTINT, CTRUNE: 385 n.SetVal(toflt(n.Val())) 386 fallthrough 387 388 case CTFLT: 389 n.SetVal(Val{truncfltlit(n.Val().U.(*Mpflt), t)}) 390 } 391 } else if isComplex[et] { 392 switch ct { 393 default: 394 goto bad 395 396 case CTFLT, CTINT, CTRUNE: 397 n.SetVal(tocplx(n.Val())) 398 fallthrough 399 400 case CTCPLX: 401 n.SetVal(Val{trunccmplxlit(n.Val().U.(*Mpcplx), t)}) 402 } 403 } else if et == types.TSTRING && (ct == CTINT || ct == CTRUNE) && explicit { 404 n.SetVal(tostr(n.Val())) 405 } else { 406 goto bad 407 } 408 } 409 410 n.Type = t 411 return n 412 413 bad: 414 if !n.Diag() { 415 if !t.Broke() { 416 yyerror("cannot convert %L to type %v", n, t) 417 } 418 n.SetDiag(true) 419 } 420 421 if n.Type.IsUntyped() { 422 n = defaultlitreuse(n, nil, reuse) 423 } 424 return n 425 } 426 427 func tocplx(v Val) Val { 428 switch u := v.U.(type) { 429 case *Mpint: 430 c := new(Mpcplx) 431 c.Real.SetInt(u) 432 c.Imag.SetFloat64(0.0) 433 v.U = c 434 435 case *Mpflt: 436 c := new(Mpcplx) 437 c.Real.Set(u) 438 c.Imag.SetFloat64(0.0) 439 v.U = c 440 } 441 442 return v 443 } 444 445 func toflt(v Val) Val { 446 switch u := v.U.(type) { 447 case *Mpint: 448 f := newMpflt() 449 f.SetInt(u) 450 v.U = f 451 452 case *Mpcplx: 453 f := newMpflt() 454 f.Set(&u.Real) 455 if u.Imag.CmpFloat64(0) != 0 { 456 yyerror("constant %v truncated to real", u.GoString()) 457 } 458 v.U = f 459 } 460 461 return v 462 } 463 464 func toint(v Val) Val { 465 switch u := v.U.(type) { 466 case *Mpint: 467 if u.Rune { 468 i := new(Mpint) 469 i.Set(u) 470 v.U = i 471 } 472 473 case *Mpflt: 474 i := new(Mpint) 475 if !i.SetFloat(u) { 476 if i.checkOverflow(0) { 477 yyerror("integer too large") 478 } else { 479 // The value of u cannot be represented as an integer; 480 // so we need to print an error message. 481 // Unfortunately some float values cannot be 482 // reasonably formatted for inclusion in an error 483 // message (example: 1 + 1e-100), so first we try to 484 // format the float; if the truncation resulted in 485 // something that looks like an integer we omit the 486 // value from the error message. 487 // (See issue #11371). 488 var t big.Float 489 t.Parse(u.GoString(), 10) 490 if t.IsInt() { 491 yyerror("constant truncated to integer") 492 } else { 493 yyerror("constant %v truncated to integer", u.GoString()) 494 } 495 } 496 } 497 v.U = i 498 499 case *Mpcplx: 500 i := new(Mpint) 501 if !i.SetFloat(&u.Real) || u.Imag.CmpFloat64(0) != 0 { 502 yyerror("constant %v truncated to integer", u.GoString()) 503 } 504 505 v.U = i 506 } 507 508 return v 509 } 510 511 func doesoverflow(v Val, t *types.Type) bool { 512 switch u := v.U.(type) { 513 case *Mpint: 514 if !t.IsInteger() { 515 Fatalf("overflow: %v integer constant", t) 516 } 517 return u.Cmp(minintval[t.Etype]) < 0 || u.Cmp(maxintval[t.Etype]) > 0 518 519 case *Mpflt: 520 if !t.IsFloat() { 521 Fatalf("overflow: %v floating-point constant", t) 522 } 523 return u.Cmp(minfltval[t.Etype]) <= 0 || u.Cmp(maxfltval[t.Etype]) >= 0 524 525 case *Mpcplx: 526 if !t.IsComplex() { 527 Fatalf("overflow: %v complex constant", t) 528 } 529 return u.Real.Cmp(minfltval[t.Etype]) <= 0 || u.Real.Cmp(maxfltval[t.Etype]) >= 0 || 530 u.Imag.Cmp(minfltval[t.Etype]) <= 0 || u.Imag.Cmp(maxfltval[t.Etype]) >= 0 531 } 532 533 return false 534 } 535 536 func overflow(v Val, t *types.Type) bool { 537 // v has already been converted 538 // to appropriate form for t. 539 if t == nil || t.Etype == TIDEAL { 540 return false 541 } 542 543 // Only uintptrs may be converted to pointers, which cannot overflow. 544 if t.IsPtr() || t.IsUnsafePtr() { 545 return false 546 } 547 548 if doesoverflow(v, t) { 549 yyerror("constant %v overflows %v", v, t) 550 return true 551 } 552 553 return false 554 555 } 556 557 func tostr(v Val) Val { 558 switch u := v.U.(type) { 559 case *Mpint: 560 var i int64 = 0xFFFD 561 if u.Cmp(minintval[TUINT32]) >= 0 && u.Cmp(maxintval[TUINT32]) <= 0 { 562 i = u.Int64() 563 } 564 v.U = string(i) 565 } 566 567 return v 568 } 569 570 func consttype(n *Node) Ctype { 571 if n == nil || n.Op != OLITERAL { 572 return 0 573 } 574 return n.Val().Ctype() 575 } 576 577 func Isconst(n *Node, ct Ctype) bool { 578 t := consttype(n) 579 580 // If the caller is asking for CTINT, allow CTRUNE too. 581 // Makes life easier for back ends. 582 return t == ct || (ct == CTINT && t == CTRUNE) 583 } 584 585 // evconst rewrites constant expressions into OLITERAL nodes. 586 func evconst(n *Node) { 587 nl, nr := n.Left, n.Right 588 589 // Pick off just the opcodes that can be constant evaluated. 590 switch op := n.Op; op { 591 case OPLUS, OMINUS, OCOM, ONOT: 592 if nl.Op == OLITERAL { 593 setconst(n, unaryOp(op, nl.Val(), n.Type)) 594 } 595 596 case OADD, OSUB, OMUL, ODIV, OMOD, OOR, OXOR, OAND, OANDNOT, OOROR, OANDAND: 597 if nl.Op == OLITERAL && nr.Op == OLITERAL { 598 setconst(n, binaryOp(nl.Val(), op, nr.Val())) 599 } 600 601 case OEQ, ONE, OLT, OLE, OGT, OGE: 602 if nl.Op == OLITERAL && nr.Op == OLITERAL { 603 if nl.Type.IsInterface() != nr.Type.IsInterface() { 604 // Mixed interface/non-interface 605 // constant comparison means comparing 606 // nil interface with some typed 607 // constant, which is always unequal. 608 // E.g., interface{}(nil) == (*int)(nil). 609 setboolconst(n, op == ONE) 610 } else { 611 setboolconst(n, compareOp(nl.Val(), op, nr.Val())) 612 } 613 } 614 615 case OLSH, ORSH: 616 if nl.Op == OLITERAL && nr.Op == OLITERAL { 617 setconst(n, shiftOp(nl.Val(), op, nr.Val())) 618 } 619 620 case OCONV: 621 if n.Type != nil && okforconst[n.Type.Etype] && nl.Op == OLITERAL { 622 // TODO(mdempsky): There should be a convval function. 623 setconst(n, convlit1(nl, n.Type, true, false).Val()) 624 } 625 626 case OARRAYBYTESTR: 627 // string([]byte(nil)) or string([]rune(nil)) 628 if nl.Op == OLITERAL && nl.Val().Ctype() == CTNIL { 629 setconst(n, Val{U: ""}) 630 } 631 632 case OADDSTR: 633 // Merge adjacent constants in the argument list. 634 s := n.List.Slice() 635 for i1 := 0; i1 < len(s); i1++ { 636 if Isconst(s[i1], CTSTR) && i1+1 < len(s) && Isconst(s[i1+1], CTSTR) { 637 // merge from i1 up to but not including i2 638 var strs []string 639 i2 := i1 640 for i2 < len(s) && Isconst(s[i2], CTSTR) { 641 strs = append(strs, s[i2].Val().U.(string)) 642 i2++ 643 } 644 645 nl := *s[i1] 646 nl.Orig = &nl 647 nl.SetVal(Val{strings.Join(strs, "")}) 648 s[i1] = &nl 649 s = append(s[:i1+1], s[i2:]...) 650 } 651 } 652 653 if len(s) == 1 && Isconst(s[0], CTSTR) { 654 n.Op = OLITERAL 655 n.SetVal(s[0].Val()) 656 } else { 657 n.List.Set(s) 658 } 659 } 660 } 661 662 func match(x, y Val) (Val, Val) { 663 switch { 664 case x.Ctype() == CTCPLX || y.Ctype() == CTCPLX: 665 return tocplx(x), tocplx(y) 666 case x.Ctype() == CTFLT || y.Ctype() == CTFLT: 667 return toflt(x), toflt(y) 668 } 669 670 // Mixed int/rune are fine. 671 return x, y 672 } 673 674 func compareOp(x Val, op Op, y Val) bool { 675 x, y = match(x, y) 676 677 switch x.Ctype() { 678 case CTNIL: 679 _, _ = x.U.(*NilVal), y.U.(*NilVal) // assert dynamic types match 680 switch op { 681 case OEQ: 682 return true 683 case ONE: 684 return false 685 } 686 687 case CTBOOL: 688 x, y := x.U.(bool), y.U.(bool) 689 switch op { 690 case OEQ: 691 return x == y 692 case ONE: 693 return x != y 694 } 695 696 case CTINT, CTRUNE: 697 x, y := x.U.(*Mpint), y.U.(*Mpint) 698 return cmpZero(x.Cmp(y), op) 699 700 case CTFLT: 701 x, y := x.U.(*Mpflt), y.U.(*Mpflt) 702 return cmpZero(x.Cmp(y), op) 703 704 case CTCPLX: 705 x, y := x.U.(*Mpcplx), y.U.(*Mpcplx) 706 eq := x.Real.Cmp(&y.Real) == 0 && x.Imag.Cmp(&y.Imag) == 0 707 switch op { 708 case OEQ: 709 return eq 710 case ONE: 711 return !eq 712 } 713 714 case CTSTR: 715 x, y := x.U.(string), y.U.(string) 716 switch op { 717 case OEQ: 718 return x == y 719 case ONE: 720 return x != y 721 case OLT: 722 return x < y 723 case OLE: 724 return x <= y 725 case OGT: 726 return x > y 727 case OGE: 728 return x >= y 729 } 730 } 731 732 Fatalf("compareOp: bad comparison: %v %v %v", x, op, y) 733 panic("unreachable") 734 } 735 736 func cmpZero(x int, op Op) bool { 737 switch op { 738 case OEQ: 739 return x == 0 740 case ONE: 741 return x != 0 742 case OLT: 743 return x < 0 744 case OLE: 745 return x <= 0 746 case OGT: 747 return x > 0 748 case OGE: 749 return x >= 0 750 } 751 752 Fatalf("cmpZero: want comparison operator, got %v", op) 753 panic("unreachable") 754 } 755 756 func binaryOp(x Val, op Op, y Val) Val { 757 x, y = match(x, y) 758 759 Outer: 760 switch x.Ctype() { 761 case CTBOOL: 762 x, y := x.U.(bool), y.U.(bool) 763 switch op { 764 case OANDAND: 765 return Val{U: x && y} 766 case OOROR: 767 return Val{U: x || y} 768 } 769 770 case CTINT, CTRUNE: 771 x, y := x.U.(*Mpint), y.U.(*Mpint) 772 773 u := new(Mpint) 774 u.Rune = x.Rune || y.Rune 775 u.Set(x) 776 switch op { 777 case OADD: 778 u.Add(y) 779 case OSUB: 780 u.Sub(y) 781 case OMUL: 782 u.Mul(y) 783 case ODIV: 784 if y.CmpInt64(0) == 0 { 785 yyerror("division by zero") 786 u.SetOverflow() 787 break 788 } 789 u.Quo(y) 790 case OMOD: 791 if y.CmpInt64(0) == 0 { 792 yyerror("division by zero") 793 u.SetOverflow() 794 break 795 } 796 u.Rem(y) 797 case OOR: 798 u.Or(y) 799 case OAND: 800 u.And(y) 801 case OANDNOT: 802 u.AndNot(y) 803 case OXOR: 804 u.Xor(y) 805 default: 806 break Outer 807 } 808 return Val{U: u} 809 810 case CTFLT: 811 x, y := x.U.(*Mpflt), y.U.(*Mpflt) 812 813 u := newMpflt() 814 u.Set(x) 815 switch op { 816 case OADD: 817 u.Add(y) 818 case OSUB: 819 u.Sub(y) 820 case OMUL: 821 u.Mul(y) 822 case ODIV: 823 if y.CmpFloat64(0) == 0 { 824 yyerror("division by zero") 825 u.SetFloat64(1) 826 break 827 } 828 u.Quo(y) 829 case OMOD: 830 // TODO(mdempsky): Move to typecheck. 831 yyerror("illegal constant expression: floating-point %% operation") 832 default: 833 break Outer 834 } 835 return Val{U: u} 836 837 case CTCPLX: 838 x, y := x.U.(*Mpcplx), y.U.(*Mpcplx) 839 840 u := new(Mpcplx) 841 u.Real.Set(&x.Real) 842 u.Imag.Set(&x.Imag) 843 switch op { 844 case OADD: 845 u.Real.Add(&y.Real) 846 u.Imag.Add(&y.Imag) 847 case OSUB: 848 u.Real.Sub(&y.Real) 849 u.Imag.Sub(&y.Imag) 850 case OMUL: 851 u.Mul(y) 852 case ODIV: 853 if !u.Div(y) { 854 yyerror("complex division by zero") 855 u.Real.SetFloat64(1) 856 u.Imag.SetFloat64(0) 857 } 858 default: 859 break Outer 860 } 861 return Val{U: u} 862 } 863 864 Fatalf("binaryOp: bad operation: %v %v %v", x, op, y) 865 panic("unreachable") 866 } 867 868 func unaryOp(op Op, x Val, t *types.Type) Val { 869 switch op { 870 case OPLUS: 871 switch x.Ctype() { 872 case CTINT, CTRUNE, CTFLT, CTCPLX: 873 return x 874 } 875 876 case OMINUS: 877 switch x.Ctype() { 878 case CTINT, CTRUNE: 879 x := x.U.(*Mpint) 880 u := new(Mpint) 881 u.Rune = x.Rune 882 u.Set(x) 883 u.Neg() 884 return Val{U: u} 885 886 case CTFLT: 887 x := x.U.(*Mpflt) 888 u := newMpflt() 889 u.Set(x) 890 u.Neg() 891 return Val{U: u} 892 893 case CTCPLX: 894 x := x.U.(*Mpcplx) 895 u := new(Mpcplx) 896 u.Real.Set(&x.Real) 897 u.Imag.Set(&x.Imag) 898 u.Real.Neg() 899 u.Imag.Neg() 900 return Val{U: u} 901 } 902 903 case OCOM: 904 x := x.U.(*Mpint) 905 906 u := new(Mpint) 907 u.Rune = x.Rune 908 if t.IsSigned() || t.IsUntyped() { 909 // Signed values change sign. 910 u.SetInt64(-1) 911 } else { 912 // Unsigned values invert their bits. 913 u.Set(maxintval[t.Etype]) 914 } 915 u.Xor(x) 916 return Val{U: u} 917 918 case ONOT: 919 return Val{U: !x.U.(bool)} 920 } 921 922 Fatalf("unaryOp: bad operation: %v %v", op, x) 923 panic("unreachable") 924 } 925 926 func shiftOp(x Val, op Op, y Val) Val { 927 if x.Ctype() != CTRUNE { 928 x = toint(x) 929 } 930 y = toint(y) 931 932 u := new(Mpint) 933 u.Set(x.U.(*Mpint)) 934 u.Rune = x.U.(*Mpint).Rune 935 switch op { 936 case OLSH: 937 u.Lsh(y.U.(*Mpint)) 938 case ORSH: 939 u.Rsh(y.U.(*Mpint)) 940 default: 941 Fatalf("shiftOp: bad operator: %v", op) 942 panic("unreachable") 943 } 944 return Val{U: u} 945 } 946 947 // setconst rewrites n as an OLITERAL with value v. 948 func setconst(n *Node, v Val) { 949 // Ensure n.Orig still points to a semantically-equivalent 950 // expression after we rewrite n into a constant. 951 if n.Orig == n { 952 n.Orig = n.sepcopy() 953 } 954 955 *n = Node{ 956 Op: OLITERAL, 957 Pos: n.Pos, 958 Orig: n.Orig, 959 Type: n.Type, 960 Xoffset: BADWIDTH, 961 } 962 n.SetVal(v) 963 964 // Check range. 965 lno := setlineno(n) 966 overflow(v, n.Type) 967 lineno = lno 968 969 // Truncate precision for non-ideal float. 970 if v.Ctype() == CTFLT && n.Type.Etype != TIDEAL { 971 n.SetVal(Val{truncfltlit(v.U.(*Mpflt), n.Type)}) 972 } 973 } 974 975 func setboolconst(n *Node, v bool) { 976 setconst(n, Val{U: v}) 977 } 978 979 func setintconst(n *Node, v int64) { 980 u := new(Mpint) 981 u.SetInt64(v) 982 setconst(n, Val{u}) 983 } 984 985 // nodlit returns a new untyped constant with value v. 986 func nodlit(v Val) *Node { 987 n := nod(OLITERAL, nil, nil) 988 n.SetVal(v) 989 switch v.Ctype() { 990 default: 991 Fatalf("nodlit ctype %d", v.Ctype()) 992 993 case CTSTR: 994 n.Type = types.Idealstring 995 996 case CTBOOL: 997 n.Type = types.Idealbool 998 999 case CTINT, CTRUNE, CTFLT, CTCPLX: 1000 n.Type = types.Types[TIDEAL] 1001 1002 case CTNIL: 1003 n.Type = types.Types[TNIL] 1004 } 1005 1006 return n 1007 } 1008 1009 // idealkind returns a constant kind like consttype 1010 // but for an arbitrary "ideal" (untyped constant) expression. 1011 func idealkind(n *Node) Ctype { 1012 if n == nil || !n.Type.IsUntyped() { 1013 return CTxxx 1014 } 1015 1016 switch n.Op { 1017 default: 1018 return CTxxx 1019 1020 case OLITERAL: 1021 return n.Val().Ctype() 1022 1023 // numeric kinds. 1024 case OADD, 1025 OAND, 1026 OANDNOT, 1027 OCOM, 1028 ODIV, 1029 OMINUS, 1030 OMOD, 1031 OMUL, 1032 OSUB, 1033 OXOR, 1034 OOR, 1035 OPLUS: 1036 k1 := idealkind(n.Left) 1037 k2 := idealkind(n.Right) 1038 if k1 > k2 { 1039 return k1 1040 } else { 1041 return k2 1042 } 1043 1044 case OREAL, OIMAG: 1045 return CTFLT 1046 1047 case OCOMPLEX: 1048 return CTCPLX 1049 1050 case OADDSTR: 1051 return CTSTR 1052 1053 case OANDAND, 1054 OEQ, 1055 OGE, 1056 OGT, 1057 OLE, 1058 OLT, 1059 ONE, 1060 ONOT, 1061 OOROR: 1062 return CTBOOL 1063 1064 // shifts (beware!). 1065 case OLSH, ORSH: 1066 return idealkind(n.Left) 1067 } 1068 } 1069 1070 // The result of defaultlit MUST be assigned back to n, e.g. 1071 // n.Left = defaultlit(n.Left, t) 1072 func defaultlit(n *Node, t *types.Type) *Node { 1073 return defaultlitreuse(n, t, noReuse) 1074 } 1075 1076 // The result of defaultlitreuse MUST be assigned back to n, e.g. 1077 // n.Left = defaultlitreuse(n.Left, t, reuse) 1078 func defaultlitreuse(n *Node, t *types.Type, reuse canReuseNode) *Node { 1079 if n == nil || !n.Type.IsUntyped() { 1080 return n 1081 } 1082 1083 if n.Op == OLITERAL && !reuse { 1084 n = n.rawcopy() 1085 reuse = true 1086 } 1087 1088 lno := setlineno(n) 1089 ctype := idealkind(n) 1090 var t1 *types.Type 1091 switch ctype { 1092 default: 1093 if t != nil { 1094 return convlit(n, t) 1095 } 1096 1097 switch n.Val().Ctype() { 1098 case CTNIL: 1099 lineno = lno 1100 if !n.Diag() { 1101 yyerror("use of untyped nil") 1102 n.SetDiag(true) 1103 } 1104 1105 n.Type = nil 1106 case CTSTR: 1107 t1 := types.Types[TSTRING] 1108 n = convlit1(n, t1, false, reuse) 1109 default: 1110 yyerror("defaultlit: unknown literal: %v", n) 1111 } 1112 lineno = lno 1113 return n 1114 1115 case CTxxx: 1116 Fatalf("defaultlit: idealkind is CTxxx: %+v", n) 1117 1118 case CTBOOL: 1119 t1 := types.Types[TBOOL] 1120 if t != nil && t.IsBoolean() { 1121 t1 = t 1122 } 1123 n = convlit1(n, t1, false, reuse) 1124 lineno = lno 1125 return n 1126 1127 case CTINT: 1128 t1 = types.Types[TINT] 1129 case CTRUNE: 1130 t1 = types.Runetype 1131 case CTFLT: 1132 t1 = types.Types[TFLOAT64] 1133 case CTCPLX: 1134 t1 = types.Types[TCOMPLEX128] 1135 } 1136 1137 // Note: n.Val().Ctype() can be CTxxx (not a constant) here 1138 // in the case of an untyped non-constant value, like 1<<i. 1139 v1 := n.Val() 1140 if t != nil { 1141 if t.IsInteger() { 1142 t1 = t 1143 v1 = toint(n.Val()) 1144 } else if t.IsFloat() { 1145 t1 = t 1146 v1 = toflt(n.Val()) 1147 } else if t.IsComplex() { 1148 t1 = t 1149 v1 = tocplx(n.Val()) 1150 } 1151 if n.Val().Ctype() != CTxxx { 1152 n.SetVal(v1) 1153 } 1154 } 1155 1156 if n.Val().Ctype() != CTxxx { 1157 overflow(n.Val(), t1) 1158 } 1159 n = convlit1(n, t1, false, reuse) 1160 lineno = lno 1161 return n 1162 } 1163 1164 // defaultlit on both nodes simultaneously; 1165 // if they're both ideal going in they better 1166 // get the same type going out. 1167 // force means must assign concrete (non-ideal) type. 1168 // The results of defaultlit2 MUST be assigned back to l and r, e.g. 1169 // n.Left, n.Right = defaultlit2(n.Left, n.Right, force) 1170 func defaultlit2(l *Node, r *Node, force bool) (*Node, *Node) { 1171 if l.Type == nil || r.Type == nil { 1172 return l, r 1173 } 1174 if !l.Type.IsUntyped() { 1175 r = convlit(r, l.Type) 1176 return l, r 1177 } 1178 1179 if !r.Type.IsUntyped() { 1180 l = convlit(l, r.Type) 1181 return l, r 1182 } 1183 1184 if !force { 1185 return l, r 1186 } 1187 1188 if l.Type.IsBoolean() { 1189 l = convlit(l, types.Types[TBOOL]) 1190 r = convlit(r, types.Types[TBOOL]) 1191 } 1192 1193 lkind := idealkind(l) 1194 rkind := idealkind(r) 1195 if lkind == CTCPLX || rkind == CTCPLX { 1196 l = convlit(l, types.Types[TCOMPLEX128]) 1197 r = convlit(r, types.Types[TCOMPLEX128]) 1198 return l, r 1199 } 1200 1201 if lkind == CTFLT || rkind == CTFLT { 1202 l = convlit(l, types.Types[TFLOAT64]) 1203 r = convlit(r, types.Types[TFLOAT64]) 1204 return l, r 1205 } 1206 1207 if lkind == CTRUNE || rkind == CTRUNE { 1208 l = convlit(l, types.Runetype) 1209 r = convlit(r, types.Runetype) 1210 return l, r 1211 } 1212 1213 l = convlit(l, types.Types[TINT]) 1214 r = convlit(r, types.Types[TINT]) 1215 1216 return l, r 1217 } 1218 1219 // strlit returns the value of a literal string Node as a string. 1220 func strlit(n *Node) string { 1221 return n.Val().U.(string) 1222 } 1223 1224 func smallintconst(n *Node) bool { 1225 if n.Op == OLITERAL && Isconst(n, CTINT) && n.Type != nil { 1226 switch simtype[n.Type.Etype] { 1227 case TINT8, 1228 TUINT8, 1229 TINT16, 1230 TUINT16, 1231 TINT32, 1232 TUINT32, 1233 TBOOL: 1234 return true 1235 1236 case TIDEAL, TINT64, TUINT64, TPTR: 1237 v, ok := n.Val().U.(*Mpint) 1238 if ok && v.Cmp(minintval[TINT32]) > 0 && v.Cmp(maxintval[TINT32]) < 0 { 1239 return true 1240 } 1241 } 1242 } 1243 1244 return false 1245 } 1246 1247 // nonnegintconst checks if Node n contains a constant expression 1248 // representable as a non-negative small integer, and returns its 1249 // (integer) value if that's the case. Otherwise, it returns -1. 1250 func nonnegintconst(n *Node) int64 { 1251 if n.Op != OLITERAL { 1252 return -1 1253 } 1254 1255 // toint will leave n.Val unchanged if it's not castable to an 1256 // Mpint, so we still have to guard the conversion. 1257 v := toint(n.Val()) 1258 vi, ok := v.U.(*Mpint) 1259 if !ok || vi.CmpInt64(0) < 0 || vi.Cmp(maxintval[TINT32]) > 0 { 1260 return -1 1261 } 1262 1263 return vi.Int64() 1264 } 1265 1266 // isGoConst reports whether n is a Go language constant (as opposed to a 1267 // compile-time constant). 1268 // 1269 // Expressions derived from nil, like string([]byte(nil)), while they 1270 // may be known at compile time, are not Go language constants. 1271 // Only called for expressions known to evaluated to compile-time 1272 // constants. 1273 func (n *Node) isGoConst() bool { 1274 if n.Orig != nil { 1275 n = n.Orig 1276 } 1277 1278 switch n.Op { 1279 case OADD, 1280 OADDSTR, 1281 OAND, 1282 OANDAND, 1283 OANDNOT, 1284 OCOM, 1285 ODIV, 1286 OEQ, 1287 OGE, 1288 OGT, 1289 OLE, 1290 OLSH, 1291 OLT, 1292 OMINUS, 1293 OMOD, 1294 OMUL, 1295 ONE, 1296 ONOT, 1297 OOR, 1298 OOROR, 1299 OPLUS, 1300 ORSH, 1301 OSUB, 1302 OXOR, 1303 OIOTA, 1304 OCOMPLEX, 1305 OREAL, 1306 OIMAG: 1307 if n.Left.isGoConst() && (n.Right == nil || n.Right.isGoConst()) { 1308 return true 1309 } 1310 1311 case OCONV: 1312 if okforconst[n.Type.Etype] && n.Left.isGoConst() { 1313 return true 1314 } 1315 1316 case OLEN, OCAP: 1317 l := n.Left 1318 if l.isGoConst() { 1319 return true 1320 } 1321 1322 // Special case: len/cap is constant when applied to array or 1323 // pointer to array when the expression does not contain 1324 // function calls or channel receive operations. 1325 t := l.Type 1326 1327 if t != nil && t.IsPtr() { 1328 t = t.Elem() 1329 } 1330 if t != nil && t.IsArray() && !hascallchan(l) { 1331 return true 1332 } 1333 1334 case OLITERAL: 1335 if n.Val().Ctype() != CTNIL { 1336 return true 1337 } 1338 1339 case ONAME: 1340 l := asNode(n.Sym.Def) 1341 if l != nil && l.Op == OLITERAL && n.Val().Ctype() != CTNIL { 1342 return true 1343 } 1344 1345 case ONONAME: 1346 if asNode(n.Sym.Def) != nil && asNode(n.Sym.Def).Op == OIOTA { 1347 return true 1348 } 1349 1350 case OALIGNOF, OOFFSETOF, OSIZEOF: 1351 return true 1352 } 1353 1354 //dump("nonconst", n); 1355 return false 1356 } 1357 1358 func hascallchan(n *Node) bool { 1359 if n == nil { 1360 return false 1361 } 1362 switch n.Op { 1363 case OAPPEND, 1364 OCALL, 1365 OCALLFUNC, 1366 OCALLINTER, 1367 OCALLMETH, 1368 OCAP, 1369 OCLOSE, 1370 OCOMPLEX, 1371 OCOPY, 1372 ODELETE, 1373 OIMAG, 1374 OLEN, 1375 OMAKE, 1376 ONEW, 1377 OPANIC, 1378 OPRINT, 1379 OPRINTN, 1380 OREAL, 1381 ORECOVER, 1382 ORECV: 1383 return true 1384 } 1385 1386 if hascallchan(n.Left) || hascallchan(n.Right) { 1387 return true 1388 } 1389 for _, n1 := range n.List.Slice() { 1390 if hascallchan(n1) { 1391 return true 1392 } 1393 } 1394 for _, n2 := range n.Rlist.Slice() { 1395 if hascallchan(n2) { 1396 return true 1397 } 1398 } 1399 1400 return false 1401 }