Commit ecab408c authored by Russ Cox's avatar Russ Cox

cmd/gc: implement new return requirements

Fixes #65.

R=ken2
CC=golang-dev
https://golang.org/cl/7441049
parent 9905cec0
......@@ -268,6 +268,7 @@ struct Node
uchar addrtaken; // address taken, even if not moved to heap
uchar dupok; // duplicate definitions ok (for func)
schar likely; // likeliness of if statement
uchar hasbreak; // has break statement
// most nodes
Type* type;
......@@ -1363,6 +1364,7 @@ Node* typecheck(Node **np, int top);
void typechecklist(NodeList *l, int top);
Node* typecheckdef(Node *n);
void copytype(Node *n, Type *t);
void checkreturn(Node*);
void queuemethod(Node *n);
/*
......
......@@ -536,7 +536,10 @@ compound_stmt:
}
stmt_list '}'
{
$$ = liststmt($3);
if($3 == nil)
$$ = nod(OEMPTY, N, N);
else
$$ = liststmt($3);
popdcl();
}
......
......@@ -376,6 +376,7 @@ main(int argc, char *argv[])
curfn = l->n;
saveerrors();
typechecklist(l->n->nbody, Etop);
checkreturn(l->n);
if(nerrors != 0)
l->n->nbody = nil; // type errors; do not compile
}
......
......@@ -3144,3 +3144,148 @@ checkmake(Type *t, char *arg, Node *n)
}
return 0;
}
static void markbreaklist(NodeList*, Node*);
static void
markbreak(Node *n, Node *implicit)
{
Label *lab;
if(n == N)
return;
switch(n->op) {
case OBREAK:
if(n->left == N) {
if(implicit)
implicit->hasbreak = 1;
} else {
lab = n->left->sym->label;
if(lab != L)
lab->def->hasbreak = 1;
}
break;
case OFOR:
case OSWITCH:
case OTYPESW:
case OSELECT:
case ORANGE:
implicit = n;
// fall through
default:
markbreak(n->left, implicit);
markbreak(n->right, implicit);
markbreak(n->ntest, implicit);
markbreak(n->nincr, implicit);
markbreaklist(n->ninit, implicit);
markbreaklist(n->nbody, implicit);
markbreaklist(n->nelse, implicit);
markbreaklist(n->list, implicit);
markbreaklist(n->rlist, implicit);
break;
}
}
static void
markbreaklist(NodeList *l, Node *implicit)
{
Node *n;
Label *lab;
for(; l; l=l->next) {
n = l->n;
if(n->op == OLABEL && l->next && n->defn == l->next->n) {
switch(n->defn->op) {
case OFOR:
case OSWITCH:
case OTYPESW:
case OSELECT:
case ORANGE:
lab = mal(sizeof *lab);
lab->def = n->defn;
n->left->sym->label = lab;
markbreak(n->defn, n->defn);
n->left->sym->label = L;
l = l->next;
continue;
}
}
markbreak(n, implicit);
}
}
static int
isterminating(NodeList *l, int top)
{
int def;
Node *n;
if(l == nil)
return 0;
if(top) {
while(l->next && l->n->op != OLABEL)
l = l->next;
markbreaklist(l, nil);
}
while(l->next)
l = l->next;
n = l->n;
if(n == N)
return 0;
switch(n->op) {
// NOTE: OLABEL is treated as a separate statement,
// not a separate prefix, so skipping to the last statement
// in the block handles the labeled statement case by
// skipping over the label. No case OLABEL here.
case OBLOCK:
return isterminating(n->list, 0);
case OGOTO:
case ORETURN:
case OPANIC:
case OXFALL:
return 1;
case OFOR:
if(n->ntest != N)
return 0;
if(n->hasbreak)
return 0;
return 1;
case OIF:
return isterminating(n->nbody, 0) && isterminating(n->nelse, 0);
case OSWITCH:
case OTYPESW:
case OSELECT:
if(n->hasbreak)
return 0;
def = 0;
for(l=n->list; l; l=l->next) {
if(!isterminating(l->n->nbody, 0))
return 0;
if(l->n->list == nil) // default
def = 1;
}
if(n->op != OSELECT && !def)
return 0;
return 1;
}
return 0;
}
void
checkreturn(Node *fn)
{
if(fn->type->outtuple && fn->nbody != nil)
if(!isterminating(fn->nbody, 1))
yyerrorl(fn->endlineno, "missing return at end of function");
}
......@@ -29,40 +29,6 @@ static void walkdiv(Node**, NodeList**);
static int bounded(Node*, int64);
static Mpint mpzero;
// can this code branch reach the end
// without an unconditional RETURN
// this is hard, so it is conservative
static int
walkret(NodeList *l)
{
Node *n;
loop:
while(l && l->next)
l = l->next;
if(l == nil)
return 1;
// at this point, we have the last
// statement of the function
n = l->n;
switch(n->op) {
case OBLOCK:
l = n->list;
goto loop;
case OGOTO:
case ORETURN:
case OPANIC:
return 0;
break;
}
// all other statements
// will flow to the end
return 1;
}
void
walk(Node *fn)
{
......@@ -76,9 +42,6 @@ walk(Node *fn)
snprint(s, sizeof(s), "\nbefore %S", curfn->nname->sym);
dumplist(s, curfn->nbody);
}
if(curfn->type->outtuple)
if(walkret(curfn->nbody))
yyerror("function ends without a return statement");
lno = lineno;
......
......@@ -662,35 +662,35 @@ static const yytype_uint16 yyrline[] =
304, 308, 312, 318, 324, 330, 335, 339, 343, 349,
355, 359, 363, 369, 373, 379, 380, 384, 390, 399,
405, 423, 428, 440, 456, 461, 468, 488, 506, 515,
534, 533, 545, 544, 575, 578, 585, 584, 595, 601,
610, 621, 627, 630, 638, 637, 648, 654, 666, 670,
675, 665, 696, 695, 708, 711, 717, 720, 732, 736,
731, 754, 753, 769, 770, 774, 778, 782, 786, 790,
794, 798, 802, 806, 810, 814, 818, 822, 826, 830,
834, 838, 842, 847, 853, 854, 858, 869, 873, 877,
881, 886, 890, 900, 904, 909, 917, 921, 922, 933,
937, 941, 945, 949, 950, 956, 963, 969, 976, 979,
986, 992, 1009, 1016, 1017, 1024, 1025, 1044, 1045, 1048,
1051, 1055, 1066, 1075, 1081, 1084, 1087, 1094, 1095, 1101,
1116, 1124, 1136, 1141, 1147, 1148, 1149, 1150, 1151, 1152,
1158, 1159, 1160, 1161, 1167, 1168, 1169, 1170, 1171, 1177,
1178, 1181, 1184, 1185, 1186, 1187, 1188, 1191, 1192, 1205,
1209, 1214, 1219, 1224, 1228, 1229, 1232, 1238, 1245, 1251,
1258, 1264, 1275, 1289, 1318, 1358, 1383, 1401, 1410, 1413,
1421, 1425, 1429, 1436, 1442, 1447, 1459, 1462, 1472, 1473,
1479, 1480, 1486, 1490, 1496, 1497, 1503, 1507, 1513, 1536,
1541, 1547, 1553, 1560, 1569, 1578, 1593, 1599, 1604, 1608,
1615, 1628, 1629, 1635, 1641, 1644, 1648, 1654, 1657, 1666,
1669, 1670, 1674, 1675, 1681, 1682, 1683, 1684, 1685, 1687,
1686, 1701, 1706, 1710, 1714, 1718, 1722, 1727, 1746, 1752,
1760, 1764, 1770, 1774, 1780, 1784, 1790, 1794, 1803, 1807,
1811, 1815, 1821, 1824, 1832, 1833, 1835, 1836, 1839, 1842,
1845, 1848, 1851, 1854, 1857, 1860, 1863, 1866, 1869, 1872,
1875, 1878, 1884, 1888, 1892, 1896, 1900, 1904, 1924, 1931,
1942, 1943, 1944, 1947, 1948, 1951, 1955, 1965, 1969, 1973,
1977, 1981, 1985, 1989, 1995, 2001, 2009, 2017, 2023, 2030,
2046, 2064, 2068, 2074, 2077, 2080, 2084, 2094, 2098, 2113,
2121, 2122, 2134, 2135, 2138, 2142, 2148, 2152, 2158, 2162
534, 533, 548, 547, 578, 581, 588, 587, 598, 604,
613, 624, 630, 633, 641, 640, 651, 657, 669, 673,
678, 668, 699, 698, 711, 714, 720, 723, 735, 739,
734, 757, 756, 772, 773, 777, 781, 785, 789, 793,
797, 801, 805, 809, 813, 817, 821, 825, 829, 833,
837, 841, 845, 850, 856, 857, 861, 872, 876, 880,
884, 889, 893, 903, 907, 912, 920, 924, 925, 936,
940, 944, 948, 952, 953, 959, 966, 972, 979, 982,
989, 995, 1012, 1019, 1020, 1027, 1028, 1047, 1048, 1051,
1054, 1058, 1069, 1078, 1084, 1087, 1090, 1097, 1098, 1104,
1119, 1127, 1139, 1144, 1150, 1151, 1152, 1153, 1154, 1155,
1161, 1162, 1163, 1164, 1170, 1171, 1172, 1173, 1174, 1180,
1181, 1184, 1187, 1188, 1189, 1190, 1191, 1194, 1195, 1208,
1212, 1217, 1222, 1227, 1231, 1232, 1235, 1241, 1248, 1254,
1261, 1267, 1278, 1292, 1321, 1361, 1386, 1404, 1413, 1416,
1424, 1428, 1432, 1439, 1445, 1450, 1462, 1465, 1475, 1476,
1482, 1483, 1489, 1493, 1499, 1500, 1506, 1510, 1516, 1539,
1544, 1550, 1556, 1563, 1572, 1581, 1596, 1602, 1607, 1611,
1618, 1631, 1632, 1638, 1644, 1647, 1651, 1657, 1660, 1669,
1672, 1673, 1677, 1678, 1684, 1685, 1686, 1687, 1688, 1690,
1689, 1704, 1709, 1713, 1717, 1721, 1725, 1730, 1749, 1755,
1763, 1767, 1773, 1777, 1783, 1787, 1793, 1797, 1806, 1810,
1814, 1818, 1824, 1827, 1835, 1836, 1838, 1839, 1842, 1845,
1848, 1851, 1854, 1857, 1860, 1863, 1866, 1869, 1872, 1875,
1878, 1881, 1887, 1891, 1895, 1899, 1903, 1907, 1927, 1934,
1945, 1946, 1947, 1950, 1951, 1954, 1958, 1968, 1972, 1976,
1980, 1984, 1988, 1992, 1998, 2004, 2012, 2020, 2026, 2033,
2049, 2067, 2071, 2077, 2080, 2083, 2087, 2097, 2101, 2116,
2124, 2125, 2137, 2138, 2141, 2145, 2151, 2155, 2161, 2165
};
#endif
......@@ -2867,13 +2867,16 @@ yyreduce:
case 61:
#line 538 "go.y"
{
(yyval.node) = liststmt((yyvsp[(3) - (4)].list));
if((yyvsp[(3) - (4)].list) == nil)
(yyval.node) = nod(OEMPTY, N, N);
else
(yyval.node) = liststmt((yyvsp[(3) - (4)].list));
popdcl();
}
break;
case 62:
#line 545 "go.y"
#line 548 "go.y"
{
// If the last token read by the lexer was consumed
// as part of the case, clear it (parser has cleared yychar).
......@@ -2886,7 +2889,7 @@ yyreduce:
break;
case 63:
#line 555 "go.y"
#line 558 "go.y"
{
int last;
......@@ -2908,28 +2911,28 @@ yyreduce:
break;
case 64:
#line 575 "go.y"
#line 578 "go.y"
{
(yyval.list) = nil;
}
break;
case 65:
#line 579 "go.y"
#line 582 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node));
}
break;
case 66:
#line 585 "go.y"
#line 588 "go.y"
{
markdcl();
}
break;
case 67:
#line 589 "go.y"
#line 592 "go.y"
{
(yyval.list) = (yyvsp[(3) - (4)].list);
popdcl();
......@@ -2937,7 +2940,7 @@ yyreduce:
break;
case 68:
#line 596 "go.y"
#line 599 "go.y"
{
(yyval.node) = nod(ORANGE, N, (yyvsp[(4) - (4)].node));
(yyval.node)->list = (yyvsp[(1) - (4)].list);
......@@ -2946,7 +2949,7 @@ yyreduce:
break;
case 69:
#line 602 "go.y"
#line 605 "go.y"
{
(yyval.node) = nod(ORANGE, N, (yyvsp[(4) - (4)].node));
(yyval.node)->list = (yyvsp[(1) - (4)].list);
......@@ -2956,7 +2959,7 @@ yyreduce:
break;
case 70:
#line 611 "go.y"
#line 614 "go.y"
{
// init ; test ; incr
if((yyvsp[(5) - (5)].node) != N && (yyvsp[(5) - (5)].node)->colas != 0)
......@@ -2970,7 +2973,7 @@ yyreduce:
break;
case 71:
#line 622 "go.y"
#line 625 "go.y"
{
// normal test
(yyval.node) = nod(OFOR, N, N);
......@@ -2979,7 +2982,7 @@ yyreduce:
break;
case 73:
#line 631 "go.y"
#line 634 "go.y"
{
(yyval.node) = (yyvsp[(1) - (2)].node);
(yyval.node)->nbody = concat((yyval.node)->nbody, (yyvsp[(2) - (2)].list));
......@@ -2987,14 +2990,14 @@ yyreduce:
break;
case 74:
#line 638 "go.y"
#line 641 "go.y"
{
markdcl();
}
break;
case 75:
#line 642 "go.y"
#line 645 "go.y"
{
(yyval.node) = (yyvsp[(3) - (3)].node);
popdcl();
......@@ -3002,7 +3005,7 @@ yyreduce:
break;
case 76:
#line 649 "go.y"
#line 652 "go.y"
{
// test
(yyval.node) = nod(OIF, N, N);
......@@ -3011,7 +3014,7 @@ yyreduce:
break;
case 77:
#line 655 "go.y"
#line 658 "go.y"
{
// init ; test
(yyval.node) = nod(OIF, N, N);
......@@ -3022,14 +3025,14 @@ yyreduce:
break;
case 78:
#line 666 "go.y"
#line 669 "go.y"
{
markdcl();
}
break;
case 79:
#line 670 "go.y"
#line 673 "go.y"
{
if((yyvsp[(3) - (3)].node)->ntest == N)
yyerror("missing condition in if statement");
......@@ -3037,14 +3040,14 @@ yyreduce:
break;
case 80:
#line 675 "go.y"
#line 678 "go.y"
{
(yyvsp[(3) - (5)].node)->nbody = (yyvsp[(5) - (5)].list);
}
break;
case 81:
#line 679 "go.y"
#line 682 "go.y"
{
Node *n;
NodeList *nn;
......@@ -3062,14 +3065,14 @@ yyreduce:
break;
case 82:
#line 696 "go.y"
#line 699 "go.y"
{
markdcl();
}
break;
case 83:
#line 700 "go.y"
#line 703 "go.y"
{
if((yyvsp[(4) - (5)].node)->ntest == N)
yyerror("missing condition in if statement");
......@@ -3079,28 +3082,28 @@ yyreduce:
break;
case 84:
#line 708 "go.y"
#line 711 "go.y"
{
(yyval.list) = nil;
}
break;
case 85:
#line 712 "go.y"
#line 715 "go.y"
{
(yyval.list) = concat((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].list));
}
break;
case 86:
#line 717 "go.y"
#line 720 "go.y"
{
(yyval.list) = nil;
}
break;
case 87:
#line 721 "go.y"
#line 724 "go.y"
{
NodeList *node;
......@@ -3112,14 +3115,14 @@ yyreduce:
break;
case 88:
#line 732 "go.y"
#line 735 "go.y"
{
markdcl();
}
break;
case 89:
#line 736 "go.y"
#line 739 "go.y"
{
Node *n;
n = (yyvsp[(3) - (3)].node)->ntest;
......@@ -3130,7 +3133,7 @@ yyreduce:
break;
case 90:
#line 744 "go.y"
#line 747 "go.y"
{
(yyval.node) = (yyvsp[(3) - (7)].node);
(yyval.node)->op = OSWITCH;
......@@ -3141,14 +3144,14 @@ yyreduce:
break;
case 91:
#line 754 "go.y"
#line 757 "go.y"
{
typesw = nod(OXXX, typesw, N);
}
break;
case 92:
#line 758 "go.y"
#line 761 "go.y"
{
(yyval.node) = nod(OSELECT, N, N);
(yyval.node)->lineno = typesw->lineno;
......@@ -3158,154 +3161,154 @@ yyreduce:
break;
case 94:
#line 771 "go.y"
#line 774 "go.y"
{
(yyval.node) = nod(OOROR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 95:
#line 775 "go.y"
#line 778 "go.y"
{
(yyval.node) = nod(OANDAND, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 96:
#line 779 "go.y"
#line 782 "go.y"
{
(yyval.node) = nod(OEQ, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 97:
#line 783 "go.y"
#line 786 "go.y"
{
(yyval.node) = nod(ONE, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 98:
#line 787 "go.y"
#line 790 "go.y"
{
(yyval.node) = nod(OLT, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 99:
#line 791 "go.y"
#line 794 "go.y"
{
(yyval.node) = nod(OLE, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 100:
#line 795 "go.y"
#line 798 "go.y"
{
(yyval.node) = nod(OGE, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 101:
#line 799 "go.y"
#line 802 "go.y"
{
(yyval.node) = nod(OGT, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 102:
#line 803 "go.y"
#line 806 "go.y"
{
(yyval.node) = nod(OADD, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 103:
#line 807 "go.y"
#line 810 "go.y"
{
(yyval.node) = nod(OSUB, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 104:
#line 811 "go.y"
#line 814 "go.y"
{
(yyval.node) = nod(OOR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 105:
#line 815 "go.y"
#line 818 "go.y"
{
(yyval.node) = nod(OXOR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 106:
#line 819 "go.y"
#line 822 "go.y"
{
(yyval.node) = nod(OMUL, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 107:
#line 823 "go.y"
#line 826 "go.y"
{
(yyval.node) = nod(ODIV, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 108:
#line 827 "go.y"
#line 830 "go.y"
{
(yyval.node) = nod(OMOD, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 109:
#line 831 "go.y"
#line 834 "go.y"
{
(yyval.node) = nod(OAND, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 110:
#line 835 "go.y"
#line 838 "go.y"
{
(yyval.node) = nod(OANDNOT, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 111:
#line 839 "go.y"
#line 842 "go.y"
{
(yyval.node) = nod(OLSH, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 112:
#line 843 "go.y"
#line 846 "go.y"
{
(yyval.node) = nod(ORSH, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 113:
#line 848 "go.y"
#line 851 "go.y"
{
(yyval.node) = nod(OSEND, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 115:
#line 855 "go.y"
#line 858 "go.y"
{
(yyval.node) = nod(OIND, (yyvsp[(2) - (2)].node), N);
}
break;
case 116:
#line 859 "go.y"
#line 862 "go.y"
{
if((yyvsp[(2) - (2)].node)->op == OCOMPLIT) {
// Special case for &T{...}: turn into (*T){...}.
......@@ -3319,28 +3322,28 @@ yyreduce:
break;
case 117:
#line 870 "go.y"
#line 873 "go.y"
{
(yyval.node) = nod(OPLUS, (yyvsp[(2) - (2)].node), N);
}
break;
case 118:
#line 874 "go.y"
#line 877 "go.y"
{
(yyval.node) = nod(OMINUS, (yyvsp[(2) - (2)].node), N);
}
break;
case 119:
#line 878 "go.y"
#line 881 "go.y"
{
(yyval.node) = nod(ONOT, (yyvsp[(2) - (2)].node), N);
}
break;
case 120:
#line 882 "go.y"
#line 885 "go.y"
{
yyerror("the bitwise complement operator is ^");
(yyval.node) = nod(OCOM, (yyvsp[(2) - (2)].node), N);
......@@ -3348,28 +3351,28 @@ yyreduce:
break;
case 121:
#line 887 "go.y"
#line 890 "go.y"
{
(yyval.node) = nod(OCOM, (yyvsp[(2) - (2)].node), N);
}
break;
case 122:
#line 891 "go.y"
#line 894 "go.y"
{
(yyval.node) = nod(ORECV, (yyvsp[(2) - (2)].node), N);
}
break;
case 123:
#line 901 "go.y"
#line 904 "go.y"
{
(yyval.node) = nod(OCALL, (yyvsp[(1) - (3)].node), N);
}
break;
case 124:
#line 905 "go.y"
#line 908 "go.y"
{
(yyval.node) = nod(OCALL, (yyvsp[(1) - (5)].node), N);
(yyval.node)->list = (yyvsp[(3) - (5)].list);
......@@ -3377,7 +3380,7 @@ yyreduce:
break;
case 125:
#line 910 "go.y"
#line 913 "go.y"
{
(yyval.node) = nod(OCALL, (yyvsp[(1) - (6)].node), N);
(yyval.node)->list = (yyvsp[(3) - (6)].list);
......@@ -3386,14 +3389,14 @@ yyreduce:
break;
case 126:
#line 918 "go.y"
#line 921 "go.y"
{
(yyval.node) = nodlit((yyvsp[(1) - (1)].val));
}
break;
case 128:
#line 923 "go.y"
#line 926 "go.y"
{
if((yyvsp[(1) - (3)].node)->op == OPACK) {
Sym *s;
......@@ -3407,35 +3410,35 @@ yyreduce:
break;
case 129:
#line 934 "go.y"
#line 937 "go.y"
{
(yyval.node) = nod(ODOTTYPE, (yyvsp[(1) - (5)].node), (yyvsp[(4) - (5)].node));
}
break;
case 130:
#line 938 "go.y"
#line 941 "go.y"
{
(yyval.node) = nod(OTYPESW, N, (yyvsp[(1) - (5)].node));
}
break;
case 131:
#line 942 "go.y"
#line 945 "go.y"
{
(yyval.node) = nod(OINDEX, (yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].node));
}
break;
case 132:
#line 946 "go.y"
#line 949 "go.y"
{
(yyval.node) = nod(OSLICE, (yyvsp[(1) - (6)].node), nod(OKEY, (yyvsp[(3) - (6)].node), (yyvsp[(5) - (6)].node)));
}
break;
case 134:
#line 951 "go.y"
#line 954 "go.y"
{
// conversion
(yyval.node) = nod(OCALL, (yyvsp[(1) - (5)].node), N);
......@@ -3444,7 +3447,7 @@ yyreduce:
break;
case 135:
#line 957 "go.y"
#line 960 "go.y"
{
(yyval.node) = (yyvsp[(3) - (5)].node);
(yyval.node)->right = (yyvsp[(1) - (5)].node);
......@@ -3454,7 +3457,7 @@ yyreduce:
break;
case 136:
#line 964 "go.y"
#line 967 "go.y"
{
(yyval.node) = (yyvsp[(3) - (5)].node);
(yyval.node)->right = (yyvsp[(1) - (5)].node);
......@@ -3463,7 +3466,7 @@ yyreduce:
break;
case 137:
#line 970 "go.y"
#line 973 "go.y"
{
yyerror("cannot parenthesize type in composite literal");
(yyval.node) = (yyvsp[(5) - (7)].node);
......@@ -3473,7 +3476,7 @@ yyreduce:
break;
case 139:
#line 979 "go.y"
#line 982 "go.y"
{
// composite expression.
// make node early so we get the right line number.
......@@ -3482,14 +3485,14 @@ yyreduce:
break;
case 140:
#line 987 "go.y"
#line 990 "go.y"
{
(yyval.node) = nod(OKEY, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 141:
#line 993 "go.y"
#line 996 "go.y"
{
// These nodes do not carry line numbers.
// Since a composite literal commonly spans several lines,
......@@ -3509,7 +3512,7 @@ yyreduce:
break;
case 142:
#line 1010 "go.y"
#line 1013 "go.y"
{
(yyval.node) = (yyvsp[(2) - (4)].node);
(yyval.node)->list = (yyvsp[(3) - (4)].list);
......@@ -3517,7 +3520,7 @@ yyreduce:
break;
case 144:
#line 1018 "go.y"
#line 1021 "go.y"
{
(yyval.node) = (yyvsp[(2) - (4)].node);
(yyval.node)->list = (yyvsp[(3) - (4)].list);
......@@ -3525,7 +3528,7 @@ yyreduce:
break;
case 146:
#line 1026 "go.y"
#line 1029 "go.y"
{
(yyval.node) = (yyvsp[(2) - (3)].node);
......@@ -3545,21 +3548,21 @@ yyreduce:
break;
case 150:
#line 1052 "go.y"
#line 1055 "go.y"
{
(yyval.i) = LBODY;
}
break;
case 151:
#line 1056 "go.y"
#line 1059 "go.y"
{
(yyval.i) = '{';
}
break;
case 152:
#line 1067 "go.y"
#line 1070 "go.y"
{
if((yyvsp[(1) - (1)].sym) == S)
(yyval.node) = N;
......@@ -3569,21 +3572,21 @@ yyreduce:
break;
case 153:
#line 1076 "go.y"
#line 1079 "go.y"
{
(yyval.node) = dclname((yyvsp[(1) - (1)].sym));
}
break;
case 154:
#line 1081 "go.y"
#line 1084 "go.y"
{
(yyval.node) = N;
}
break;
case 156:
#line 1088 "go.y"
#line 1091 "go.y"
{
(yyval.sym) = (yyvsp[(1) - (1)].sym);
// during imports, unqualified non-exported identifiers are from builtinpkg
......@@ -3593,14 +3596,14 @@ yyreduce:
break;
case 158:
#line 1096 "go.y"
#line 1099 "go.y"
{
(yyval.sym) = S;
}
break;
case 159:
#line 1102 "go.y"
#line 1105 "go.y"
{
Pkg *p;
......@@ -3616,7 +3619,7 @@ yyreduce:
break;
case 160:
#line 1117 "go.y"
#line 1120 "go.y"
{
(yyval.node) = oldname((yyvsp[(1) - (1)].sym));
if((yyval.node)->pack != N)
......@@ -3625,7 +3628,7 @@ yyreduce:
break;
case 162:
#line 1137 "go.y"
#line 1140 "go.y"
{
yyerror("final argument in variadic function missing type");
(yyval.node) = nod(ODDD, typenod(typ(TINTER)), N);
......@@ -3633,35 +3636,35 @@ yyreduce:
break;
case 163:
#line 1142 "go.y"
#line 1145 "go.y"
{
(yyval.node) = nod(ODDD, (yyvsp[(2) - (2)].node), N);
}
break;
case 169:
#line 1153 "go.y"
#line 1156 "go.y"
{
(yyval.node) = nod(OTPAREN, (yyvsp[(2) - (3)].node), N);
}
break;
case 173:
#line 1162 "go.y"
#line 1165 "go.y"
{
(yyval.node) = nod(OIND, (yyvsp[(2) - (2)].node), N);
}
break;
case 178:
#line 1172 "go.y"
#line 1175 "go.y"
{
(yyval.node) = nod(OTPAREN, (yyvsp[(2) - (3)].node), N);
}
break;
case 188:
#line 1193 "go.y"
#line 1196 "go.y"
{
if((yyvsp[(1) - (3)].node)->op == OPACK) {
Sym *s;
......@@ -3675,14 +3678,14 @@ yyreduce:
break;
case 189:
#line 1206 "go.y"
#line 1209 "go.y"
{
(yyval.node) = nod(OTARRAY, (yyvsp[(2) - (4)].node), (yyvsp[(4) - (4)].node));
}
break;
case 190:
#line 1210 "go.y"
#line 1213 "go.y"
{
// array literal of nelem
(yyval.node) = nod(OTARRAY, nod(ODDD, N, N), (yyvsp[(4) - (4)].node));
......@@ -3690,7 +3693,7 @@ yyreduce:
break;
case 191:
#line 1215 "go.y"
#line 1218 "go.y"
{
(yyval.node) = nod(OTCHAN, (yyvsp[(2) - (2)].node), N);
(yyval.node)->etype = Cboth;
......@@ -3698,7 +3701,7 @@ yyreduce:
break;
case 192:
#line 1220 "go.y"
#line 1223 "go.y"
{
(yyval.node) = nod(OTCHAN, (yyvsp[(3) - (3)].node), N);
(yyval.node)->etype = Csend;
......@@ -3706,21 +3709,21 @@ yyreduce:
break;
case 193:
#line 1225 "go.y"
#line 1228 "go.y"
{
(yyval.node) = nod(OTMAP, (yyvsp[(3) - (5)].node), (yyvsp[(5) - (5)].node));
}
break;
case 196:
#line 1233 "go.y"
#line 1236 "go.y"
{
(yyval.node) = nod(OIND, (yyvsp[(2) - (2)].node), N);
}
break;
case 197:
#line 1239 "go.y"
#line 1242 "go.y"
{
(yyval.node) = nod(OTCHAN, (yyvsp[(3) - (3)].node), N);
(yyval.node)->etype = Crecv;
......@@ -3728,7 +3731,7 @@ yyreduce:
break;
case 198:
#line 1246 "go.y"
#line 1249 "go.y"
{
(yyval.node) = nod(OTSTRUCT, N, N);
(yyval.node)->list = (yyvsp[(3) - (5)].list);
......@@ -3737,7 +3740,7 @@ yyreduce:
break;
case 199:
#line 1252 "go.y"
#line 1255 "go.y"
{
(yyval.node) = nod(OTSTRUCT, N, N);
fixlbrace((yyvsp[(2) - (3)].i));
......@@ -3745,7 +3748,7 @@ yyreduce:
break;
case 200:
#line 1259 "go.y"
#line 1262 "go.y"
{
(yyval.node) = nod(OTINTER, N, N);
(yyval.node)->list = (yyvsp[(3) - (5)].list);
......@@ -3754,7 +3757,7 @@ yyreduce:
break;
case 201:
#line 1265 "go.y"
#line 1268 "go.y"
{
(yyval.node) = nod(OTINTER, N, N);
fixlbrace((yyvsp[(2) - (3)].i));
......@@ -3762,7 +3765,7 @@ yyreduce:
break;
case 202:
#line 1276 "go.y"
#line 1279 "go.y"
{
(yyval.node) = (yyvsp[(2) - (3)].node);
if((yyval.node) == N)
......@@ -3777,7 +3780,7 @@ yyreduce:
break;
case 203:
#line 1290 "go.y"
#line 1293 "go.y"
{
Node *t;
......@@ -3809,7 +3812,7 @@ yyreduce:
break;
case 204:
#line 1319 "go.y"
#line 1322 "go.y"
{
Node *rcvr, *t;
......@@ -3850,7 +3853,7 @@ yyreduce:
break;
case 205:
#line 1359 "go.y"
#line 1362 "go.y"
{
Sym *s;
Type *t;
......@@ -3878,7 +3881,7 @@ yyreduce:
break;
case 206:
#line 1384 "go.y"
#line 1387 "go.y"
{
(yyval.node) = methodname1(newname((yyvsp[(4) - (8)].sym)), (yyvsp[(2) - (8)].list)->n->right);
(yyval.node)->type = functype((yyvsp[(2) - (8)].list)->n, (yyvsp[(6) - (8)].list), (yyvsp[(8) - (8)].list));
......@@ -3897,7 +3900,7 @@ yyreduce:
break;
case 207:
#line 1402 "go.y"
#line 1405 "go.y"
{
(yyvsp[(3) - (5)].list) = checkarglist((yyvsp[(3) - (5)].list), 1);
(yyval.node) = nod(OTFUNC, N, N);
......@@ -3907,14 +3910,14 @@ yyreduce:
break;
case 208:
#line 1410 "go.y"
#line 1413 "go.y"
{
(yyval.list) = nil;
}
break;
case 209:
#line 1414 "go.y"
#line 1417 "go.y"
{
(yyval.list) = (yyvsp[(2) - (3)].list);
if((yyval.list) == nil)
......@@ -3923,21 +3926,21 @@ yyreduce:
break;
case 210:
#line 1422 "go.y"
#line 1425 "go.y"
{
(yyval.list) = nil;
}
break;
case 211:
#line 1426 "go.y"
#line 1429 "go.y"
{
(yyval.list) = list1(nod(ODCLFIELD, N, (yyvsp[(1) - (1)].node)));
}
break;
case 212:
#line 1430 "go.y"
#line 1433 "go.y"
{
(yyvsp[(2) - (3)].list) = checkarglist((yyvsp[(2) - (3)].list), 0);
(yyval.list) = (yyvsp[(2) - (3)].list);
......@@ -3945,14 +3948,14 @@ yyreduce:
break;
case 213:
#line 1437 "go.y"
#line 1440 "go.y"
{
closurehdr((yyvsp[(1) - (1)].node));
}
break;
case 214:
#line 1443 "go.y"
#line 1446 "go.y"
{
(yyval.node) = closurebody((yyvsp[(3) - (4)].list));
fixlbrace((yyvsp[(2) - (4)].i));
......@@ -3960,21 +3963,21 @@ yyreduce:
break;
case 215:
#line 1448 "go.y"
#line 1451 "go.y"
{
(yyval.node) = closurebody(nil);
}
break;
case 216:
#line 1459 "go.y"
#line 1462 "go.y"
{
(yyval.list) = nil;
}
break;
case 217:
#line 1463 "go.y"
#line 1466 "go.y"
{
(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(2) - (3)].list));
if(nsyntaxerrors == 0)
......@@ -3985,56 +3988,56 @@ yyreduce:
break;
case 219:
#line 1474 "go.y"
#line 1477 "go.y"
{
(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list));
}
break;
case 221:
#line 1481 "go.y"
#line 1484 "go.y"
{
(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list));
}
break;
case 222:
#line 1487 "go.y"
#line 1490 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 223:
#line 1491 "go.y"
#line 1494 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 225:
#line 1498 "go.y"
#line 1501 "go.y"
{
(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list));
}
break;
case 226:
#line 1504 "go.y"
#line 1507 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 227:
#line 1508 "go.y"
#line 1511 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 228:
#line 1514 "go.y"
#line 1517 "go.y"
{
NodeList *l;
......@@ -4060,7 +4063,7 @@ yyreduce:
break;
case 229:
#line 1537 "go.y"
#line 1540 "go.y"
{
(yyvsp[(1) - (2)].node)->val = (yyvsp[(2) - (2)].val);
(yyval.list) = list1((yyvsp[(1) - (2)].node));
......@@ -4068,7 +4071,7 @@ yyreduce:
break;
case 230:
#line 1542 "go.y"
#line 1545 "go.y"
{
(yyvsp[(2) - (4)].node)->val = (yyvsp[(4) - (4)].val);
(yyval.list) = list1((yyvsp[(2) - (4)].node));
......@@ -4077,7 +4080,7 @@ yyreduce:
break;
case 231:
#line 1548 "go.y"
#line 1551 "go.y"
{
(yyvsp[(2) - (3)].node)->right = nod(OIND, (yyvsp[(2) - (3)].node)->right, N);
(yyvsp[(2) - (3)].node)->val = (yyvsp[(3) - (3)].val);
......@@ -4086,7 +4089,7 @@ yyreduce:
break;
case 232:
#line 1554 "go.y"
#line 1557 "go.y"
{
(yyvsp[(3) - (5)].node)->right = nod(OIND, (yyvsp[(3) - (5)].node)->right, N);
(yyvsp[(3) - (5)].node)->val = (yyvsp[(5) - (5)].val);
......@@ -4096,7 +4099,7 @@ yyreduce:
break;
case 233:
#line 1561 "go.y"
#line 1564 "go.y"
{
(yyvsp[(3) - (5)].node)->right = nod(OIND, (yyvsp[(3) - (5)].node)->right, N);
(yyvsp[(3) - (5)].node)->val = (yyvsp[(5) - (5)].val);
......@@ -4106,7 +4109,7 @@ yyreduce:
break;
case 234:
#line 1570 "go.y"
#line 1573 "go.y"
{
Node *n;
......@@ -4118,7 +4121,7 @@ yyreduce:
break;
case 235:
#line 1579 "go.y"
#line 1582 "go.y"
{
Pkg *pkg;
......@@ -4134,14 +4137,14 @@ yyreduce:
break;
case 236:
#line 1594 "go.y"
#line 1597 "go.y"
{
(yyval.node) = embedded((yyvsp[(1) - (1)].sym));
}
break;
case 237:
#line 1600 "go.y"
#line 1603 "go.y"
{
(yyval.node) = nod(ODCLFIELD, (yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node));
ifacedcl((yyval.node));
......@@ -4149,14 +4152,14 @@ yyreduce:
break;
case 238:
#line 1605 "go.y"
#line 1608 "go.y"
{
(yyval.node) = nod(ODCLFIELD, N, oldname((yyvsp[(1) - (1)].sym)));
}
break;
case 239:
#line 1609 "go.y"
#line 1612 "go.y"
{
(yyval.node) = nod(ODCLFIELD, N, oldname((yyvsp[(2) - (3)].sym)));
yyerror("cannot parenthesize embedded type");
......@@ -4164,7 +4167,7 @@ yyreduce:
break;
case 240:
#line 1616 "go.y"
#line 1619 "go.y"
{
// without func keyword
(yyvsp[(2) - (4)].list) = checkarglist((yyvsp[(2) - (4)].list), 1);
......@@ -4175,7 +4178,7 @@ yyreduce:
break;
case 242:
#line 1630 "go.y"
#line 1633 "go.y"
{
(yyval.node) = nod(ONONAME, N, N);
(yyval.node)->sym = (yyvsp[(1) - (2)].sym);
......@@ -4184,7 +4187,7 @@ yyreduce:
break;
case 243:
#line 1636 "go.y"
#line 1639 "go.y"
{
(yyval.node) = nod(ONONAME, N, N);
(yyval.node)->sym = (yyvsp[(1) - (2)].sym);
......@@ -4193,56 +4196,56 @@ yyreduce:
break;
case 245:
#line 1645 "go.y"
#line 1648 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 246:
#line 1649 "go.y"
#line 1652 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 247:
#line 1654 "go.y"
#line 1657 "go.y"
{
(yyval.list) = nil;
}
break;
case 248:
#line 1658 "go.y"
#line 1661 "go.y"
{
(yyval.list) = (yyvsp[(1) - (2)].list);
}
break;
case 249:
#line 1666 "go.y"
#line 1669 "go.y"
{
(yyval.node) = N;
}
break;
case 251:
#line 1671 "go.y"
#line 1674 "go.y"
{
(yyval.node) = liststmt((yyvsp[(1) - (1)].list));
}
break;
case 253:
#line 1676 "go.y"
#line 1679 "go.y"
{
(yyval.node) = N;
}
break;
case 259:
#line 1687 "go.y"
#line 1690 "go.y"
{
(yyvsp[(1) - (2)].node) = nod(OLABEL, (yyvsp[(1) - (2)].node), N);
(yyvsp[(1) - (2)].node)->sym = dclstack; // context, for goto restrictions
......@@ -4250,7 +4253,7 @@ yyreduce:
break;
case 260:
#line 1692 "go.y"
#line 1695 "go.y"
{
NodeList *l;
......@@ -4263,7 +4266,7 @@ yyreduce:
break;
case 261:
#line 1702 "go.y"
#line 1705 "go.y"
{
// will be converted to OFALL
(yyval.node) = nod(OXFALL, N, N);
......@@ -4271,35 +4274,35 @@ yyreduce:
break;
case 262:
#line 1707 "go.y"
#line 1710 "go.y"
{
(yyval.node) = nod(OBREAK, (yyvsp[(2) - (2)].node), N);
}
break;
case 263:
#line 1711 "go.y"
#line 1714 "go.y"
{
(yyval.node) = nod(OCONTINUE, (yyvsp[(2) - (2)].node), N);
}
break;
case 264:
#line 1715 "go.y"
#line 1718 "go.y"
{
(yyval.node) = nod(OPROC, (yyvsp[(2) - (2)].node), N);
}
break;
case 265:
#line 1719 "go.y"
#line 1722 "go.y"
{
(yyval.node) = nod(ODEFER, (yyvsp[(2) - (2)].node), N);
}
break;
case 266:
#line 1723 "go.y"
#line 1726 "go.y"
{
(yyval.node) = nod(OGOTO, (yyvsp[(2) - (2)].node), N);
(yyval.node)->sym = dclstack; // context, for goto restrictions
......@@ -4307,7 +4310,7 @@ yyreduce:
break;
case 267:
#line 1728 "go.y"
#line 1731 "go.y"
{
(yyval.node) = nod(ORETURN, N, N);
(yyval.node)->list = (yyvsp[(2) - (2)].list);
......@@ -4327,7 +4330,7 @@ yyreduce:
break;
case 268:
#line 1747 "go.y"
#line 1750 "go.y"
{
(yyval.list) = nil;
if((yyvsp[(1) - (1)].node) != N)
......@@ -4336,7 +4339,7 @@ yyreduce:
break;
case 269:
#line 1753 "go.y"
#line 1756 "go.y"
{
(yyval.list) = (yyvsp[(1) - (3)].list);
if((yyvsp[(3) - (3)].node) != N)
......@@ -4345,189 +4348,189 @@ yyreduce:
break;
case 270:
#line 1761 "go.y"
#line 1764 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 271:
#line 1765 "go.y"
#line 1768 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 272:
#line 1771 "go.y"
#line 1774 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 273:
#line 1775 "go.y"
#line 1778 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 274:
#line 1781 "go.y"
#line 1784 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 275:
#line 1785 "go.y"
#line 1788 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 276:
#line 1791 "go.y"
#line 1794 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 277:
#line 1795 "go.y"
#line 1798 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 278:
#line 1804 "go.y"
#line 1807 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 279:
#line 1808 "go.y"
#line 1811 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 280:
#line 1812 "go.y"
#line 1815 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 281:
#line 1816 "go.y"
#line 1819 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 282:
#line 1821 "go.y"
#line 1824 "go.y"
{
(yyval.list) = nil;
}
break;
case 283:
#line 1825 "go.y"
#line 1828 "go.y"
{
(yyval.list) = (yyvsp[(1) - (2)].list);
}
break;
case 288:
#line 1839 "go.y"
#line 1842 "go.y"
{
(yyval.node) = N;
}
break;
case 290:
#line 1845 "go.y"
#line 1848 "go.y"
{
(yyval.list) = nil;
}
break;
case 292:
#line 1851 "go.y"
#line 1854 "go.y"
{
(yyval.node) = N;
}
break;
case 294:
#line 1857 "go.y"
#line 1860 "go.y"
{
(yyval.list) = nil;
}
break;
case 296:
#line 1863 "go.y"
#line 1866 "go.y"
{
(yyval.list) = nil;
}
break;
case 298:
#line 1869 "go.y"
#line 1872 "go.y"
{
(yyval.list) = nil;
}
break;
case 300:
#line 1875 "go.y"
#line 1878 "go.y"
{
(yyval.val).ctype = CTxxx;
}
break;
case 302:
#line 1885 "go.y"
#line 1888 "go.y"
{
importimport((yyvsp[(2) - (4)].sym), (yyvsp[(3) - (4)].val).u.sval);
}
break;
case 303:
#line 1889 "go.y"
#line 1892 "go.y"
{
importvar((yyvsp[(2) - (4)].sym), (yyvsp[(3) - (4)].type));
}
break;
case 304:
#line 1893 "go.y"
#line 1896 "go.y"
{
importconst((yyvsp[(2) - (5)].sym), types[TIDEAL], (yyvsp[(4) - (5)].node));
}
break;
case 305:
#line 1897 "go.y"
#line 1900 "go.y"
{
importconst((yyvsp[(2) - (6)].sym), (yyvsp[(3) - (6)].type), (yyvsp[(5) - (6)].node));
}
break;
case 306:
#line 1901 "go.y"
#line 1904 "go.y"
{
importtype((yyvsp[(2) - (4)].type), (yyvsp[(3) - (4)].type));
}
break;
case 307:
#line 1905 "go.y"
#line 1908 "go.y"
{
if((yyvsp[(2) - (4)].node) == N) {
dclcontext = PEXTERN; // since we skip the funcbody below
......@@ -4548,7 +4551,7 @@ yyreduce:
break;
case 308:
#line 1925 "go.y"
#line 1928 "go.y"
{
(yyval.sym) = (yyvsp[(1) - (1)].sym);
structpkg = (yyval.sym)->pkg;
......@@ -4556,7 +4559,7 @@ yyreduce:
break;
case 309:
#line 1932 "go.y"
#line 1935 "go.y"
{
(yyval.type) = pkgtype((yyvsp[(1) - (1)].sym));
importsym((yyvsp[(1) - (1)].sym), OTYPE);
......@@ -4564,14 +4567,14 @@ yyreduce:
break;
case 315:
#line 1952 "go.y"
#line 1955 "go.y"
{
(yyval.type) = pkgtype((yyvsp[(1) - (1)].sym));
}
break;
case 316:
#line 1956 "go.y"
#line 1959 "go.y"
{
// predefined name like uint8
(yyvsp[(1) - (1)].sym) = pkglookup((yyvsp[(1) - (1)].sym)->name, builtinpkg);
......@@ -4584,49 +4587,49 @@ yyreduce:
break;
case 317:
#line 1966 "go.y"
#line 1969 "go.y"
{
(yyval.type) = aindex(N, (yyvsp[(3) - (3)].type));
}
break;
case 318:
#line 1970 "go.y"
#line 1973 "go.y"
{
(yyval.type) = aindex(nodlit((yyvsp[(2) - (4)].val)), (yyvsp[(4) - (4)].type));
}
break;
case 319:
#line 1974 "go.y"
#line 1977 "go.y"
{
(yyval.type) = maptype((yyvsp[(3) - (5)].type), (yyvsp[(5) - (5)].type));
}
break;
case 320:
#line 1978 "go.y"
#line 1981 "go.y"
{
(yyval.type) = tostruct((yyvsp[(3) - (4)].list));
}
break;
case 321:
#line 1982 "go.y"
#line 1985 "go.y"
{
(yyval.type) = tointerface((yyvsp[(3) - (4)].list));
}
break;
case 322:
#line 1986 "go.y"
#line 1989 "go.y"
{
(yyval.type) = ptrto((yyvsp[(2) - (2)].type));
}
break;
case 323:
#line 1990 "go.y"
#line 1993 "go.y"
{
(yyval.type) = typ(TCHAN);
(yyval.type)->type = (yyvsp[(2) - (2)].type);
......@@ -4635,7 +4638,7 @@ yyreduce:
break;
case 324:
#line 1996 "go.y"
#line 1999 "go.y"
{
(yyval.type) = typ(TCHAN);
(yyval.type)->type = (yyvsp[(3) - (4)].type);
......@@ -4644,7 +4647,7 @@ yyreduce:
break;
case 325:
#line 2002 "go.y"
#line 2005 "go.y"
{
(yyval.type) = typ(TCHAN);
(yyval.type)->type = (yyvsp[(3) - (3)].type);
......@@ -4653,7 +4656,7 @@ yyreduce:
break;
case 326:
#line 2010 "go.y"
#line 2013 "go.y"
{
(yyval.type) = typ(TCHAN);
(yyval.type)->type = (yyvsp[(3) - (3)].type);
......@@ -4662,14 +4665,14 @@ yyreduce:
break;
case 327:
#line 2018 "go.y"
#line 2021 "go.y"
{
(yyval.type) = functype(nil, (yyvsp[(3) - (5)].list), (yyvsp[(5) - (5)].list));
}
break;
case 328:
#line 2024 "go.y"
#line 2027 "go.y"
{
(yyval.node) = nod(ODCLFIELD, N, typenod((yyvsp[(2) - (3)].type)));
if((yyvsp[(1) - (3)].sym))
......@@ -4679,7 +4682,7 @@ yyreduce:
break;
case 329:
#line 2031 "go.y"
#line 2034 "go.y"
{
Type *t;
......@@ -4696,7 +4699,7 @@ yyreduce:
break;
case 330:
#line 2047 "go.y"
#line 2050 "go.y"
{
Sym *s;
......@@ -4715,49 +4718,49 @@ yyreduce:
break;
case 331:
#line 2065 "go.y"
#line 2068 "go.y"
{
(yyval.node) = nod(ODCLFIELD, newname((yyvsp[(1) - (5)].sym)), typenod(functype(fakethis(), (yyvsp[(3) - (5)].list), (yyvsp[(5) - (5)].list))));
}
break;
case 332:
#line 2069 "go.y"
#line 2072 "go.y"
{
(yyval.node) = nod(ODCLFIELD, N, typenod((yyvsp[(1) - (1)].type)));
}
break;
case 333:
#line 2074 "go.y"
#line 2077 "go.y"
{
(yyval.list) = nil;
}
break;
case 335:
#line 2081 "go.y"
#line 2084 "go.y"
{
(yyval.list) = (yyvsp[(2) - (3)].list);
}
break;
case 336:
#line 2085 "go.y"
#line 2088 "go.y"
{
(yyval.list) = list1(nod(ODCLFIELD, N, typenod((yyvsp[(1) - (1)].type))));
}
break;
case 337:
#line 2095 "go.y"
#line 2098 "go.y"
{
(yyval.node) = nodlit((yyvsp[(1) - (1)].val));
}
break;
case 338:
#line 2099 "go.y"
#line 2102 "go.y"
{
(yyval.node) = nodlit((yyvsp[(2) - (2)].val));
switch((yyval.node)->val.ctype){
......@@ -4775,7 +4778,7 @@ yyreduce:
break;
case 339:
#line 2114 "go.y"
#line 2117 "go.y"
{
(yyval.node) = oldname(pkglookup((yyvsp[(1) - (1)].sym)->name, builtinpkg));
if((yyval.node)->op != OLITERAL)
......@@ -4784,7 +4787,7 @@ yyreduce:
break;
case 341:
#line 2123 "go.y"
#line 2126 "go.y"
{
if((yyvsp[(2) - (5)].node)->val.ctype == CTRUNE && (yyvsp[(4) - (5)].node)->val.ctype == CTINT) {
(yyval.node) = (yyvsp[(2) - (5)].node);
......@@ -4798,42 +4801,42 @@ yyreduce:
break;
case 344:
#line 2139 "go.y"
#line 2142 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 345:
#line 2143 "go.y"
#line 2146 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 346:
#line 2149 "go.y"
#line 2152 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 347:
#line 2153 "go.y"
#line 2156 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 348:
#line 2159 "go.y"
#line 2162 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 349:
#line 2163 "go.y"
#line 2166 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
......@@ -4841,7 +4844,7 @@ yyreduce:
/* Line 1267 of yacc.c. */
#line 4846 "y.tab.c"
#line 4849 "y.tab.c"
default: break;
}
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
......@@ -5055,7 +5058,7 @@ yyreturn:
}
#line 2167 "go.y"
#line 2170 "go.y"
static void
......
......@@ -6,12 +6,12 @@
package main
func f() int { // ERROR "return|control"
func f() int { // GCCGO_ERROR "control"
if false {
return 0;
}
// we should not be able to return successfully w/o a return statement
}
} // GC_ERROR "return"
func main() {
print(f(), "\n");
......
......@@ -11,4 +11,5 @@ package main
func a(b int) int64 {
b // ERROR "not used"
return 0
}
// errorcheck
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Test compiler diagnosis of function missing return statements.
// See issue 65 and golang.org/s/go11return.
package p
type T int
var x interface{}
var c chan int
func external() int // ok
func _() int {
} // ERROR "missing return"
func _() int {
print(1)
} // ERROR "missing return"
// return is okay
func _() int {
print(1)
return 2
}
// goto is okay
func _() int {
L:
print(1)
goto L
}
// panic is okay
func _() int {
print(1)
panic(2)
}
// but only builtin panic
func _() int {
var panic = func(int) {}
print(1)
panic(2)
} // ERROR "missing return"
// block ending in terminating statement is okay
func _() int {
{
print(1)
return 2
}
}
// block ending in terminating statement is okay
func _() int {
L:
{
print(1)
goto L
}
}
// block ending in terminating statement is okay
func _() int {
print(1)
{
panic(2)
}
}
// adding more code - even though it is dead - now requires a return
func _() int {
print(1)
return 2
print(3)
} // ERROR "missing return"
func _() int {
L:
print(1)
goto L
print(3)
} // ERROR "missing return"
func _() int {
print(1)
panic(2)
print(3)
} // ERROR "missing return"
func _() int {
{
print(1)
return 2
print(3)
}
} // ERROR "missing return"
func _() int {
L:
{
print(1)
goto L
print(3)
}
} // ERROR "missing return"
func _() int {
print(1)
{
panic(2)
print(3)
}
} // ERROR "missing return"
func _() int {
{
print(1)
return 2
}
print(3)
} // ERROR "missing return"
func _() int {
L:
{
print(1)
goto L
}
print(3)
} // ERROR "missing return"
func _() int {
print(1)
{
panic(2)
}
print(3)
} // ERROR "missing return"
// even an empty dead block triggers the message, because it
// becomes the final statement.
func _() int {
print(1)
return 2
{}
} // ERROR "missing return"
func _() int {
L:
print(1)
goto L
{}
} // ERROR "missing return"
func _() int {
print(1)
panic(2)
{}
} // ERROR "missing return"
func _() int {
{
print(1)
return 2
{}
}
} // ERROR "missing return"
func _() int {
L:
{
print(1)
goto L
{}
}
} // ERROR "missing return"
func _() int {
print(1)
{
panic(2)
{}
}
} // ERROR "missing return"
func _() int {
{
print(1)
return 2
}
{}
} // ERROR "missing return"
func _() int {
L:
{
print(1)
goto L
}
{}
} // ERROR "missing return"
func _() int {
print(1)
{
panic(2)
}
{}
} // ERROR "missing return"
// if-else chain with final else and all terminating is okay
func _() int {
print(1)
if x == nil {
panic(2)
} else {
panic(3)
}
}
func _() int {
L:
print(1)
if x == nil {
panic(2)
} else {
goto L
}
}
func _() int {
L:
print(1)
if x == nil {
panic(2)
} else if x == 1 {
return 0
} else if x != 2 {
panic(3)
} else {
goto L
}
}
// if-else chain missing final else is not okay, even if the
// conditions cover every possible case.
func _() int {
print(1)
if x == nil {
panic(2)
} else if x != nil {
panic(3)
}
} // ERROR "missing return"
func _() int {
print(1)
if x == nil {
panic(2)
}
} // ERROR "missing return"
func _() int {
L:
print(1)
if x == nil {
panic(2)
} else if x == 1 {
return 0
} else if x != 1 {
panic(3)
}
} // ERROR "missing return"
// for { loops that never break are okay.
func _() int {
print(1)
for {}
}
func _() int {
for {
for {
break
}
}
}
func _() int {
for {
L:
for {
break L
}
}
}
// for { loops that break are not okay.
func _() int {
print(1)
for { break }
} // ERROR "missing return"
func _() int {
for {
for {
}
break
}
} // ERROR "missing return"
func _() int {
L:
for {
for {
break L
}
}
} // ERROR "missing return"
// if there's a condition - even "true" - the loops are no longer syntactically terminating
func _() int {
print(1)
for x == nil {}
} // ERROR "missing return"
func _() int {
for x == nil {
for {
break
}
}
} // ERROR "missing return"
func _() int {
for x == nil {
L:
for {
break L
}
}
} // ERROR "missing return"
func _() int {
print(1)
for true {}
} // ERROR "missing return"
func _() int {
for true {
for {
break
}
}
} // ERROR "missing return"
func _() int {
for true {
L:
for {
break L
}
}
} // ERROR "missing return"
// select in which all cases terminate and none break are okay.
func _() int {
print(1)
select{}
}
func _() int {
print(1)
select {
case <-c:
print(2)
panic("abc")
}
}
func _() int {
print(1)
select {
case <-c:
print(2)
for{}
}
}
func _() int {
L:
print(1)
select {
case <-c:
print(2)
panic("abc")
case c <- 1:
print(2)
goto L
}
}
func _() int {
print(1)
select {
case <-c:
print(2)
panic("abc")
default:
select{}
}
}
// if any cases don't terminate, the select isn't okay anymore
func _() int {
print(1)
select {
case <-c:
print(2)
}
} // ERROR "missing return"
func _() int {
L:
print(1)
select {
case <-c:
print(2)
panic("abc")
goto L
case c <- 1:
print(2)
}
} // ERROR "missing return"
func _() int {
print(1)
select {
case <-c:
print(2)
panic("abc")
default:
print(2)
}
} // ERROR "missing return"
// if any breaks refer to the select, the select isn't okay anymore, even if they're dead
func _() int {
print(1)
select{ default: break }
} // ERROR "missing return"
func _() int {
print(1)
select {
case <-c:
print(2)
panic("abc")
break
}
} // ERROR "missing return"
func _() int {
print(1)
L:
select {
case <-c:
print(2)
for{ break L }
}
} // ERROR "missing return"
func _() int {
print(1)
L:
select {
case <-c:
print(2)
panic("abc")
case c <- 1:
print(2)
break L
}
} // ERROR "missing return"
func _() int {
print(1)
select {
case <-c:
print(1)
panic("abc")
default:
select{}
break
}
} // ERROR "missing return"
// switch with default in which all cases terminate is okay
func _() int {
print(1)
switch x {
case 1:
print(2)
panic(3)
default:
return 4
}
}
func _() int {
print(1)
switch x {
default:
return 4
case 1:
print(2)
panic(3)
}
}
func _() int {
print(1)
switch x {
case 1:
print(2)
fallthrough
default:
return 4
}
}
// if no default or some case doesn't terminate, switch is no longer okay
func _() int {
print(1)
switch {
}
} // ERROR "missing return"
func _() int {
print(1)
switch x {
case 1:
print(2)
panic(3)
case 2:
return 4
}
} // ERROR "missing return"
func _() int {
print(1)
switch x {
case 2:
return 4
case 1:
print(2)
panic(3)
}
} // ERROR "missing return"
func _() int {
print(1)
switch x {
case 1:
print(2)
fallthrough
case 2:
return 4
}
} // ERROR "missing return"
func _() int {
print(1)
switch x {
case 1:
print(2)
panic(3)
}
} // ERROR "missing return"
// if any breaks refer to the switch, switch is no longer okay
func _() int {
print(1)
L:
switch x {
case 1:
print(2)
panic(3)
break L
default:
return 4
}
} // ERROR "missing return"
func _() int {
print(1)
switch x {
default:
return 4
break
case 1:
print(2)
panic(3)
}
} // ERROR "missing return"
func _() int {
print(1)
L:
switch x {
case 1:
print(2)
for {
break L
}
default:
return 4
}
} // ERROR "missing return"
// type switch with default in which all cases terminate is okay
func _() int {
print(1)
switch x.(type) {
case int:
print(2)
panic(3)
default:
return 4
}
}
func _() int {
print(1)
switch x.(type) {
default:
return 4
case int:
print(2)
panic(3)
}
}
func _() int {
print(1)
switch x.(type) {
case int:
print(2)
fallthrough
default:
return 4
}
}
// if no default or some case doesn't terminate, switch is no longer okay
func _() int {
print(1)
switch {
}
} // ERROR "missing return"
func _() int {
print(1)
switch x.(type) {
case int:
print(2)
panic(3)
case float64:
return 4
}
} // ERROR "missing return"
func _() int {
print(1)
switch x.(type) {
case float64:
return 4
case int:
print(2)
panic(3)
}
} // ERROR "missing return"
func _() int {
print(1)
switch x.(type) {
case int:
print(2)
fallthrough
case float64:
return 4
}
} // ERROR "missing return"
func _() int {
print(1)
switch x.(type) {
case int:
print(2)
panic(3)
}
} // ERROR "missing return"
// if any breaks refer to the switch, switch is no longer okay
func _() int {
print(1)
L:
switch x.(type) {
case int:
print(2)
panic(3)
break L
default:
return 4
}
} // ERROR "missing return"
func _() int {
print(1)
switch x.(type) {
default:
return 4
break
case int:
print(2)
panic(3)
}
} // ERROR "missing return"
func _() int {
print(1)
L:
switch x.(type) {
case int:
print(2)
for {
break L
}
default:
return 4
}
} // ERROR "missing return"
// again, but without the leading print(1).
// testing that everything works when the terminating statement is first.
func _() int {
} // ERROR "missing return"
// return is okay
func _() int {
return 2
}
// goto is okay
func _() int {
L:
goto L
}
// panic is okay
func _() int {
panic(2)
}
// but only builtin panic
func _() int {
var panic = func(int) {}
panic(2)
} // ERROR "missing return"
// block ending in terminating statement is okay
func _() int {
{
return 2
}
}
// block ending in terminating statement is okay
func _() int {
L:
{
goto L
}
}
// block ending in terminating statement is okay
func _() int {
{
panic(2)
}
}
// adding more code - even though it is dead - now requires a return
func _() int {
return 2
print(3)
} // ERROR "missing return"
func _() int {
L:
goto L
print(3)
} // ERROR "missing return"
func _() int {
panic(2)
print(3)
} // ERROR "missing return"
func _() int {
{
return 2
print(3)
}
} // ERROR "missing return"
func _() int {
L:
{
goto L
print(3)
}
} // ERROR "missing return"
func _() int {
{
panic(2)
print(3)
}
} // ERROR "missing return"
func _() int {
{
return 2
}
print(3)
} // ERROR "missing return"
func _() int {
L:
{
goto L
}
print(3)
} // ERROR "missing return"
func _() int {
{
panic(2)
}
print(3)
} // ERROR "missing return"
// even an empty dead block triggers the message, because it
// becomes the final statement.
func _() int {
return 2
{}
} // ERROR "missing return"
func _() int {
L:
goto L
{}
} // ERROR "missing return"
func _() int {
panic(2)
{}
} // ERROR "missing return"
func _() int {
{
return 2
{}
}
} // ERROR "missing return"
func _() int {
L:
{
goto L
{}
}
} // ERROR "missing return"
func _() int {
{
panic(2)
{}
}
} // ERROR "missing return"
func _() int {
{
return 2
}
{}
} // ERROR "missing return"
func _() int {
L:
{
goto L
}
{}
} // ERROR "missing return"
func _() int {
{
panic(2)
}
{}
} // ERROR "missing return"
// if-else chain with final else and all terminating is okay
func _() int {
if x == nil {
panic(2)
} else {
panic(3)
}
}
func _() int {
L:
if x == nil {
panic(2)
} else {
goto L
}
}
func _() int {
L:
if x == nil {
panic(2)
} else if x == 1 {
return 0
} else if x != 2 {
panic(3)
} else {
goto L
}
}
// if-else chain missing final else is not okay, even if the
// conditions cover every possible case.
func _() int {
if x == nil {
panic(2)
} else if x != nil {
panic(3)
}
} // ERROR "missing return"
func _() int {
if x == nil {
panic(2)
}
} // ERROR "missing return"
func _() int {
L:
if x == nil {
panic(2)
} else if x == 1 {
return 0
} else if x != 1 {
panic(3)
}
} // ERROR "missing return"
// for { loops that never break are okay.
func _() int {
for {}
}
func _() int {
for {
for {
break
}
}
}
func _() int {
for {
L:
for {
break L
}
}
}
// for { loops that break are not okay.
func _() int {
for { break }
} // ERROR "missing return"
func _() int {
for {
for {
}
break
}
} // ERROR "missing return"
func _() int {
L:
for {
for {
break L
}
}
} // ERROR "missing return"
// if there's a condition - even "true" - the loops are no longer syntactically terminating
func _() int {
for x == nil {}
} // ERROR "missing return"
func _() int {
for x == nil {
for {
break
}
}
} // ERROR "missing return"
func _() int {
for x == nil {
L:
for {
break L
}
}
} // ERROR "missing return"
func _() int {
for true {}
} // ERROR "missing return"
func _() int {
for true {
for {
break
}
}
} // ERROR "missing return"
func _() int {
for true {
L:
for {
break L
}
}
} // ERROR "missing return"
// select in which all cases terminate and none break are okay.
func _() int {
select{}
}
func _() int {
select {
case <-c:
print(2)
panic("abc")
}
}
func _() int {
select {
case <-c:
print(2)
for{}
}
}
func _() int {
L:
select {
case <-c:
print(2)
panic("abc")
case c <- 1:
print(2)
goto L
}
}
func _() int {
select {
case <-c:
print(2)
panic("abc")
default:
select{}
}
}
// if any cases don't terminate, the select isn't okay anymore
func _() int {
select {
case <-c:
print(2)
}
} // ERROR "missing return"
func _() int {
L:
select {
case <-c:
print(2)
panic("abc")
goto L
case c <- 1:
print(2)
}
} // ERROR "missing return"
func _() int {
select {
case <-c:
print(2)
panic("abc")
default:
print(2)
}
} // ERROR "missing return"
// if any breaks refer to the select, the select isn't okay anymore, even if they're dead
func _() int {
select{ default: break }
} // ERROR "missing return"
func _() int {
select {
case <-c:
print(2)
panic("abc")
break
}
} // ERROR "missing return"
func _() int {
L:
select {
case <-c:
print(2)
for{ break L }
}
} // ERROR "missing return"
func _() int {
L:
select {
case <-c:
print(2)
panic("abc")
case c <- 1:
print(2)
break L
}
} // ERROR "missing return"
func _() int {
select {
case <-c:
panic("abc")
default:
select{}
break
}
} // ERROR "missing return"
// switch with default in which all cases terminate is okay
func _() int {
switch x {
case 1:
print(2)
panic(3)
default:
return 4
}
}
func _() int {
switch x {
default:
return 4
case 1:
print(2)
panic(3)
}
}
func _() int {
switch x {
case 1:
print(2)
fallthrough
default:
return 4
}
}
// if no default or some case doesn't terminate, switch is no longer okay
func _() int {
switch {
}
} // ERROR "missing return"
func _() int {
switch x {
case 1:
print(2)
panic(3)
case 2:
return 4
}
} // ERROR "missing return"
func _() int {
switch x {
case 2:
return 4
case 1:
print(2)
panic(3)
}
} // ERROR "missing return"
func _() int {
switch x {
case 1:
print(2)
fallthrough
case 2:
return 4
}
} // ERROR "missing return"
func _() int {
switch x {
case 1:
print(2)
panic(3)
}
} // ERROR "missing return"
// if any breaks refer to the switch, switch is no longer okay
func _() int {
L:
switch x {
case 1:
print(2)
panic(3)
break L
default:
return 4
}
} // ERROR "missing return"
func _() int {
switch x {
default:
return 4
break
case 1:
print(2)
panic(3)
}
} // ERROR "missing return"
func _() int {
L:
switch x {
case 1:
print(2)
for {
break L
}
default:
return 4
}
} // ERROR "missing return"
// type switch with default in which all cases terminate is okay
func _() int {
switch x.(type) {
case int:
print(2)
panic(3)
default:
return 4
}
}
func _() int {
switch x.(type) {
default:
return 4
case int:
print(2)
panic(3)
}
}
func _() int {
switch x.(type) {
case int:
print(2)
fallthrough
default:
return 4
}
}
// if no default or some case doesn't terminate, switch is no longer okay
func _() int {
switch {
}
} // ERROR "missing return"
func _() int {
switch x.(type) {
case int:
print(2)
panic(3)
case float64:
return 4
}
} // ERROR "missing return"
func _() int {
switch x.(type) {
case float64:
return 4
case int:
print(2)
panic(3)
}
} // ERROR "missing return"
func _() int {
switch x.(type) {
case int:
print(2)
fallthrough
case float64:
return 4
}
} // ERROR "missing return"
func _() int {
switch x.(type) {
case int:
print(2)
panic(3)
}
} // ERROR "missing return"
// if any breaks refer to the switch, switch is no longer okay
func _() int {
L:
switch x.(type) {
case int:
print(2)
panic(3)
break L
default:
return 4
}
} // ERROR "missing return"
func _() int {
switch x.(type) {
default:
return 4
break
case int:
print(2)
panic(3)
}
} // ERROR "missing return"
func _() int {
L:
switch x.(type) {
case int:
print(2)
for {
break L
}
default:
return 4
}
} // ERROR "missing return"
/**/
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment