Source file src/pkg/cmd/compile/internal/gc/const.go
1
2
3
4
5 package gc
6
7 import (
8 "cmd/compile/internal/types"
9 "math/big"
10 "strings"
11 )
12
13
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
30
31
32
33
34
35
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
93
94
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
116
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
125 func (n *Node) CanInt64() bool {
126 if !Isconst(n, CTINT) {
127 return false
128 }
129
130
131
132 return n.Val().U.(*Mpint).CmpInt64(n.Int64()) == 0
133 }
134
135
136
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
145
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
153
154
155 return oldv
156 }
157
158 fv := newMpflt()
159
160
161
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
175
176
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
184
185
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
206
207 type canReuseNode bool
208
209 const (
210 noReuse canReuseNode = false
211 reuseOK canReuseNode = true
212 )
213
214
215
216
217
218 func convlit(n *Node, t *types.Type) *Node {
219 return convlit1(n, t, false, noReuse)
220 }
221
222
223
224
225
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
236
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
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
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
295
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
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
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 := newMpcmplx()
431 c.Real.SetInt(u)
432 c.Imag.SetFloat64(0.0)
433 v.U = c
434
435 case *Mpflt:
436 c := newMpcmplx()
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
480
481
482
483
484
485
486
487
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
538
539 if t == nil || t.Etype == TIDEAL {
540 return false
541 }
542
543
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
581
582 return t == ct || (ct == CTINT && t == CTRUNE)
583 }
584
585
586 func evconst(n *Node) {
587 nl, nr := n.Left, n.Right
588
589
590 switch op := n.Op; op {
591 case OPLUS, ONEG, OBITNOT, 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
605
606
607
608
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 okforconst[n.Type.Etype] && nl.Op == OLITERAL {
622
623 setconst(n, convlit1(nl, n.Type, true, false).Val())
624 }
625
626 case OCONVNOP:
627 if okforconst[n.Type.Etype] && nl.Op == OLITERAL {
628
629 n.Op = OCONV
630 setconst(n, nl.Val())
631 }
632
633 case OADDSTR:
634
635 s := n.List.Slice()
636 for i1 := 0; i1 < len(s); i1++ {
637 if Isconst(s[i1], CTSTR) && i1+1 < len(s) && Isconst(s[i1+1], CTSTR) {
638
639 var strs []string
640 i2 := i1
641 for i2 < len(s) && Isconst(s[i2], CTSTR) {
642 strs = append(strs, s[i2].Val().U.(string))
643 i2++
644 }
645
646 nl := *s[i1]
647 nl.Orig = &nl
648 nl.SetVal(Val{strings.Join(strs, "")})
649 s[i1] = &nl
650 s = append(s[:i1+1], s[i2:]...)
651 }
652 }
653
654 if len(s) == 1 && Isconst(s[0], CTSTR) {
655 n.Op = OLITERAL
656 n.SetVal(s[0].Val())
657 } else {
658 n.List.Set(s)
659 }
660
661 case OCAP, OLEN:
662 switch nl.Type.Etype {
663 case TSTRING:
664 if Isconst(nl, CTSTR) {
665 setintconst(n, int64(len(nl.Val().U.(string))))
666 }
667 case TARRAY:
668 if !hascallchan(nl) {
669 setintconst(n, nl.Type.NumElem())
670 }
671 }
672
673 case OALIGNOF, OOFFSETOF, OSIZEOF:
674 setintconst(n, evalunsafe(n))
675
676 case OREAL, OIMAG:
677 if nl.Op == OLITERAL {
678 var re, im *Mpflt
679 switch u := nl.Val().U.(type) {
680 case *Mpint:
681 re = newMpflt()
682 re.SetInt(u)
683
684 case *Mpflt:
685 re = u
686
687 case *Mpcplx:
688 re = &u.Real
689 im = &u.Imag
690 default:
691 Fatalf("impossible")
692 }
693 if n.Op == OIMAG {
694 if im == nil {
695 im = newMpflt()
696 }
697 re = im
698 }
699 setconst(n, Val{re})
700 }
701
702 case OCOMPLEX:
703 if nl == nil || nr == nil {
704
705 break
706 }
707 if nl.Op == OLITERAL && nr.Op == OLITERAL {
708
709 c := newMpcmplx()
710 c.Real.Set(toflt(nl.Val()).U.(*Mpflt))
711 c.Imag.Set(toflt(nr.Val()).U.(*Mpflt))
712 setconst(n, Val{c})
713 }
714 }
715 }
716
717 func match(x, y Val) (Val, Val) {
718 switch {
719 case x.Ctype() == CTCPLX || y.Ctype() == CTCPLX:
720 return tocplx(x), tocplx(y)
721 case x.Ctype() == CTFLT || y.Ctype() == CTFLT:
722 return toflt(x), toflt(y)
723 }
724
725
726 return x, y
727 }
728
729 func compareOp(x Val, op Op, y Val) bool {
730 x, y = match(x, y)
731
732 switch x.Ctype() {
733 case CTNIL:
734 _, _ = x.U.(*NilVal), y.U.(*NilVal)
735 switch op {
736 case OEQ:
737 return true
738 case ONE:
739 return false
740 }
741
742 case CTBOOL:
743 x, y := x.U.(bool), y.U.(bool)
744 switch op {
745 case OEQ:
746 return x == y
747 case ONE:
748 return x != y
749 }
750
751 case CTINT, CTRUNE:
752 x, y := x.U.(*Mpint), y.U.(*Mpint)
753 return cmpZero(x.Cmp(y), op)
754
755 case CTFLT:
756 x, y := x.U.(*Mpflt), y.U.(*Mpflt)
757 return cmpZero(x.Cmp(y), op)
758
759 case CTCPLX:
760 x, y := x.U.(*Mpcplx), y.U.(*Mpcplx)
761 eq := x.Real.Cmp(&y.Real) == 0 && x.Imag.Cmp(&y.Imag) == 0
762 switch op {
763 case OEQ:
764 return eq
765 case ONE:
766 return !eq
767 }
768
769 case CTSTR:
770 x, y := x.U.(string), y.U.(string)
771 switch op {
772 case OEQ:
773 return x == y
774 case ONE:
775 return x != y
776 case OLT:
777 return x < y
778 case OLE:
779 return x <= y
780 case OGT:
781 return x > y
782 case OGE:
783 return x >= y
784 }
785 }
786
787 Fatalf("compareOp: bad comparison: %v %v %v", x, op, y)
788 panic("unreachable")
789 }
790
791 func cmpZero(x int, op Op) bool {
792 switch op {
793 case OEQ:
794 return x == 0
795 case ONE:
796 return x != 0
797 case OLT:
798 return x < 0
799 case OLE:
800 return x <= 0
801 case OGT:
802 return x > 0
803 case OGE:
804 return x >= 0
805 }
806
807 Fatalf("cmpZero: want comparison operator, got %v", op)
808 panic("unreachable")
809 }
810
811 func binaryOp(x Val, op Op, y Val) Val {
812 x, y = match(x, y)
813
814 Outer:
815 switch x.Ctype() {
816 case CTBOOL:
817 x, y := x.U.(bool), y.U.(bool)
818 switch op {
819 case OANDAND:
820 return Val{U: x && y}
821 case OOROR:
822 return Val{U: x || y}
823 }
824
825 case CTINT, CTRUNE:
826 x, y := x.U.(*Mpint), y.U.(*Mpint)
827
828 u := new(Mpint)
829 u.Rune = x.Rune || y.Rune
830 u.Set(x)
831 switch op {
832 case OADD:
833 u.Add(y)
834 case OSUB:
835 u.Sub(y)
836 case OMUL:
837 u.Mul(y)
838 case ODIV:
839 if y.CmpInt64(0) == 0 {
840 yyerror("division by zero")
841 return Val{}
842 }
843 u.Quo(y)
844 case OMOD:
845 if y.CmpInt64(0) == 0 {
846 yyerror("division by zero")
847 return Val{}
848 }
849 u.Rem(y)
850 case OOR:
851 u.Or(y)
852 case OAND:
853 u.And(y)
854 case OANDNOT:
855 u.AndNot(y)
856 case OXOR:
857 u.Xor(y)
858 default:
859 break Outer
860 }
861 return Val{U: u}
862
863 case CTFLT:
864 x, y := x.U.(*Mpflt), y.U.(*Mpflt)
865
866 u := newMpflt()
867 u.Set(x)
868 switch op {
869 case OADD:
870 u.Add(y)
871 case OSUB:
872 u.Sub(y)
873 case OMUL:
874 u.Mul(y)
875 case ODIV:
876 if y.CmpFloat64(0) == 0 {
877 yyerror("division by zero")
878 return Val{}
879 }
880 u.Quo(y)
881 case OMOD, OOR, OAND, OANDNOT, OXOR:
882
883 yyerror("invalid operation: operator %v not defined on untyped float", op)
884 return Val{}
885 default:
886 break Outer
887 }
888 return Val{U: u}
889
890 case CTCPLX:
891 x, y := x.U.(*Mpcplx), y.U.(*Mpcplx)
892
893 u := newMpcmplx()
894 u.Real.Set(&x.Real)
895 u.Imag.Set(&x.Imag)
896 switch op {
897 case OADD:
898 u.Real.Add(&y.Real)
899 u.Imag.Add(&y.Imag)
900 case OSUB:
901 u.Real.Sub(&y.Real)
902 u.Imag.Sub(&y.Imag)
903 case OMUL:
904 u.Mul(y)
905 case ODIV:
906 if !u.Div(y) {
907 yyerror("complex division by zero")
908 return Val{}
909 }
910 case OMOD, OOR, OAND, OANDNOT, OXOR:
911
912 yyerror("invalid operation: operator %v not defined on untyped complex", op)
913 return Val{}
914 default:
915 break Outer
916 }
917 return Val{U: u}
918 }
919
920 Fatalf("binaryOp: bad operation: %v %v %v", x, op, y)
921 panic("unreachable")
922 }
923
924 func unaryOp(op Op, x Val, t *types.Type) Val {
925 switch op {
926 case OPLUS:
927 switch x.Ctype() {
928 case CTINT, CTRUNE, CTFLT, CTCPLX:
929 return x
930 }
931
932 case ONEG:
933 switch x.Ctype() {
934 case CTINT, CTRUNE:
935 x := x.U.(*Mpint)
936 u := new(Mpint)
937 u.Rune = x.Rune
938 u.Set(x)
939 u.Neg()
940 return Val{U: u}
941
942 case CTFLT:
943 x := x.U.(*Mpflt)
944 u := newMpflt()
945 u.Set(x)
946 u.Neg()
947 return Val{U: u}
948
949 case CTCPLX:
950 x := x.U.(*Mpcplx)
951 u := newMpcmplx()
952 u.Real.Set(&x.Real)
953 u.Imag.Set(&x.Imag)
954 u.Real.Neg()
955 u.Imag.Neg()
956 return Val{U: u}
957 }
958
959 case OBITNOT:
960 switch x.Ctype() {
961 case CTINT, CTRUNE:
962 x := x.U.(*Mpint)
963
964 u := new(Mpint)
965 u.Rune = x.Rune
966 if t.IsSigned() || t.IsUntyped() {
967
968 u.SetInt64(-1)
969 } else {
970
971 u.Set(maxintval[t.Etype])
972 }
973 u.Xor(x)
974 return Val{U: u}
975
976 case CTFLT:
977
978 yyerror("invalid operation: operator %v not defined on untyped float", op)
979 return Val{}
980 case CTCPLX:
981
982 yyerror("invalid operation: operator %v not defined on untyped complex", op)
983 return Val{}
984 }
985
986 case ONOT:
987 return Val{U: !x.U.(bool)}
988 }
989
990 Fatalf("unaryOp: bad operation: %v %v", op, x)
991 panic("unreachable")
992 }
993
994 func shiftOp(x Val, op Op, y Val) Val {
995 if x.Ctype() != CTRUNE {
996 x = toint(x)
997 }
998 y = toint(y)
999
1000 u := new(Mpint)
1001 u.Set(x.U.(*Mpint))
1002 u.Rune = x.U.(*Mpint).Rune
1003 switch op {
1004 case OLSH:
1005 u.Lsh(y.U.(*Mpint))
1006 case ORSH:
1007 u.Rsh(y.U.(*Mpint))
1008 default:
1009 Fatalf("shiftOp: bad operator: %v", op)
1010 panic("unreachable")
1011 }
1012 return Val{U: u}
1013 }
1014
1015
1016 func setconst(n *Node, v Val) {
1017
1018 if v.U == nil {
1019 n.Type = nil
1020 return
1021 }
1022
1023
1024
1025 if n.Orig == n {
1026 n.Orig = n.sepcopy()
1027 }
1028
1029 *n = Node{
1030 Op: OLITERAL,
1031 Pos: n.Pos,
1032 Orig: n.Orig,
1033 Type: n.Type,
1034 Xoffset: BADWIDTH,
1035 }
1036 n.SetVal(v)
1037
1038
1039 lno := setlineno(n)
1040 overflow(v, n.Type)
1041 lineno = lno
1042
1043
1044 if v.Ctype() == CTFLT && n.Type.Etype != TIDEAL {
1045 n.SetVal(Val{truncfltlit(v.U.(*Mpflt), n.Type)})
1046 }
1047 }
1048
1049 func setboolconst(n *Node, v bool) {
1050 setconst(n, Val{U: v})
1051 }
1052
1053 func setintconst(n *Node, v int64) {
1054 u := new(Mpint)
1055 u.SetInt64(v)
1056 setconst(n, Val{u})
1057 }
1058
1059
1060 func nodlit(v Val) *Node {
1061 n := nod(OLITERAL, nil, nil)
1062 n.SetVal(v)
1063 switch v.Ctype() {
1064 default:
1065 Fatalf("nodlit ctype %d", v.Ctype())
1066
1067 case CTSTR:
1068 n.Type = types.Idealstring
1069
1070 case CTBOOL:
1071 n.Type = types.Idealbool
1072
1073 case CTINT, CTRUNE, CTFLT, CTCPLX:
1074 n.Type = types.Types[TIDEAL]
1075
1076 case CTNIL:
1077 n.Type = types.Types[TNIL]
1078 }
1079
1080 return n
1081 }
1082
1083
1084
1085 func idealkind(n *Node) Ctype {
1086 if n == nil || !n.Type.IsUntyped() {
1087 return CTxxx
1088 }
1089
1090 switch n.Op {
1091 default:
1092 return CTxxx
1093
1094 case OLITERAL:
1095 return n.Val().Ctype()
1096
1097
1098 case OADD,
1099 OAND,
1100 OANDNOT,
1101 OBITNOT,
1102 ODIV,
1103 ONEG,
1104 OMOD,
1105 OMUL,
1106 OSUB,
1107 OXOR,
1108 OOR,
1109 OPLUS:
1110 k1 := idealkind(n.Left)
1111 k2 := idealkind(n.Right)
1112 if k1 > k2 {
1113 return k1
1114 } else {
1115 return k2
1116 }
1117
1118 case OREAL, OIMAG:
1119 return CTFLT
1120
1121 case OCOMPLEX:
1122 return CTCPLX
1123
1124 case OADDSTR:
1125 return CTSTR
1126
1127 case OANDAND,
1128 OEQ,
1129 OGE,
1130 OGT,
1131 OLE,
1132 OLT,
1133 ONE,
1134 ONOT,
1135 OOROR:
1136 return CTBOOL
1137
1138
1139 case OLSH, ORSH:
1140 return idealkind(n.Left)
1141 }
1142 }
1143
1144
1145
1146 func defaultlit(n *Node, t *types.Type) *Node {
1147 return defaultlitreuse(n, t, noReuse)
1148 }
1149
1150
1151
1152 func defaultlitreuse(n *Node, t *types.Type, reuse canReuseNode) *Node {
1153 if n == nil || !n.Type.IsUntyped() {
1154 return n
1155 }
1156
1157 if n.Op == OLITERAL && !reuse {
1158 n = n.rawcopy()
1159 reuse = true
1160 }
1161
1162 lno := setlineno(n)
1163 ctype := idealkind(n)
1164 var t1 *types.Type
1165 switch ctype {
1166 default:
1167 if t != nil {
1168 return convlit(n, t)
1169 }
1170
1171 switch n.Val().Ctype() {
1172 case CTNIL:
1173 lineno = lno
1174 if !n.Diag() {
1175 yyerror("use of untyped nil")
1176 n.SetDiag(true)
1177 }
1178
1179 n.Type = nil
1180 case CTSTR:
1181 t1 := types.Types[TSTRING]
1182 n = convlit1(n, t1, false, reuse)
1183 default:
1184 yyerror("defaultlit: unknown literal: %v", n)
1185 }
1186 lineno = lno
1187 return n
1188
1189 case CTxxx:
1190 Fatalf("defaultlit: idealkind is CTxxx: %+v", n)
1191
1192 case CTBOOL:
1193 t1 := types.Types[TBOOL]
1194 if t != nil && t.IsBoolean() {
1195 t1 = t
1196 }
1197 n = convlit1(n, t1, false, reuse)
1198 lineno = lno
1199 return n
1200
1201 case CTINT:
1202 t1 = types.Types[TINT]
1203 case CTRUNE:
1204 t1 = types.Runetype
1205 case CTFLT:
1206 t1 = types.Types[TFLOAT64]
1207 case CTCPLX:
1208 t1 = types.Types[TCOMPLEX128]
1209 }
1210
1211
1212
1213 v1 := n.Val()
1214 if t != nil {
1215 if t.IsInteger() {
1216 t1 = t
1217 v1 = toint(n.Val())
1218 } else if t.IsFloat() {
1219 t1 = t
1220 v1 = toflt(n.Val())
1221 } else if t.IsComplex() {
1222 t1 = t
1223 v1 = tocplx(n.Val())
1224 }
1225 if n.Val().Ctype() != CTxxx {
1226 n.SetVal(v1)
1227 }
1228 }
1229
1230 if n.Val().Ctype() != CTxxx {
1231 overflow(n.Val(), t1)
1232 }
1233 n = convlit1(n, t1, false, reuse)
1234 lineno = lno
1235 return n
1236 }
1237
1238
1239
1240
1241
1242
1243
1244 func defaultlit2(l *Node, r *Node, force bool) (*Node, *Node) {
1245 if l.Type == nil || r.Type == nil {
1246 return l, r
1247 }
1248 if !l.Type.IsUntyped() {
1249 r = convlit(r, l.Type)
1250 return l, r
1251 }
1252
1253 if !r.Type.IsUntyped() {
1254 l = convlit(l, r.Type)
1255 return l, r
1256 }
1257
1258 if !force {
1259 return l, r
1260 }
1261
1262 if l.Type.IsBoolean() {
1263 l = convlit(l, types.Types[TBOOL])
1264 r = convlit(r, types.Types[TBOOL])
1265 }
1266
1267 lkind := idealkind(l)
1268 rkind := idealkind(r)
1269 if lkind == CTCPLX || rkind == CTCPLX {
1270 l = convlit(l, types.Types[TCOMPLEX128])
1271 r = convlit(r, types.Types[TCOMPLEX128])
1272 return l, r
1273 }
1274
1275 if lkind == CTFLT || rkind == CTFLT {
1276 l = convlit(l, types.Types[TFLOAT64])
1277 r = convlit(r, types.Types[TFLOAT64])
1278 return l, r
1279 }
1280
1281 if lkind == CTRUNE || rkind == CTRUNE {
1282 l = convlit(l, types.Runetype)
1283 r = convlit(r, types.Runetype)
1284 return l, r
1285 }
1286
1287 l = convlit(l, types.Types[TINT])
1288 r = convlit(r, types.Types[TINT])
1289
1290 return l, r
1291 }
1292
1293
1294 func strlit(n *Node) string {
1295 return n.Val().U.(string)
1296 }
1297
1298
1299 func smallintconst(n *Node) bool {
1300 if n.Op == OLITERAL && Isconst(n, CTINT) && n.Type != nil {
1301 switch simtype[n.Type.Etype] {
1302 case TINT8,
1303 TUINT8,
1304 TINT16,
1305 TUINT16,
1306 TINT32,
1307 TUINT32,
1308 TBOOL:
1309 return true
1310
1311 case TIDEAL, TINT64, TUINT64, TPTR:
1312 v, ok := n.Val().U.(*Mpint)
1313 if ok && v.Cmp(minintval[TINT32]) >= 0 && v.Cmp(maxintval[TINT32]) <= 0 {
1314 return true
1315 }
1316 }
1317 }
1318
1319 return false
1320 }
1321
1322
1323
1324
1325
1326
1327 func indexconst(n *Node) int64 {
1328 if n.Op != OLITERAL {
1329 return -1
1330 }
1331
1332 v := toint(n.Val())
1333 vi, ok := v.U.(*Mpint)
1334 if !ok || vi.CmpInt64(0) < 0 {
1335 return -1
1336 }
1337 if vi.Cmp(maxintval[TINT]) > 0 {
1338 return -2
1339 }
1340
1341 return vi.Int64()
1342 }
1343
1344
1345
1346
1347
1348
1349 func (n *Node) isGoConst() bool {
1350 return n.Op == OLITERAL && n.Val().Ctype() != CTNIL
1351 }
1352
1353 func hascallchan(n *Node) bool {
1354 if n == nil {
1355 return false
1356 }
1357 switch n.Op {
1358 case OAPPEND,
1359 OCALL,
1360 OCALLFUNC,
1361 OCALLINTER,
1362 OCALLMETH,
1363 OCAP,
1364 OCLOSE,
1365 OCOMPLEX,
1366 OCOPY,
1367 ODELETE,
1368 OIMAG,
1369 OLEN,
1370 OMAKE,
1371 ONEW,
1372 OPANIC,
1373 OPRINT,
1374 OPRINTN,
1375 OREAL,
1376 ORECOVER,
1377 ORECV:
1378 return true
1379 }
1380
1381 if hascallchan(n.Left) || hascallchan(n.Right) {
1382 return true
1383 }
1384 for _, n1 := range n.List.Slice() {
1385 if hascallchan(n1) {
1386 return true
1387 }
1388 }
1389 for _, n2 := range n.Rlist.Slice() {
1390 if hascallchan(n2) {
1391 return true
1392 }
1393 }
1394
1395 return false
1396 }
1397
1398
1399 type constSet struct {
1400 m map[constSetKey]*Node
1401 }
1402
1403 type constSetKey struct {
1404 typ *types.Type
1405 val interface{}
1406 }
1407
1408
1409
1410
1411
1412
1413
1414
1415 func (s *constSet) add(n *Node) *Node {
1416 if n.Op == OCONVIFACE && n.Implicit() {
1417 n = n.Left
1418 }
1419
1420 if !n.isGoConst() {
1421 return nil
1422 }
1423 if n.Type.IsUntyped() {
1424 Fatalf("%v is untyped", n)
1425 }
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442 typ := n.Type
1443 switch typ {
1444 case types.Bytetype:
1445 typ = types.Types[TUINT8]
1446 case types.Runetype:
1447 typ = types.Types[TINT32]
1448 }
1449 k := constSetKey{typ, n.Val().Interface()}
1450
1451 if s.m == nil {
1452 s.m = make(map[constSetKey]*Node)
1453 }
1454 old, dup := s.m[k]
1455 if !dup {
1456 s.m[k] = n
1457 }
1458 return old
1459 }
1460
View as plain text