github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/src/cmd/gc/swt.c (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 #include <u.h> 6 #include <libc.h> 7 #include "go.h" 8 9 enum 10 { 11 Snorm = 0, 12 Strue, 13 Sfalse, 14 Stype, 15 16 Tdefault, // default case 17 Texprconst, // normal constant case 18 Texprvar, // normal variable case 19 Ttypenil, // case nil 20 Ttypeconst, // type hashes 21 Ttypevar, // interface type 22 23 Ncase = 4, // count needed to split 24 }; 25 26 typedef struct Case Case; 27 struct Case 28 { 29 Node* node; // points at case statement 30 uint32 hash; // hash of a type switch 31 uint8 type; // type of case 32 uint8 diag; // suppress multiple diagnostics 33 uint16 ordinal; // position in switch 34 Case* link; // linked list to link 35 }; 36 #define C ((Case*)nil) 37 38 void 39 dumpcase(Case *c0) 40 { 41 Case *c; 42 43 for(c=c0; c!=C; c=c->link) { 44 switch(c->type) { 45 case Tdefault: 46 print("case-default\n"); 47 print(" ord=%d\n", c->ordinal); 48 break; 49 case Texprconst: 50 print("case-exprconst\n"); 51 print(" ord=%d\n", c->ordinal); 52 break; 53 case Texprvar: 54 print("case-exprvar\n"); 55 print(" ord=%d\n", c->ordinal); 56 print(" op=%O\n", c->node->left->op); 57 break; 58 case Ttypenil: 59 print("case-typenil\n"); 60 print(" ord=%d\n", c->ordinal); 61 break; 62 case Ttypeconst: 63 print("case-typeconst\n"); 64 print(" ord=%d\n", c->ordinal); 65 print(" hash=%ux\n", c->hash); 66 break; 67 case Ttypevar: 68 print("case-typevar\n"); 69 print(" ord=%d\n", c->ordinal); 70 break; 71 default: 72 print("case-???\n"); 73 print(" ord=%d\n", c->ordinal); 74 print(" op=%O\n", c->node->left->op); 75 print(" hash=%ux\n", c->hash); 76 break; 77 } 78 } 79 print("\n"); 80 } 81 82 static int 83 ordlcmp(Case *c1, Case *c2) 84 { 85 // sort default first 86 if(c1->type == Tdefault) 87 return -1; 88 if(c2->type == Tdefault) 89 return +1; 90 91 // sort nil second 92 if(c1->type == Ttypenil) 93 return -1; 94 if(c2->type == Ttypenil) 95 return +1; 96 97 // sort by ordinal 98 if(c1->ordinal > c2->ordinal) 99 return +1; 100 if(c1->ordinal < c2->ordinal) 101 return -1; 102 return 0; 103 } 104 105 static int 106 exprcmp(Case *c1, Case *c2) 107 { 108 int ct, n; 109 Node *n1, *n2; 110 111 // sort non-constants last 112 if(c1->type != Texprconst) 113 return +1; 114 if(c2->type != Texprconst) 115 return -1; 116 117 n1 = c1->node->left; 118 n2 = c2->node->left; 119 120 // sort by type (for switches on interface) 121 ct = n1->val.ctype; 122 if(ct != n2->val.ctype) 123 return ct - n2->val.ctype; 124 if(!eqtype(n1->type, n2->type)) { 125 if(n1->type->vargen > n2->type->vargen) 126 return +1; 127 else 128 return -1; 129 } 130 131 // sort by constant value 132 n = 0; 133 switch(ct) { 134 case CTFLT: 135 n = mpcmpfltflt(n1->val.u.fval, n2->val.u.fval); 136 break; 137 case CTINT: 138 case CTRUNE: 139 n = mpcmpfixfix(n1->val.u.xval, n2->val.u.xval); 140 break; 141 case CTSTR: 142 n = cmpslit(n1, n2); 143 break; 144 } 145 146 return n; 147 } 148 149 static int 150 typecmp(Case *c1, Case *c2) 151 { 152 153 // sort non-constants last 154 if(c1->type != Ttypeconst) 155 return +1; 156 if(c2->type != Ttypeconst) 157 return -1; 158 159 // sort by hash code 160 if(c1->hash > c2->hash) 161 return +1; 162 if(c1->hash < c2->hash) 163 return -1; 164 165 // sort by ordinal so duplicate error 166 // happens on later case. 167 if(c1->ordinal > c2->ordinal) 168 return +1; 169 if(c1->ordinal < c2->ordinal) 170 return -1; 171 return 0; 172 } 173 174 static Case* 175 csort(Case *l, int(*f)(Case*, Case*)) 176 { 177 Case *l1, *l2, *le; 178 179 if(l == C || l->link == C) 180 return l; 181 182 l1 = l; 183 l2 = l; 184 for(;;) { 185 l2 = l2->link; 186 if(l2 == C) 187 break; 188 l2 = l2->link; 189 if(l2 == C) 190 break; 191 l1 = l1->link; 192 } 193 194 l2 = l1->link; 195 l1->link = C; 196 l1 = csort(l, f); 197 l2 = csort(l2, f); 198 199 /* set up lead element */ 200 if((*f)(l1, l2) < 0) { 201 l = l1; 202 l1 = l1->link; 203 } else { 204 l = l2; 205 l2 = l2->link; 206 } 207 le = l; 208 209 for(;;) { 210 if(l1 == C) { 211 while(l2) { 212 le->link = l2; 213 le = l2; 214 l2 = l2->link; 215 } 216 le->link = C; 217 break; 218 } 219 if(l2 == C) { 220 while(l1) { 221 le->link = l1; 222 le = l1; 223 l1 = l1->link; 224 } 225 break; 226 } 227 if((*f)(l1, l2) < 0) { 228 le->link = l1; 229 le = l1; 230 l1 = l1->link; 231 } else { 232 le->link = l2; 233 le = l2; 234 l2 = l2->link; 235 } 236 } 237 le->link = C; 238 return l; 239 } 240 241 static Node* 242 newlabel(void) 243 { 244 static int label; 245 246 label++; 247 snprint(namebuf, sizeof(namebuf), "%.6d", label); 248 return newname(lookup(namebuf)); 249 } 250 251 /* 252 * build separate list of statements and cases 253 * make labels between cases and statements 254 * deal with fallthrough, break, unreachable statements 255 */ 256 static void 257 casebody(Node *sw, Node *typeswvar) 258 { 259 Node *n, *c, *last; 260 Node *def; 261 NodeList *cas, *stat, *l, *lc; 262 Node *go, *br; 263 int32 lno, needvar; 264 265 if(sw->list == nil) 266 return; 267 268 lno = setlineno(sw); 269 270 cas = nil; // cases 271 stat = nil; // statements 272 def = N; // defaults 273 br = nod(OBREAK, N, N); 274 275 for(l=sw->list; l; l=l->next) { 276 n = l->n; 277 setlineno(n); 278 if(n->op != OXCASE) 279 fatal("casebody %O", n->op); 280 n->op = OCASE; 281 needvar = count(n->list) != 1 || n->list->n->op == OLITERAL; 282 283 go = nod(OGOTO, newlabel(), N); 284 if(n->list == nil) { 285 if(def != N) 286 yyerror("more than one default case"); 287 // reuse original default case 288 n->right = go; 289 def = n; 290 } 291 292 if(n->list != nil && n->list->next == nil) { 293 // one case - reuse OCASE node. 294 c = n->list->n; 295 n->left = c; 296 n->right = go; 297 n->list = nil; 298 cas = list(cas, n); 299 } else { 300 // expand multi-valued cases 301 for(lc=n->list; lc; lc=lc->next) { 302 c = lc->n; 303 cas = list(cas, nod(OCASE, c, go)); 304 } 305 } 306 307 stat = list(stat, nod(OLABEL, go->left, N)); 308 if(typeswvar && needvar && n->nname != N) { 309 NodeList *l; 310 311 l = list1(nod(ODCL, n->nname, N)); 312 l = list(l, nod(OAS, n->nname, typeswvar)); 313 typechecklist(l, Etop); 314 stat = concat(stat, l); 315 } 316 stat = concat(stat, n->nbody); 317 318 // botch - shouldn't fall thru declaration 319 last = stat->end->n; 320 if(last->xoffset == n->xoffset && last->op == OXFALL) { 321 if(typeswvar) { 322 setlineno(last); 323 yyerror("cannot fallthrough in type switch"); 324 } 325 if(l->next == nil) { 326 setlineno(last); 327 yyerror("cannot fallthrough final case in switch"); 328 } 329 last->op = OFALL; 330 } else 331 stat = list(stat, br); 332 } 333 334 stat = list(stat, br); 335 if(def) 336 cas = list(cas, def); 337 338 sw->list = cas; 339 sw->nbody = stat; 340 lineno = lno; 341 } 342 343 static Case* 344 mkcaselist(Node *sw, int arg) 345 { 346 Node *n; 347 Case *c, *c1, *c2; 348 NodeList *l; 349 int ord; 350 351 c = C; 352 ord = 0; 353 354 for(l=sw->list; l; l=l->next) { 355 n = l->n; 356 c1 = mal(sizeof(*c1)); 357 c1->link = c; 358 c = c1; 359 360 ord++; 361 if((uint16)ord != ord) 362 fatal("too many cases in switch"); 363 c->ordinal = ord; 364 c->node = n; 365 366 if(n->left == N) { 367 c->type = Tdefault; 368 continue; 369 } 370 371 switch(arg) { 372 case Stype: 373 c->hash = 0; 374 if(n->left->op == OLITERAL) { 375 c->type = Ttypenil; 376 continue; 377 } 378 if(istype(n->left->type, TINTER)) { 379 c->type = Ttypevar; 380 continue; 381 } 382 383 c->hash = typehash(n->left->type); 384 c->type = Ttypeconst; 385 continue; 386 387 case Snorm: 388 case Strue: 389 case Sfalse: 390 c->type = Texprvar; 391 c->hash = typehash(n->left->type); 392 switch(consttype(n->left)) { 393 case CTFLT: 394 case CTINT: 395 case CTRUNE: 396 case CTSTR: 397 c->type = Texprconst; 398 } 399 continue; 400 } 401 } 402 403 if(c == C) 404 return C; 405 406 // sort by value and diagnose duplicate cases 407 switch(arg) { 408 case Stype: 409 c = csort(c, typecmp); 410 for(c1=c; c1!=C; c1=c1->link) { 411 for(c2=c1->link; c2!=C && c2->hash==c1->hash; c2=c2->link) { 412 if(c1->type == Ttypenil || c1->type == Tdefault) 413 break; 414 if(c2->type == Ttypenil || c2->type == Tdefault) 415 break; 416 if(!eqtype(c1->node->left->type, c2->node->left->type)) 417 continue; 418 yyerrorl(c2->node->lineno, "duplicate case %T in type switch\n\tprevious case at %L", c2->node->left->type, c1->node->lineno); 419 } 420 } 421 break; 422 case Snorm: 423 case Strue: 424 case Sfalse: 425 c = csort(c, exprcmp); 426 for(c1=c; c1->link!=C; c1=c1->link) { 427 if(exprcmp(c1, c1->link) != 0) 428 continue; 429 setlineno(c1->link->node); 430 yyerror("duplicate case %N in switch\n\tprevious case at %L", c1->node->left, c1->node->lineno); 431 } 432 break; 433 } 434 435 // put list back in processing order 436 c = csort(c, ordlcmp); 437 return c; 438 } 439 440 static Node* exprname; 441 442 static Node* 443 exprbsw(Case *c0, int ncase, int arg) 444 { 445 NodeList *cas; 446 Node *a, *n; 447 Case *c; 448 int i, half, lno; 449 450 cas = nil; 451 if(ncase < Ncase) { 452 for(i=0; i<ncase; i++) { 453 n = c0->node; 454 lno = setlineno(n); 455 456 if(assignop(n->left->type, exprname->type, nil) == OCONVIFACE || 457 assignop(exprname->type, n->left->type, nil) == OCONVIFACE) 458 goto snorm; 459 460 switch(arg) { 461 case Strue: 462 a = nod(OIF, N, N); 463 a->ntest = n->left; // if val 464 a->nbody = list1(n->right); // then goto l 465 break; 466 467 case Sfalse: 468 a = nod(OIF, N, N); 469 a->ntest = nod(ONOT, n->left, N); // if !val 470 typecheck(&a->ntest, Erv); 471 a->nbody = list1(n->right); // then goto l 472 break; 473 474 default: 475 snorm: 476 a = nod(OIF, N, N); 477 a->ntest = nod(OEQ, exprname, n->left); // if name == val 478 typecheck(&a->ntest, Erv); 479 a->nbody = list1(n->right); // then goto l 480 break; 481 } 482 483 cas = list(cas, a); 484 c0 = c0->link; 485 lineno = lno; 486 } 487 return liststmt(cas); 488 } 489 490 // find the middle and recur 491 c = c0; 492 half = ncase>>1; 493 for(i=1; i<half; i++) 494 c = c->link; 495 a = nod(OIF, N, N); 496 a->ntest = nod(OLE, exprname, c->node->left); 497 typecheck(&a->ntest, Erv); 498 a->nbody = list1(exprbsw(c0, half, arg)); 499 a->nelse = list1(exprbsw(c->link, ncase-half, arg)); 500 return a; 501 } 502 503 /* 504 * normal (expression) switch. 505 * rebulid case statements into if .. goto 506 */ 507 static void 508 exprswitch(Node *sw) 509 { 510 Node *def; 511 NodeList *cas; 512 Node *a; 513 Case *c0, *c, *c1; 514 Type *t; 515 int arg, ncase; 516 517 casebody(sw, N); 518 519 arg = Snorm; 520 if(isconst(sw->ntest, CTBOOL)) { 521 arg = Strue; 522 if(sw->ntest->val.u.bval == 0) 523 arg = Sfalse; 524 } 525 walkexpr(&sw->ntest, &sw->ninit); 526 t = sw->type; 527 if(t == T) 528 return; 529 530 /* 531 * convert the switch into OIF statements 532 */ 533 exprname = N; 534 cas = nil; 535 if(arg != Strue && arg != Sfalse) { 536 exprname = temp(sw->ntest->type); 537 cas = list1(nod(OAS, exprname, sw->ntest)); 538 typechecklist(cas, Etop); 539 } else { 540 exprname = nodbool(arg == Strue); 541 } 542 543 c0 = mkcaselist(sw, arg); 544 if(c0 != C && c0->type == Tdefault) { 545 def = c0->node->right; 546 c0 = c0->link; 547 } else { 548 def = nod(OBREAK, N, N); 549 } 550 551 loop: 552 if(c0 == C) { 553 cas = list(cas, def); 554 sw->nbody = concat(cas, sw->nbody); 555 sw->list = nil; 556 walkstmtlist(sw->nbody); 557 return; 558 } 559 560 // deal with the variables one-at-a-time 561 if(!okforcmp[t->etype] || c0->type != Texprconst) { 562 a = exprbsw(c0, 1, arg); 563 cas = list(cas, a); 564 c0 = c0->link; 565 goto loop; 566 } 567 568 // do binary search on run of constants 569 ncase = 1; 570 for(c=c0; c->link!=C; c=c->link) { 571 if(c->link->type != Texprconst) 572 break; 573 ncase++; 574 } 575 576 // break the chain at the count 577 c1 = c->link; 578 c->link = C; 579 580 // sort and compile constants 581 c0 = csort(c0, exprcmp); 582 a = exprbsw(c0, ncase, arg); 583 cas = list(cas, a); 584 585 c0 = c1; 586 goto loop; 587 588 } 589 590 static Node* hashname; 591 static Node* facename; 592 static Node* boolname; 593 594 static Node* 595 typeone(Node *t) 596 { 597 NodeList *init; 598 Node *a, *b, *var; 599 600 var = t->nname; 601 init = nil; 602 if(var == N) { 603 typecheck(&nblank, Erv | Easgn); 604 var = nblank; 605 } else 606 init = list1(nod(ODCL, var, N)); 607 608 a = nod(OAS2, N, N); 609 a->list = list(list1(var), boolname); // var,bool = 610 b = nod(ODOTTYPE, facename, N); 611 b->type = t->left->type; // interface.(type) 612 a->rlist = list1(b); 613 typecheck(&a, Etop); 614 init = list(init, a); 615 616 b = nod(OIF, N, N); 617 b->ntest = boolname; 618 b->nbody = list1(t->right); // if bool { goto l } 619 a = liststmt(list(init, b)); 620 return a; 621 } 622 623 static Node* 624 typebsw(Case *c0, int ncase) 625 { 626 NodeList *cas; 627 Node *a, *n; 628 Case *c; 629 int i, half; 630 631 cas = nil; 632 633 if(ncase < Ncase) { 634 for(i=0; i<ncase; i++) { 635 n = c0->node; 636 if(c0->type != Ttypeconst) 637 fatal("typebsw"); 638 a = nod(OIF, N, N); 639 a->ntest = nod(OEQ, hashname, nodintconst(c0->hash)); 640 typecheck(&a->ntest, Erv); 641 a->nbody = list1(n->right); 642 cas = list(cas, a); 643 c0 = c0->link; 644 } 645 return liststmt(cas); 646 } 647 648 // find the middle and recur 649 c = c0; 650 half = ncase>>1; 651 for(i=1; i<half; i++) 652 c = c->link; 653 a = nod(OIF, N, N); 654 a->ntest = nod(OLE, hashname, nodintconst(c->hash)); 655 typecheck(&a->ntest, Erv); 656 a->nbody = list1(typebsw(c0, half)); 657 a->nelse = list1(typebsw(c->link, ncase-half)); 658 return a; 659 } 660 661 /* 662 * convert switch of the form 663 * switch v := i.(type) { case t1: ..; case t2: ..; } 664 * into if statements 665 */ 666 static void 667 typeswitch(Node *sw) 668 { 669 Node *def; 670 NodeList *cas, *hash; 671 Node *a, *n; 672 Case *c, *c0, *c1; 673 int ncase; 674 Type *t; 675 Val v; 676 677 if(sw->ntest == nil) 678 return; 679 if(sw->ntest->right == nil) { 680 setlineno(sw); 681 yyerror("type switch must have an assignment"); 682 return; 683 } 684 walkexpr(&sw->ntest->right, &sw->ninit); 685 if(!istype(sw->ntest->right->type, TINTER)) { 686 yyerror("type switch must be on an interface"); 687 return; 688 } 689 cas = nil; 690 691 /* 692 * predeclare temporary variables 693 * and the boolean var 694 */ 695 facename = temp(sw->ntest->right->type); 696 a = nod(OAS, facename, sw->ntest->right); 697 typecheck(&a, Etop); 698 cas = list(cas, a); 699 700 casebody(sw, facename); 701 702 boolname = temp(types[TBOOL]); 703 typecheck(&boolname, Erv); 704 705 hashname = temp(types[TUINT32]); 706 typecheck(&hashname, Erv); 707 708 t = sw->ntest->right->type; 709 if(isnilinter(t)) 710 a = syslook("efacethash", 1); 711 else 712 a = syslook("ifacethash", 1); 713 argtype(a, t); 714 a = nod(OCALL, a, N); 715 a->list = list1(facename); 716 a = nod(OAS, hashname, a); 717 typecheck(&a, Etop); 718 cas = list(cas, a); 719 720 c0 = mkcaselist(sw, Stype); 721 if(c0 != C && c0->type == Tdefault) { 722 def = c0->node->right; 723 c0 = c0->link; 724 } else { 725 def = nod(OBREAK, N, N); 726 } 727 728 /* 729 * insert if statement into each case block 730 */ 731 for(c=c0; c!=C; c=c->link) { 732 n = c->node; 733 switch(c->type) { 734 735 case Ttypenil: 736 v.ctype = CTNIL; 737 a = nod(OIF, N, N); 738 a->ntest = nod(OEQ, facename, nodlit(v)); 739 typecheck(&a->ntest, Erv); 740 a->nbody = list1(n->right); // if i==nil { goto l } 741 n->right = a; 742 break; 743 744 case Ttypevar: 745 case Ttypeconst: 746 n->right = typeone(n); 747 break; 748 } 749 } 750 751 /* 752 * generate list of if statements, binary search for constant sequences 753 */ 754 while(c0 != C) { 755 if(c0->type != Ttypeconst) { 756 n = c0->node; 757 cas = list(cas, n->right); 758 c0=c0->link; 759 continue; 760 } 761 762 // identify run of constants 763 c1 = c = c0; 764 while(c->link!=C && c->link->type==Ttypeconst) 765 c = c->link; 766 c0 = c->link; 767 c->link = nil; 768 769 // sort by hash 770 c1 = csort(c1, typecmp); 771 772 // for debugging: linear search 773 if(0) { 774 for(c=c1; c!=C; c=c->link) { 775 n = c->node; 776 cas = list(cas, n->right); 777 } 778 continue; 779 } 780 781 // combine adjacent cases with the same hash 782 ncase = 0; 783 for(c=c1; c!=C; c=c->link) { 784 ncase++; 785 hash = list1(c->node->right); 786 while(c->link != C && c->link->hash == c->hash) { 787 hash = list(hash, c->link->node->right); 788 c->link = c->link->link; 789 } 790 c->node->right = liststmt(hash); 791 } 792 793 // binary search among cases to narrow by hash 794 cas = list(cas, typebsw(c1, ncase)); 795 } 796 if(nerrors == 0) { 797 cas = list(cas, def); 798 sw->nbody = concat(cas, sw->nbody); 799 sw->list = nil; 800 walkstmtlist(sw->nbody); 801 } 802 } 803 804 void 805 walkswitch(Node *sw) 806 { 807 /* 808 * reorder the body into (OLIST, cases, statements) 809 * cases have OGOTO into statements. 810 * both have inserted OBREAK statements 811 */ 812 if(sw->ntest == N) { 813 sw->ntest = nodbool(1); 814 typecheck(&sw->ntest, Erv); 815 } 816 817 if(sw->ntest->op == OTYPESW) { 818 typeswitch(sw); 819 //dump("sw", sw); 820 return; 821 } 822 exprswitch(sw); 823 // Discard old AST elements after a walk. They can confuse racewealk. 824 sw->ntest = nil; 825 sw->list = nil; 826 } 827 828 /* 829 * type check switch statement 830 */ 831 void 832 typecheckswitch(Node *n) 833 { 834 int top, lno, ptr; 835 char *nilonly; 836 Type *t, *badtype, *missing, *have; 837 NodeList *l, *ll; 838 Node *ncase, *nvar; 839 Node *def; 840 841 lno = lineno; 842 typechecklist(n->ninit, Etop); 843 nilonly = nil; 844 845 if(n->ntest != N && n->ntest->op == OTYPESW) { 846 // type switch 847 top = Etype; 848 typecheck(&n->ntest->right, Erv); 849 t = n->ntest->right->type; 850 if(t != T && t->etype != TINTER) 851 yyerror("cannot type switch on non-interface value %lN", n->ntest->right); 852 } else { 853 // value switch 854 top = Erv; 855 if(n->ntest) { 856 typecheck(&n->ntest, Erv); 857 defaultlit(&n->ntest, T); 858 t = n->ntest->type; 859 } else 860 t = types[TBOOL]; 861 if(t) { 862 if(!okforeq[t->etype]) 863 yyerror("cannot switch on %lN", n->ntest); 864 else if(t->etype == TARRAY && !isfixedarray(t)) 865 nilonly = "slice"; 866 else if(t->etype == TARRAY && isfixedarray(t) && algtype1(t, nil) == ANOEQ) 867 yyerror("cannot switch on %lN", n->ntest); 868 else if(t->etype == TSTRUCT && algtype1(t, &badtype) == ANOEQ) 869 yyerror("cannot switch on %lN (struct containing %T cannot be compared)", n->ntest, badtype); 870 else if(t->etype == TFUNC) 871 nilonly = "func"; 872 else if(t->etype == TMAP) 873 nilonly = "map"; 874 } 875 } 876 n->type = t; 877 878 def = N; 879 for(l=n->list; l; l=l->next) { 880 ncase = l->n; 881 setlineno(n); 882 if(ncase->list == nil) { 883 // default 884 if(def != N) 885 yyerror("multiple defaults in switch (first at %L)", def->lineno); 886 else 887 def = ncase; 888 } else { 889 for(ll=ncase->list; ll; ll=ll->next) { 890 setlineno(ll->n); 891 typecheck(&ll->n, Erv | Etype); 892 if(ll->n->type == T || t == T) 893 continue; 894 setlineno(ncase); 895 switch(top) { 896 case Erv: // expression switch 897 defaultlit(&ll->n, t); 898 if(ll->n->op == OTYPE) 899 yyerror("type %T is not an expression", ll->n->type); 900 else if(ll->n->type != T && !assignop(ll->n->type, t, nil) && !assignop(t, ll->n->type, nil)) { 901 if(n->ntest) 902 yyerror("invalid case %N in switch on %N (mismatched types %T and %T)", ll->n, n->ntest, ll->n->type, t); 903 else 904 yyerror("invalid case %N in switch (mismatched types %T and bool)", ll->n, ll->n->type); 905 } else if(nilonly && !isconst(ll->n, CTNIL)) { 906 yyerror("invalid case %N in switch (can only compare %s %N to nil)", ll->n, nilonly, n->ntest); 907 } 908 break; 909 case Etype: // type switch 910 if(ll->n->op == OLITERAL && istype(ll->n->type, TNIL)) { 911 ; 912 } else if(ll->n->op != OTYPE && ll->n->type != T) { // should this be ||? 913 yyerror("%lN is not a type", ll->n); 914 // reset to original type 915 ll->n = n->ntest->right; 916 } else if(ll->n->type->etype != TINTER && t->etype == TINTER && !implements(ll->n->type, t, &missing, &have, &ptr)) { 917 if(have && !missing->broke && !have->broke) 918 yyerror("impossible type switch case: %lN cannot have dynamic type %T" 919 " (wrong type for %S method)\n\thave %S%hT\n\twant %S%hT", 920 n->ntest->right, ll->n->type, missing->sym, have->sym, have->type, 921 missing->sym, missing->type); 922 else if(!missing->broke) 923 yyerror("impossible type switch case: %lN cannot have dynamic type %T" 924 " (missing %S method)", n->ntest->right, ll->n->type, missing->sym); 925 } 926 break; 927 } 928 } 929 } 930 if(top == Etype && n->type != T) { 931 ll = ncase->list; 932 nvar = ncase->nname; 933 if(nvar != N) { 934 if(ll && ll->next == nil && ll->n->type != T && !istype(ll->n->type, TNIL)) { 935 // single entry type switch 936 nvar->ntype = typenod(ll->n->type); 937 } else { 938 // multiple entry type switch or default 939 nvar->ntype = typenod(n->type); 940 } 941 } 942 } 943 typechecklist(ncase->nbody, Etop); 944 } 945 946 lineno = lno; 947 }