Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(128)

Side by Side Diff: src/cmd/gc/walk.c

Issue 1303042: code review 1303042: gc: new typechecking rules (Closed)
Patch Set: code review 1303042: gc: new typechecking rules Created 14 years, 9 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/cmd/gc/typecheck.c ('k') | src/pkg/math/fltasm_amd64.s » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "go.h" 5 #include "go.h"
6 6
7 static Node* walkprint(Node*, NodeList**, int); 7 static Node* walkprint(Node*, NodeList**, int);
8 static Node* conv(Node*, Type*); 8 static Node* conv(Node*, Type*);
9 static Node* mapfn(char*, Type*); 9 static Node* mapfn(char*, Type*);
10 static Node* makenewvar(Type*, NodeList**, Node**); 10 static Node* makenewvar(Type*, NodeList**, Node**);
11 11
12 enum
13 {
14 Inone,
15 I2T,
16 I2T2,
17 I2I,
18 I2Ix,
19 I2I2,
20 T2I,
21 I2Isame,
22 E2T,
23 E2T2,
24 E2I,
25 E2I2,
26 I2E,
27 I2E2,
28 T2E,
29 E2Esame,
30 };
31
32 // can this code branch reach the end 12 // can this code branch reach the end
33 // without an undcontitional RETURN 13 // without an undcontitional RETURN
34 // this is hard, so it is conservative 14 // this is hard, so it is conservative
35 int 15 int
36 walkret(NodeList *l) 16 walkret(NodeList *l)
37 { 17 {
38 Node *n; 18 Node *n;
39 19
40 loop: 20 loop:
41 while(l && l->next) 21 while(l && l->next)
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 t = n->type; 142 t = n->type;
163 t->sym = n->sym; 143 t->sym = n->sym;
164 t->local = n->local; 144 t->local = n->local;
165 t->vargen = n->vargen; 145 t->vargen = n->vargen;
166 t->siggen = 0; 146 t->siggen = 0;
167 t->method = nil; 147 t->method = nil;
168 t->nod = N; 148 t->nod = N;
169 t->printed = 0; 149 t->printed = 0;
170 t->deferwidth = 0; 150 t->deferwidth = 0;
171 151
172 » // double-check use of type as map key 152 » // double-check use of type as map key.
173 » // TODO(rsc): also use of type as receiver?
174 if(maplineno) { 153 if(maplineno) {
175 lineno = maplineno; 154 lineno = maplineno;
176 maptype(n->type, types[TBOOL]); 155 maptype(n->type, types[TBOOL]);
177 } 156 }
178 if(embedlineno) { 157 if(embedlineno) {
179 lineno = embedlineno; 158 lineno = embedlineno;
180 if(isptr[t->etype]) 159 if(isptr[t->etype])
181 yyerror("embedded type cannot be a pointer"); 160 yyerror("embedded type cannot be a pointer");
182 } 161 }
183 162
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 default: 413 default:
435 walkexpr(&n->left, &n->ninit); 414 walkexpr(&n->left, &n->ninit);
436 break; 415 break;
437 } 416 }
438 break; 417 break;
439 418
440 case OFOR: 419 case OFOR:
441 walkstmtlist(n->ninit); 420 walkstmtlist(n->ninit);
442 if(n->ntest != N) { 421 if(n->ntest != N) {
443 walkstmtlist(n->ntest->ninit); 422 walkstmtlist(n->ntest->ninit);
444 » » » walkexpr(&n->ntest, &n->ninit); 423 » » » init = n->ntest->ninit;
424 » » » n->ntest->ninit = nil;
425 » » » walkexpr(&n->ntest, &init);
426 » » » n->ntest->ninit = concat(init, n->ntest->ninit);
445 } 427 }
446 walkstmt(&n->nincr); 428 walkstmt(&n->nincr);
447 walkstmtlist(n->nbody); 429 walkstmtlist(n->nbody);
448 break; 430 break;
449 431
450 case OIF: 432 case OIF:
451 walkstmtlist(n->ninit); 433 walkstmtlist(n->ninit);
452 walkexpr(&n->ntest, &n->ninit); 434 walkexpr(&n->ntest, &n->ninit);
453 walkstmtlist(n->nbody); 435 walkstmtlist(n->nbody);
454 walkstmtlist(n->nelse); 436 walkstmtlist(n->nelse);
(...skipping 21 matching lines...) Expand all
476 if(samelist(rl, n->list)) { 458 if(samelist(rl, n->list)) {
477 // special return in disguise 459 // special return in disguise
478 n->list = nil; 460 n->list = nil;
479 break; 461 break;
480 } 462 }
481 ll = ascompatee(n->op, rl, n->list, &n->ninit); 463 ll = ascompatee(n->op, rl, n->list, &n->ninit);
482 n->list = reorder3(ll); 464 n->list = reorder3(ll);
483 break; 465 break;
484 } 466 }
485 ll = ascompatte(n->op, getoutarg(curfn->type), n->list, 1, &n->n init); 467 ll = ascompatte(n->op, getoutarg(curfn->type), n->list, 1, &n->n init);
486 » » n->list = reorder4(ll); 468 » » n->list = ll;
487 break; 469 break;
488 470
489 case OSELECT: 471 case OSELECT:
490 walkselect(n); 472 walkselect(n);
491 break; 473 break;
492 474
493 case OSWITCH: 475 case OSWITCH:
494 walkswitch(n); 476 walkswitch(n);
495 break; 477 break;
496 478
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 516
535 void 517 void
536 walkexpr(Node **np, NodeList **init) 518 walkexpr(Node **np, NodeList **init)
537 { 519 {
538 Node *r, *l, *var, *a; 520 Node *r, *l, *var, *a;
539 NodeList *ll, *lr, *lpost; 521 NodeList *ll, *lr, *lpost;
540 Type *t; 522 Type *t;
541 int et; 523 int et;
542 int32 lno; 524 int32 lno;
543 Node *n, *fn; 525 Node *n, *fn;
526 char buf[100], *p;
544 527
545 n = *np; 528 n = *np;
546 529
547 if(n == N) 530 if(n == N)
548 return; 531 return;
549 532
550 if(init == &n->ninit) { 533 if(init == &n->ninit) {
551 // not okay to use n->ninit when walking n, 534 // not okay to use n->ninit when walking n,
552 // because we might replace n with some other node 535 // because we might replace n with some other node
553 // and would lose the init list. 536 // and would lose the init list.
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 walkexprlist(n->list, init); 647 walkexprlist(n->list, init);
665 ll = ascompatte(n->op, getinarg(t), n->list, 0, init); 648 ll = ascompatte(n->op, getinarg(t), n->list, 0, init);
666 n->list = reorder1(ll); 649 n->list = reorder1(ll);
667 if(isselect(n)) { 650 if(isselect(n)) {
668 // special prob with selectsend and selectrecv: 651 // special prob with selectsend and selectrecv:
669 // if chan is nil, they don't know big the channel 652 // if chan is nil, they don't know big the channel
670 // element is and therefore don't know how to find 653 // element is and therefore don't know how to find
671 // the output bool, so we clear it before the call. 654 // the output bool, so we clear it before the call.
672 Node *b; 655 Node *b;
673 b = nodbool(0); 656 b = nodbool(0);
657 typecheck(&b, Erv);
674 lr = ascompatte(n->op, getoutarg(t), list1(b), 0, init); 658 lr = ascompatte(n->op, getoutarg(t), list1(b), 0, init);
675 n->list = concat(n->list, lr); 659 n->list = concat(n->list, lr);
676 } 660 }
677 goto ret; 661 goto ret;
678 662
679 case OCALLMETH: 663 case OCALLMETH:
680 t = n->left->type; 664 t = n->left->type;
681 if(n->list && n->list->n->op == OAS) 665 if(n->list && n->list->n->op == OAS)
682 goto ret; 666 goto ret;
683 walkexpr(&n->left, init); 667 walkexpr(&n->left, init);
(...skipping 19 matching lines...) Expand all
703 if(l == N || r == N) 687 if(l == N || r == N)
704 goto ret; 688 goto ret;
705 r = ascompatee1(n->op, l, r, init); 689 r = ascompatee1(n->op, l, r, init);
706 if(r != N) { 690 if(r != N) {
707 r->dodata = n->dodata; 691 r->dodata = n->dodata;
708 n = r; 692 n = r;
709 } 693 }
710 goto ret; 694 goto ret;
711 695
712 case OAS2: 696 case OAS2:
713 as2:
714 *init = concat(*init, n->ninit); 697 *init = concat(*init, n->ninit);
715 n->ninit = nil; 698 n->ninit = nil;
716 walkexprlistsafe(n->list, init); 699 walkexprlistsafe(n->list, init);
717 walkexprlistsafe(n->rlist, init); 700 walkexprlistsafe(n->rlist, init);
718 ll = ascompatee(OAS, n->list, n->rlist, init); 701 ll = ascompatee(OAS, n->list, n->rlist, init);
719 ll = reorder3(ll); 702 ll = reorder3(ll);
720 n = liststmt(ll); 703 n = liststmt(ll);
721 goto ret; 704 goto ret;
722 705
723 case OAS2FUNC: 706 case OAS2FUNC:
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 t = l->left->type; 778 t = l->left->type;
796 n = mkcall1(mapfn("mapassign2", t), T, init, l->left, l->right, n->rlist->n, n->rlist->next->n); 779 n = mkcall1(mapfn("mapassign2", t), T, init, l->left, l->right, n->rlist->n, n->rlist->next->n);
797 goto ret; 780 goto ret;
798 781
799 case OAS2DOTTYPE: 782 case OAS2DOTTYPE:
800 // a,b = i.(T) 783 // a,b = i.(T)
801 *init = concat(*init, n->ninit); 784 *init = concat(*init, n->ninit);
802 n->ninit = nil; 785 n->ninit = nil;
803 r = n->rlist->n; 786 r = n->rlist->n;
804 walkexprlistsafe(n->list, init); 787 walkexprlistsafe(n->list, init);
805 » » walkdottype(r, init); 788 » » r->op = ODOTTYPE2;
806 » » et = ifaceas1(r->type, r->left->type, 1); 789 » » walkexpr(&r, init);
807 » » switch(et) {
808 » » case I2Isame:
809 » » case E2Esame:
810 » » case I2E:
811 » » » n->rlist = list(list1(r->left), nodbool(1));
812 » » » typechecklist(n->rlist, Erv);
813 » » » goto as2;
814 » » case I2T:
815 » » » et = I2T2;
816 » » » break;
817 » » case I2Ix:
818 » » » et = I2I2;
819 » » » break;
820 » » case E2I:
821 » » » et = E2I2;
822 » » » break;
823 » » case E2T:
824 » » » et = E2T2;
825 » » » break;
826 » » default:
827 » » » et = Inone;
828 » » » break;
829 » » }
830 » » if(et == Inone)
831 » » » break;
832 » » r = ifacecvt(r->type, r->left, et, init);
833 ll = ascompatet(n->op, n->list, &r->type, 0, init); 790 ll = ascompatet(n->op, n->list, &r->type, 0, init);
834 n = liststmt(concat(list1(r), ll)); 791 n = liststmt(concat(list1(r), ll));
835 goto ret; 792 goto ret;
836 793
837 case ODOTTYPE: 794 case ODOTTYPE:
838 » » walkdottype(n, init); 795 » case ODOTTYPE2:»»·······
839 » » walkconv(&n, init); 796 » » // Build name of function: assertI2E2 etc.
797 » » strcpy(buf, "assert");
798 » » p = buf+strlen(buf);
799 » » if(isnilinter(n->left->type))
800 » » » *p++ = 'E';
801 » » else
802 » » » *p++ = 'I';
803 » » *p++ = '2';
804 » » if(isnilinter(n->type))
805 » » » *p++ = 'E';
806 » » else if(isinter(n->type))
807 » » » *p++ = 'I';
808 » » else
809 » » » *p++ = 'T';
810 » » if(n->op == ODOTTYPE2)
811 » » » *p++ = '2';
812 » » *p = '\0';
813 »·······
814 » » fn = syslook(buf, 1);
815 » » ll = list1(typename(n->type));
816 » » ll = list(ll, n->left);
817 » » argtype(fn, n->left->type);
818 » » argtype(fn, n->type);
819 » » n = nod(OCALL, fn, N);
820 » » n->list = ll;
821 » » typecheck(&n, Erv | Efnstruct);
822 » » walkexpr(&n, init);
823 » » goto ret;
824
825 » case OCONVIFACE:
826 » » // Build name of function: convI2E etc.
827 » » // Not all names are possible
828 » » // (e.g., we'll never generate convE2E or convE2I).
829 » » walkexpr(&n->left, init);
830 » » strcpy(buf, "conv");
831 » » p = buf+strlen(buf);
832 » » if(isnilinter(n->left->type))
833 » » » *p++ = 'E';
834 » » else if(isinter(n->left->type))
835 » » » *p++ = 'I';
836 » » else
837 » » » *p++ = 'T';
838 » » *p++ = '2';
839 » » if(isnilinter(n->type))
840 » » » *p++ = 'E';
841 » » else
842 » » » *p++ = 'I';
843 » » *p = '\0';
844 » »·······
845 » » fn = syslook(buf, 1);
846 » » ll = nil;
847 » » if(!isinter(n->left->type))
848 » » » ll = list(ll, typename(n->left->type));
849 » » if(!isnilinter(n->type))
850 » » » ll = list(ll, typename(n->type));
851 » » ll = list(ll, n->left);
852 » » argtype(fn, n->left->type);
853 » » argtype(fn, n->type);
854 » » dowidth(fn->type);
855 » » n = nod(OCALL, fn, N);
856 » » n->list = ll;
857 » » typecheck(&n, Erv);
858 » » walkexpr(&n, init);
840 goto ret; 859 goto ret;
841 860
842 case OCONV: 861 case OCONV:
843 case OCONVNOP: 862 case OCONVNOP:
844 if(thechar == '5') { 863 if(thechar == '5') {
845 if(isfloat[n->left->type->etype] && 864 if(isfloat[n->left->type->etype] &&
846 (n->type->etype == TINT64 || n->type->etype == TUINT6 4)) { 865 (n->type->etype == TINT64 || n->type->etype == TUINT6 4)) {
847 n = mkcall("float64toint64", n->type, init, conv (n->left, types[TFLOAT64])); 866 n = mkcall("float64toint64", n->type, init, conv (n->left, types[TFLOAT64]));
848 goto ret; 867 goto ret;
849 } 868 }
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
1169 argtype(fn, t->type); // any-1 1188 argtype(fn, t->type); // any-1
1170 n = mkcall1(fn, n->type, init, 1189 n = mkcall1(fn, n->type, init,
1171 typename(n->type), 1190 typename(n->type),
1172 conv(l, types[TINT64]), 1191 conv(l, types[TINT64]),
1173 conv(r, types[TINT64])); 1192 conv(r, types[TINT64]));
1174 goto ret; 1193 goto ret;
1175 1194
1176 case ORUNESTR: 1195 case ORUNESTR:
1177 // sys_intstring(v) 1196 // sys_intstring(v)
1178 n = mkcall("intstring", n->type, init, 1197 n = mkcall("intstring", n->type, init,
1179 » » » conv(n->left, types[TINT64]));» // TODO(rsc): int64?! 1198 » » » conv(n->left, types[TINT64]));
1180 goto ret; 1199 goto ret;
1181 1200
1182 case OARRAYBYTESTR: 1201 case OARRAYBYTESTR:
1183 // slicebytetostring([]byte) string; 1202 // slicebytetostring([]byte) string;
1184 n = mkcall("slicebytetostring", n->type, init, n->left); 1203 n = mkcall("slicebytetostring", n->type, init, n->left);
1185 goto ret; 1204 goto ret;
1186 1205
1187 case OARRAYRUNESTR: 1206 case OARRAYRUNESTR:
1188 // sliceinttostring([]int) string; 1207 // sliceinttostring([]int) string;
1189 n = mkcall("sliceinttostring", n->type, init, n->left); 1208 n = mkcall("sliceinttostring", n->type, init, n->left);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1227 goto ret; 1246 goto ret;
1228 1247
1229 case OSEND: 1248 case OSEND:
1230 n = mkcall1(chanfn("chansend1", 2, n->left->type), T, init, n->l eft, n->right); 1249 n = mkcall1(chanfn("chansend1", 2, n->left->type), T, init, n->l eft, n->right);
1231 goto ret; 1250 goto ret;
1232 1251
1233 case OSENDNB: 1252 case OSENDNB:
1234 n = mkcall1(chanfn("chansend2", 2, n->left->type), n->type, init , n->left, n->right); 1253 n = mkcall1(chanfn("chansend2", 2, n->left->type), n->type, init , n->left, n->right);
1235 goto ret; 1254 goto ret;
1236 1255
1237 case OCONVIFACE:
1238 walkexpr(&n->left, init);
1239 n = ifacecvt(n->type, n->left, n->etype, init);
1240 goto ret;
1241
1242 case OCLOSURE: 1256 case OCLOSURE:
1243 n = walkclosure(n, init); 1257 n = walkclosure(n, init);
1244 goto ret; 1258 goto ret;
1245 } 1259 }
1246 fatal("missing switch %O", n->op); 1260 fatal("missing switch %O", n->op);
1247 1261
1248 ret: 1262 ret:
1249 if(debug['w'] && n != N) 1263 if(debug['w'] && n != N)
1250 dump("walk", n); 1264 dump("walk", n);
1251 1265
(...skipping 12 matching lines...) Expand all
1264 nas = nod(OAS, nvar, callnew(t->type)); 1278 nas = nod(OAS, nvar, callnew(t->type));
1265 typecheck(&nas, Etop); 1279 typecheck(&nas, Etop);
1266 walkexpr(&nas, init); 1280 walkexpr(&nas, init);
1267 *init = list(*init, nas); 1281 *init = list(*init, nas);
1268 1282
1269 *nstar = nod(OIND, nvar, N); 1283 *nstar = nod(OIND, nvar, N);
1270 typecheck(nstar, Erv); 1284 typecheck(nstar, Erv);
1271 return nvar; 1285 return nvar;
1272 } 1286 }
1273 1287
1274 // TODO(rsc): cut
1275 void
1276 walkdottype(Node *n, NodeList **init)
1277 {
1278 walkexpr(&n->left, init);
1279 if(n->left == N)
1280 return;
1281 if(n->right != N) {
1282 walkexpr(&n->right, init);
1283 n->type = n->right->type;
1284 n->right = N;
1285 }
1286 }
1287
1288 // TODO(rsc): cut
1289 void
1290 walkconv(Node **np, NodeList **init)
1291 {
1292 int et;
1293 char *what;
1294 Type *t;
1295 Node *l;
1296 Node *n;
1297
1298 n = *np;
1299 t = n->type;
1300 if(t == T)
1301 return;
1302 walkexpr(&n->left, init);
1303 l = n->left;
1304 if(l == N)
1305 return;
1306 if(l->type == T)
1307 return;
1308
1309 // if using .(T), interface assertion.
1310 if(n->op == ODOTTYPE) {
1311 et = ifaceas1(t, l->type, 1);
1312 if(et == I2Isame || et == E2Esame) {
1313 n->op = OCONVNOP;
1314 return;
1315 }
1316 if(et != Inone) {
1317 n = ifacecvt(t, l, et, init);
1318 *np = n;
1319 return;
1320 }
1321 goto bad;
1322 }
1323
1324 fatal("walkconv");
1325
1326 bad:
1327 if(n->diag)
1328 return;
1329 n->diag = 1;
1330 if(n->op == ODOTTYPE)
1331 what = "type assertion";
1332 else
1333 what = "conversion";
1334 if(l->type != T)
1335 yyerror("invalid %s: %T to %T", what, l->type, t);
1336 }
1337
1338 Node* 1288 Node*
1339 ascompatee1(int op, Node *l, Node *r, NodeList **init) 1289 ascompatee1(int op, Node *l, Node *r, NodeList **init)
1340 { 1290 {
1341 return convas(nod(OAS, l, r), init); 1291 return convas(nod(OAS, l, r), init);
1342 } 1292 }
1343 1293
1344 NodeList* 1294 NodeList*
1345 ascompatee(int op, NodeList *nl, NodeList *nr, NodeList **init) 1295 ascompatee(int op, NodeList *nl, NodeList *nr, NodeList **init)
1346 { 1296 {
1347 NodeList *ll, *lr, *nn; 1297 NodeList *ll, *lr, *nn;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1411 r = structnext(&saver); 1361 r = structnext(&saver);
1412 continue; 1362 continue;
1413 } 1363 }
1414 1364
1415 // any lv that causes a fn call must be 1365 // any lv that causes a fn call must be
1416 // deferred until all the return arguments 1366 // deferred until all the return arguments
1417 // have been pulled from the output arguments 1367 // have been pulled from the output arguments
1418 if(fncall(l, r->type)) { 1368 if(fncall(l, r->type)) {
1419 tmp = nod(OXXX, N, N); 1369 tmp = nod(OXXX, N, N);
1420 tempname(tmp, r->type); 1370 tempname(tmp, r->type);
1371 typecheck(&tmp, Erv);
1421 a = nod(OAS, l, tmp); 1372 a = nod(OAS, l, tmp);
1422 a = convas(a, init); 1373 a = convas(a, init);
1423 mm = list(mm, a); 1374 mm = list(mm, a);
1424 l = tmp; 1375 l = tmp;
1425 } 1376 }
1426 1377
1427 a = nod(OAS, l, nodarg(r, fp)); 1378 a = nod(OAS, l, nodarg(r, fp));
1428 a = convas(a, init); 1379 a = convas(a, init);
1429 ullmancalc(a); 1380 ullmancalc(a);
1430 if(a->ullman >= UINF) 1381 if(a->ullman >= UINF)
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1510 } 1461 }
1511 1462
1512 // make a named type for the struct 1463 // make a named type for the struct
1513 st = sigtype(st); 1464 st = sigtype(st);
1514 dowidth(st); 1465 dowidth(st);
1515 1466
1516 // now we have the size, make the struct 1467 // now we have the size, make the struct
1517 var = nod(OXXX, N, N); 1468 var = nod(OXXX, N, N);
1518 tempname(var, st); 1469 tempname(var, st);
1519 var->sym = lookup(".ddd"); 1470 var->sym = lookup(".ddd");
1471 typecheck(&var, Erv);
1520 1472
1521 // assign the fields to the struct. 1473 // assign the fields to the struct.
1522 // use the init list so that reorder1 doesn't reorder 1474 // use the init list so that reorder1 doesn't reorder
1523 // these assignments after the interface conversion 1475 // these assignments after the interface conversion
1524 // below. 1476 // below.
1525 t = st->type; 1477 t = st->type;
1526 for(lr=n; lr; lr=lr->next) { 1478 for(lr=n; lr; lr=lr->next) {
1527 r = lr->n; 1479 r = lr->n;
1528 r->left = nod(OXXX, N, N); 1480 r->left = nod(OXXX, N, N);
1529 *r->left = *var; 1481 *r->left = *var;
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
1920 1872
1921 dowidth(t->type); 1873 dowidth(t->type);
1922 1874
1923 return t; 1875 return t;
1924 1876
1925 bad: 1877 bad:
1926 yyerror("not a channel: %lT", t); 1878 yyerror("not a channel: %lT", t);
1927 return T; 1879 return T;
1928 } 1880 }
1929 1881
1930 /*
1931 * assigning src to dst involving interfaces?
1932 * return op to use.
1933 */
1934 int
1935 ifaceas1(Type *dst, Type *src, int explicit)
1936 {
1937 if(src == T || dst == T)
1938 return Inone;
1939
1940 if(explicit && !isinter(src))
1941 yyerror("cannot use .(T) on non-interface type %T", src);
1942
1943 if(isinter(dst)) {
1944 if(isinter(src)) {
1945 if(isnilinter(dst)) {
1946 if(isnilinter(src))
1947 return E2Esame;
1948 return I2E;
1949 }
1950 if(eqtype(dst, src))
1951 return I2Isame;
1952 ifacecheck(dst, src, lineno, explicit);
1953 if(isnilinter(src))
1954 return E2I;
1955 if(explicit)
1956 return I2Ix;
1957 return I2I;
1958 }
1959 if(isnilinter(dst))
1960 return T2E;
1961 ifacecheck(dst, src, lineno, explicit);
1962 return T2I;
1963 }
1964 if(isinter(src)) {
1965 ifacecheck(dst, src, lineno, explicit);
1966 if(isnilinter(src))
1967 return E2T;
1968 return I2T;
1969 }
1970 return Inone;
1971 }
1972
1973 /*
1974 * treat convert T to T as noop
1975 */
1976 int
1977 ifaceas(Type *dst, Type *src, int explicit)
1978 {
1979 int et;
1980
1981 et = ifaceas1(dst, src, explicit);
1982 if(et == I2Isame || et == E2Esame)
1983 et = Inone;
1984 return et;
1985 }
1986
1987 static char*
1988 ifacename[] =
1989 {
1990 [I2T] = "ifaceI2T",
1991 [I2T2] = "ifaceI2T2",
1992 [I2I] = "ifaceI2I",
1993 [I2Ix] = "ifaceI2Ix",
1994 [I2I2] = "ifaceI2I2",
1995 [I2Isame] = "ifaceI2Isame",
1996 [E2T] = "ifaceE2T",
1997 [E2T2] = "ifaceE2T2",
1998 [E2I] = "ifaceE2I",
1999 [E2I2] = "ifaceE2I2",
2000 [I2E] = "ifaceI2E",
2001 [I2E2] = "ifaceI2E2",
2002 [T2I] = "ifaceT2I",
2003 [T2E] = "ifaceT2E",
2004 [E2Esame] = "ifaceE2Esame",
2005 };
2006
2007 Node*
2008 ifacecvt(Type *tl, Node *n, int et, NodeList **init)
2009 {
2010 Type *tr;
2011 Node *r, *on;
2012 NodeList *args;
2013
2014 tr = n->type;
2015
2016 switch(et) {
2017 default:
2018 fatal("ifacecvt: unknown op %d\n", et);
2019
2020 case I2Isame:
2021 case E2Esame:
2022 return n;
2023
2024 case T2I:
2025 // ifaceT2I(sigi *byte, sigt *byte, elem any) (ret any);
2026 args = list1(typename(tl)); // sigi
2027 args = list(args, typename(tr)); // sigt
2028 args = list(args, n); // elem
2029
2030 on = syslook("ifaceT2I", 1);
2031 argtype(on, tr);
2032 argtype(on, tl);
2033 dowidth(on->type);
2034 break;
2035
2036 case I2T:
2037 case I2T2:
2038 case I2I:
2039 case I2Ix:
2040 case I2I2:
2041 case E2T:
2042 case E2T2:
2043 case E2I:
2044 case E2I2:
2045 // iface[IT]2[IT][2](sigt *byte, iface any) (ret any[, ok bool]) ;
2046 args = list1(typename(tl)); // sigi or sigt
2047 args = list(args, n); // iface
2048
2049 on = syslook(ifacename[et], 1);
2050 argtype(on, tr);
2051 argtype(on, tl);
2052 break;
2053
2054 case I2E:
2055 // TODO(rsc): Should do this in back end, without a call.
2056 // ifaceI2E(elem any) (ret any);
2057 args = list1(n); // elem
2058
2059 on = syslook("ifaceI2E", 1);
2060 argtype(on, tr);
2061 argtype(on, tl);
2062 break;
2063
2064 case T2E:
2065 // TODO(rsc): Should do this in back end for pointer case, witho ut a call.
2066 // ifaceT2E(sigt *byte, elem any) (ret any);
2067 args = list1(typename(tr)); // sigt
2068 args = list(args, n); // elem
2069
2070 on = syslook("ifaceT2E", 1);
2071 argtype(on, tr);
2072 argtype(on, tl);
2073 break;
2074 }
2075
2076 dowidth(on->type);
2077 r = nod(OCALL, on, N);
2078 r->list = args;
2079 typecheck(&r, Erv | Efnstruct);
2080 walkexpr(&r, init);
2081 return r;
2082 }
2083
2084 Node* 1882 Node*
2085 convas(Node *n, NodeList **init) 1883 convas(Node *n, NodeList **init)
2086 { 1884 {
2087 Node *l, *r; 1885 Node *l, *r;
2088 Type *lt, *rt; 1886 Type *lt, *rt;
2089 int et;
2090 1887
2091 if(n->op != OAS) 1888 if(n->op != OAS)
2092 fatal("convas: not OAS %O", n->op); 1889 fatal("convas: not OAS %O", n->op);
2093 n->typecheck = 1; 1890 n->typecheck = 1;
2094 1891
2095 lt = T; 1892 lt = T;
2096 rt = T; 1893 rt = T;
2097 1894
2098 l = n->left; 1895 l = n->left;
2099 r = n->right; 1896 r = n->right;
2100 if(l == N || r == N) 1897 if(l == N || r == N)
2101 goto out; 1898 goto out;
2102 1899
2103 lt = l->type; 1900 lt = l->type;
2104 rt = r->type; 1901 rt = r->type;
2105 if(lt == T || rt == T) 1902 if(lt == T || rt == T)
2106 goto out; 1903 goto out;
2107 1904
2108 if(isblank(n->left)) { 1905 if(isblank(n->left)) {
2109 defaultlit(&n->right, T); 1906 defaultlit(&n->right, T);
2110 goto out; 1907 goto out;
2111 } 1908 }
2112 1909
2113 if(n->left->op == OINDEXMAP) { 1910 if(n->left->op == OINDEXMAP) {
2114 n = mkcall1(mapfn("mapassign1", n->left->left->type), T, init, 1911 n = mkcall1(mapfn("mapassign1", n->left->left->type), T, init,
2115 n->left->left, n->left->right, n->right); 1912 n->left->left, n->left->right, n->right);
2116 goto out; 1913 goto out;
2117 } 1914 }
2118 1915 »
2119 if(eqtype(lt, rt)) 1916 if(eqtype(lt, rt))
2120 goto out; 1917 goto out;
2121 1918 »·······
2122 » et = ifaceas(lt, rt, 0); 1919 » n->right = assignconv(r, lt, "assignment");
2123 » if(et != Inone) { 1920 » walkexpr(&n->right, init);
2124 » » n->right = ifacecvt(lt, r, et, init);
2125 » » goto out;
2126 » }
2127 1921
2128 out: 1922 out:
2129 ullmancalc(n); 1923 ullmancalc(n);
2130 return n; 1924 return n;
2131 } 1925 }
2132 1926
2133 /* 1927 /*
2134 * from ascompat[te] 1928 * from ascompat[te]
2135 * evaluating actual function arguments. 1929 * evaluating actual function arguments.
2136 * f(a,b) 1930 * f(a,b)
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
2285 n1->left = q->right; 2079 n1->left = q->right;
2286 r = list(r, q); 2080 r = list(r, q);
2287 break; 2081 break;
2288 } 2082 }
2289 } 2083 }
2290 } 2084 }
2291 } 2085 }
2292 return concat(all, r); 2086 return concat(all, r);
2293 } 2087 }
2294 2088
2295 NodeList*
2296 reorder4(NodeList *ll)
2297 {
2298 /*
2299 * from ascompat[te]
2300 * return c,d
2301 * return expression assigned to output
2302 * parameters. there may be no problems.
2303 *
2304 * TODO(rsc): i don't believe that.
2305 * func f() (a, b int) {
2306 * a, b = 1, 2;
2307 * return b, a;
2308 * }
2309 */
2310 return ll;
2311 }
2312
2313 /* 2089 /*
2314 * walk through argin parameters. 2090 * walk through argin parameters.
2315 * generate and return code to allocate 2091 * generate and return code to allocate
2316 * copies of escaped parameters to the heap. 2092 * copies of escaped parameters to the heap.
2317 */ 2093 */
2318 NodeList* 2094 NodeList*
2319 paramstoheap(Type **argin, int out) 2095 paramstoheap(Type **argin, int out)
2320 { 2096 {
2321 Type *t; 2097 Type *t;
2322 Iter savet; 2098 Iter savet;
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
2465 2241
2466 if(t->etype != TMAP) 2242 if(t->etype != TMAP)
2467 fatal("mapfn %T", t); 2243 fatal("mapfn %T", t);
2468 fn = syslook(name, 1); 2244 fn = syslook(name, 1);
2469 argtype(fn, t->down); 2245 argtype(fn, t->down);
2470 argtype(fn, t->type); 2246 argtype(fn, t->type);
2471 argtype(fn, t->down); 2247 argtype(fn, t->down);
2472 argtype(fn, t->type); 2248 argtype(fn, t->type);
2473 return fn; 2249 return fn;
2474 } 2250 }
OLDNEW
« no previous file with comments | « src/cmd/gc/typecheck.c ('k') | src/pkg/math/fltasm_amd64.s » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b