LEFT | RIGHT |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 /* | 5 /* |
6 * type check the whole tree of an expression. | 6 * type check the whole tree of an expression. |
7 * calculates expression types. | 7 * calculates expression types. |
8 * evaluates compile time constants. | 8 * evaluates compile time constants. |
9 * marks variables that escape the local frame. | 9 * marks variables that escape the local frame. |
10 * rewrites n->op to be more specific in some cases. | 10 * rewrites n->op to be more specific in some cases. |
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 l = typecheck(&n->left, ntop); | 475 l = typecheck(&n->left, ntop); |
476 if((t = l->type) == T) | 476 if((t = l->type) == T) |
477 goto error; | 477 goto error; |
478 if(l->op == OTYPE) { | 478 if(l->op == OTYPE) { |
479 ok |= Etype; | 479 ok |= Etype; |
480 n->op = OTYPE; | 480 n->op = OTYPE; |
481 n->type = ptrto(l->type); | 481 n->type = ptrto(l->type); |
482 n->left = N; | 482 n->left = N; |
483 goto ret; | 483 goto ret; |
484 } | 484 } |
485 » » if((top & (Erv | Etop)) && !isptr[t->etype]) { | 485 » » if(!isptr[t->etype]) { |
486 » » » yyerror("invalid indirect of %lN", n->left); | 486 » » » if(top & (Erv | Etop)) { |
487 » » » goto error; | 487 » » » » yyerror("invalid indirect of %lN", n->left); |
| 488 » » » » goto error; |
| 489 » » » } |
| 490 » » » goto ret; |
488 } | 491 } |
489 ok |= Erv; | 492 ok |= Erv; |
490 n->type = t->type; | 493 n->type = t->type; |
491 goto ret; | 494 goto ret; |
492 | 495 |
493 /* | 496 /* |
494 * arithmetic exprs | 497 * arithmetic exprs |
495 */ | 498 */ |
496 case OASOP: | 499 case OASOP: |
497 ok |= Etop; | 500 ok |= Etop; |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
630 // swap for back end | 633 // swap for back end |
631 n->left = r; | 634 n->left = r; |
632 n->right = l; | 635 n->right = l; |
633 } else if(r->op == OLITERAL && r->val.ctype == CTNIL) { | 636 } else if(r->op == OLITERAL && r->val.ctype == CTNIL) { |
634 // leave alone for back end | 637 // leave alone for back end |
635 } else { | 638 } else { |
636 n->etype = n->op; | 639 n->etype = n->op; |
637 n->op = OCMPIFACE; | 640 n->op = OCMPIFACE; |
638 } | 641 } |
639 } | 642 } |
640 » » if((op == ODIV || op == OMOD) && r->op == OLITERAL) { | 643 |
641 » » » switch(r->val.ctype) { | 644 » » if((op == ODIV || op == OMOD) && isconst(r, CTINT)) |
642 » » » case CTINT: | 645 » » if(mpcmpfixc(r->val.u.xval, 0) == 0) { |
643 » » » case CTRUNE: | 646 » » » yyerror("division by zero"); |
644 » » » » if(mpcmpfixc(r->val.u.xval, 0) == 0) { | 647 » » » goto error; |
645 » » » » » yyerror("division by zero"); | |
646 » » » » » goto error; | |
647 » » » » } | |
648 » » » » break; | |
649 » » » case CTFLT: | |
650 » » » » if(mpcmpfltc(r->val.u.fval, 0) == 0) { | |
651 » » » » » yyerror("division by zero"); | |
652 » » » » » goto error; | |
653 » » » » } | |
654 » » » » break; | |
655 » » » case CTCPLX: | |
656 » » » » if(mpcmpfltc(&r->val.u.cval->real, 0) == 0 && | |
657 » » » » mpcmpfltc(&r->val.u.cval->imag, 0) == 0) { | |
658 » » » » » yyerror("complex division by zero"); | |
659 » » » » » goto error; | |
660 » » » » } | |
661 » » » » break; | |
662 » » » } | |
663 }· | 648 }· |
| 649 |
664 n->type = t; | 650 n->type = t; |
665 goto ret; | 651 goto ret; |
666 | 652 |
667 shift: | 653 shift: |
668 defaultlit(&r, types[TUINT]); | 654 defaultlit(&r, types[TUINT]); |
669 n->right = r; | 655 n->right = r; |
670 t = r->type; | 656 t = r->type; |
671 if(!isint[t->etype] || issigned[t->etype]) { | 657 if(!isint[t->etype] || issigned[t->etype]) { |
672 yyerror("invalid operation: %N (shift count type %T, mus
t be unsigned integer)", n, r->type); | 658 yyerror("invalid operation: %N (shift count type %T, mus
t be unsigned integer)", n, r->type); |
673 goto error; | 659 goto error; |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
967 goto error; | 953 goto error; |
968 } | 954 } |
969 if(n->right->left != N) { | 955 if(n->right->left != N) { |
970 if((t = n->right->left->type) == T) | 956 if((t = n->right->left->type) == T) |
971 goto error; | 957 goto error; |
972 if(!isint[t->etype]) { | 958 if(!isint[t->etype]) { |
973 yyerror("invalid slice index %N (type %T)", n->r
ight->left, t); | 959 yyerror("invalid slice index %N (type %T)", n->r
ight->left, t); |
974 goto error; | 960 goto error; |
975 } | 961 } |
976 if(n->right->left->op == OLITERAL) { | 962 if(n->right->left->op == OLITERAL) { |
977 » » » » if(mpgetfix(n->right->left->val.u.xval) < 0) | 963 » » » » if(mpgetfix(n->right->left->val.u.xval) < 0) { |
978 yyerror("invalid slice index %N (index m
ust be non-negative)", n->right->left); | 964 yyerror("invalid slice index %N (index m
ust be non-negative)", n->right->left); |
979 » » » » else if(tp != nil && tp->bound > 0 && mpgetfix(n
->right->left->val.u.xval) > tp->bound) | 965 » » » » » goto error; |
| 966 » » » » } else if(tp != nil && tp->bound > 0 && mpgetfix
(n->right->left->val.u.xval) > tp->bound) { |
980 yyerror("invalid slice index %N (out of
bounds for %d-element array)", n->right->left, tp->bound); | 967 yyerror("invalid slice index %N (out of
bounds for %d-element array)", n->right->left, tp->bound); |
981 » » » » else if(mpcmpfixfix(n->right->left->val.u.xval,
maxintval[TINT]) > 0) | 968 » » » » » goto error; |
| 969 » » » » } else if(mpcmpfixfix(n->right->left->val.u.xval
, maxintval[TINT]) > 0) { |
982 yyerror("invalid slice index %N (index t
oo large)", n->right->left); | 970 yyerror("invalid slice index %N (index t
oo large)", n->right->left); |
| 971 goto error; |
| 972 } |
983 } | 973 } |
984 } | 974 } |
985 if(n->right->right != N) { | 975 if(n->right->right != N) { |
986 if((t = n->right->right->type) == T) | 976 if((t = n->right->right->type) == T) |
987 goto error; | 977 goto error; |
988 if(!isint[t->etype]) { | 978 if(!isint[t->etype]) { |
989 yyerror("invalid slice index %N (type %T)", n->r
ight->right, t); | 979 yyerror("invalid slice index %N (type %T)", n->r
ight->right, t); |
990 goto error; | 980 goto error; |
991 } | 981 } |
992 if(n->right->right->op == OLITERAL) { | 982 if(n->right->right->op == OLITERAL) { |
993 » » » » if(mpgetfix(n->right->right->val.u.xval) < 0) | 983 » » » » if(mpgetfix(n->right->right->val.u.xval) < 0) { |
994 yyerror("invalid slice index %N (index m
ust be non-negative)", n->right->right); | 984 yyerror("invalid slice index %N (index m
ust be non-negative)", n->right->right); |
995 » » » » else if(tp != nil && tp->bound > 0 && mpgetfix(n
->right->right->val.u.xval) > tp->bound) | 985 » » » » » goto error; |
| 986 » » » » } else if(tp != nil && tp->bound > 0 && mpgetfix
(n->right->right->val.u.xval) > tp->bound) { |
996 yyerror("invalid slice index %N (out of
bounds for %d-element array)", n->right->right, tp->bound); | 987 yyerror("invalid slice index %N (out of
bounds for %d-element array)", n->right->right, tp->bound); |
997 » » » » else if(mpcmpfixfix(n->right->right->val.u.xval,
maxintval[TINT]) > 0) | 988 » » » » » goto error; |
| 989 » » » » } else if(mpcmpfixfix(n->right->right->val.u.xva
l, maxintval[TINT]) > 0) { |
998 yyerror("invalid slice index %N (index t
oo large)", n->right->right); | 990 yyerror("invalid slice index %N (index t
oo large)", n->right->right); |
999 » » » } | 991 » » » » » goto error; |
| 992 » » » » } |
| 993 » » » } |
| 994 » » } |
| 995 » » if(n->right->left != N |
| 996 » » && n->right->right != N |
| 997 » » && n->right->left->op == OLITERAL |
| 998 » » && n->right->right->op == OLITERAL |
| 999 » » && mpcmpfixfix(n->right->left->val.u.xval, n->right->right->v
al.u.xval) > 0) { |
| 1000 » » » yyerror("inverted slice index %N > %N", n->right->left,
n->right->right); |
| 1001 » » » goto error; |
1000 } | 1002 } |
1001 goto ret; | 1003 goto ret; |
1002 | 1004 |
1003 /* | 1005 /* |
1004 * call and call like | 1006 * call and call like |
1005 */ | 1007 */ |
1006 case OCALL: | 1008 case OCALL: |
1007 l = n->left; | 1009 l = n->left; |
1008 if(l->op == ONAME && (r = unsafenmagic(n)) != N) { | 1010 if(l->op == ONAME && (r = unsafenmagic(n)) != N) { |
1009 if(n->isddd) | 1011 if(n->isddd) |
(...skipping 772 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1782 break; | 1784 break; |
1783 } | 1785 } |
1784 r = f; | 1786 r = f; |
1785 } | 1787 } |
1786 return r; | 1788 return r; |
1787 } | 1789 } |
1788 | 1790 |
1789 static int | 1791 static int |
1790 looktypedot(Node *n, Type *t, int dostrcmp) | 1792 looktypedot(Node *n, Type *t, int dostrcmp) |
1791 { | 1793 { |
1792 » Type *f1, *f2, *tt; | 1794 » Type *f1, *f2; |
1793 Sym *s; | 1795 Sym *s; |
1794 ········ | 1796 ········ |
1795 s = n->right->sym; | 1797 s = n->right->sym; |
1796 | 1798 |
1797 if(t->etype == TINTER) { | 1799 if(t->etype == TINTER) { |
1798 f1 = lookdot1(n, s, t, t->type, dostrcmp); | 1800 f1 = lookdot1(n, s, t, t->type, dostrcmp); |
1799 if(f1 == T) | 1801 if(f1 == T) |
1800 return 0; | 1802 return 0; |
1801 | 1803 |
1802 if(f1->width == BADWIDTH) | |
1803 fatal("lookdot badwidth %T %p", f1, f1); | |
1804 n->right = methodname(n->right, t); | 1804 n->right = methodname(n->right, t); |
1805 n->xoffset = f1->width; | 1805 n->xoffset = f1->width; |
1806 n->type = f1->type; | 1806 n->type = f1->type; |
1807 n->op = ODOTINTER; | 1807 n->op = ODOTINTER; |
1808 return 1; | 1808 return 1; |
1809 } | 1809 } |
1810 | 1810 |
1811 » tt = t; | 1811 » // Find the base type: methtype will fail if t |
1812 » if(t->sym == S && isptr[t->etype]) | 1812 » // is not of the form T or *T. |
1813 » » tt = t->type; | 1813 » f2 = methtype(t, 0); |
1814 | |
1815 » f2 = methtype(tt, 0); | |
1816 if(f2 == T) | 1814 if(f2 == T) |
1817 return 0; | 1815 return 0; |
1818 | 1816 |
1819 expandmeth(f2); | 1817 expandmeth(f2); |
1820 f2 = lookdot1(n, s, f2, f2->xmethod, dostrcmp); | 1818 f2 = lookdot1(n, s, f2, f2->xmethod, dostrcmp); |
1821 if(f2 == T) | 1819 if(f2 == T) |
1822 return 0; | 1820 return 0; |
1823 | 1821 |
1824 // disallow T.m if m requires *T receiver | 1822 // disallow T.m if m requires *T receiver |
1825 if(isptr[getthisx(f2->type)->type->type->etype] | 1823 if(isptr[getthisx(f2->type)->type->type->etype] |
(...skipping 1189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3015 fatal("got %T for %N", n->type, n); | 3013 fatal("got %T for %N", n->type, n); |
3016 if(typecheckdefstack->n != n) | 3014 if(typecheckdefstack->n != n) |
3017 fatal("typecheckdefstack mismatch"); | 3015 fatal("typecheckdefstack mismatch"); |
3018 l = typecheckdefstack; | 3016 l = typecheckdefstack; |
3019 typecheckdefstack = l->next; | 3017 typecheckdefstack = l->next; |
3020 | 3018 |
3021 lineno = lno; | 3019 lineno = lno; |
3022 n->walkdef = 1; | 3020 n->walkdef = 1; |
3023 return n; | 3021 return n; |
3024 } | 3022 } |
LEFT | RIGHT |