mirror of
https://github.com/golang/go
synced 2024-11-22 08:44:41 -07:00
cmd/gc: add way to specify 'noescape' for extern funcs
A new comment directive //go:noescape instructs the compiler that the following external (no body) func declaration should be treated as if none of its arguments escape to the heap. Fixes #4099. R=golang-dev, dave, minux.ma, daniel.morsing, remyoudompheng, adg, agl, iant CC=golang-dev https://golang.org/cl/7289048
This commit is contained in:
parent
f1c409b98b
commit
fd178d6a7e
@ -25,6 +25,8 @@ other packages. It is therefore not necessary when compiling client C of
|
||||
package P to read the files of P's dependencies, only the compiled output
|
||||
of P.
|
||||
|
||||
Command Line
|
||||
|
||||
Usage:
|
||||
go tool 6g [flags] file...
|
||||
The specified files must be Go source files and all part of the same package.
|
||||
@ -48,7 +50,7 @@ Flags:
|
||||
disable optimizations
|
||||
-S
|
||||
write assembly language text to standard output (code only)
|
||||
-SS
|
||||
-S -S
|
||||
write assembly language text to standard output (code and data)
|
||||
-u
|
||||
disallow importing packages not marked as safe
|
||||
@ -60,5 +62,28 @@ Flags:
|
||||
There are also a number of debugging flags; run the command with no arguments
|
||||
to get a usage message.
|
||||
|
||||
Compiler Directives
|
||||
|
||||
The compiler accepts two compiler directives in the form of // comments at the
|
||||
beginning of a line. To distinguish them from non-directive comments, the directives
|
||||
require no space between the slashes and the name of the directive. However, since
|
||||
they are comments, tools unaware of the directive convention or of a particular
|
||||
directive can skip over a directive like any other comment.
|
||||
|
||||
//line path/to/file:linenumber
|
||||
|
||||
The //line directive specifies that the source line that follows should be recorded
|
||||
as having come from the given file path and line number. Successive lines are
|
||||
recorded using increasing line numbers, until the next directive. This directive
|
||||
typically appears in machine-generated code, so that compilers and debuggers
|
||||
will show lines in the original input to the generator.
|
||||
|
||||
//go:noescape
|
||||
|
||||
The //go:noescape directive specifies that the next declaration in the file, which
|
||||
must be a func without a body (meaning that it has an implementation not written
|
||||
in Go) does not allow any of the pointers passed as arguments to escape into the
|
||||
heap or into the values returned from the function. This information can be used as
|
||||
during the compiler's escape analysis of Go code calling the function.
|
||||
*/
|
||||
package documentation
|
||||
|
@ -330,7 +330,10 @@ escfunc(EscState *e, Node *func)
|
||||
case PPARAM:
|
||||
if(ll->n->type && !haspointers(ll->n->type))
|
||||
break;
|
||||
ll->n->esc = EscNone; // prime for escflood later
|
||||
if(curfn->nbody == nil && !curfn->noescape)
|
||||
ll->n->esc = EscHeap;
|
||||
else
|
||||
ll->n->esc = EscNone; // prime for escflood later
|
||||
e->noesc = list(e->noesc, ll->n);
|
||||
ll->n->escloopdepth = 1;
|
||||
break;
|
||||
@ -1109,13 +1112,21 @@ esctag(EscState *e, Node *func)
|
||||
{
|
||||
Node *savefn;
|
||||
NodeList *ll;
|
||||
|
||||
Type *t;
|
||||
|
||||
USED(e);
|
||||
func->esc = EscFuncTagged;
|
||||
|
||||
// External functions must be assumed unsafe.
|
||||
if(func->nbody == nil)
|
||||
// External functions are assumed unsafe,
|
||||
// unless //go:noescape is given before the declaration.
|
||||
if(func->nbody == nil) {
|
||||
if(func->noescape) {
|
||||
for(t=getinargx(func->type)->type; t; t=t->down)
|
||||
if(haspointers(t->type))
|
||||
t->note = mktag(EscNone);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
savefn = curfn;
|
||||
curfn = func;
|
||||
|
@ -253,6 +253,7 @@ struct Node
|
||||
uchar colas; // OAS resulting from :=
|
||||
uchar diag; // already printed error about this
|
||||
uchar esc; // EscXXX
|
||||
uchar noescape; // func arguments do not escape
|
||||
uchar funcdepth;
|
||||
uchar builtin; // built-in name, like len or close
|
||||
uchar walkdef;
|
||||
@ -943,6 +944,7 @@ EXTERN int compiling_wrappers;
|
||||
EXTERN int pure_go;
|
||||
EXTERN int flag_race;
|
||||
EXTERN int flag_largemodel;
|
||||
EXTERN int noescape;
|
||||
|
||||
EXTERN int nointerface;
|
||||
EXTERN int fieldtrack_enabled;
|
||||
|
@ -1277,8 +1277,11 @@ xfndcl:
|
||||
$$ = $2;
|
||||
if($$ == N)
|
||||
break;
|
||||
if(noescape && $3 != nil)
|
||||
yyerror("can only use //go:noescape with external func implementations");
|
||||
$$->nbody = $3;
|
||||
$$->endlineno = lineno;
|
||||
$$->noescape = noescape;
|
||||
funcbody($$);
|
||||
}
|
||||
|
||||
@ -1462,6 +1465,7 @@ xdcl_list:
|
||||
if(nsyntaxerrors == 0)
|
||||
testdclstack();
|
||||
nointerface = 0;
|
||||
noescape = 0;
|
||||
}
|
||||
|
||||
vardcl_list:
|
||||
|
@ -1436,7 +1436,7 @@ getlinepragma(void)
|
||||
Hist *h;
|
||||
|
||||
c = getr();
|
||||
if(c == 'g' && fieldtrack_enabled)
|
||||
if(c == 'g')
|
||||
goto go;
|
||||
if(c != 'l')
|
||||
goto out;
|
||||
@ -1491,18 +1491,32 @@ getlinepragma(void)
|
||||
goto out;
|
||||
|
||||
go:
|
||||
for(i=1; i<11; i++) {
|
||||
c = getr();
|
||||
if(c != "go:nointerface"[i])
|
||||
goto out;
|
||||
}
|
||||
nointerface = 1;
|
||||
cp = lexbuf;
|
||||
ep = lexbuf+sizeof(lexbuf)-5;
|
||||
*cp++ = 'g'; // already read
|
||||
for(;;) {
|
||||
c = getr();
|
||||
if(c == EOF || c == '\n')
|
||||
if(c == EOF || c >= Runeself)
|
||||
goto out;
|
||||
if(c == '\n')
|
||||
break;
|
||||
if(cp < ep)
|
||||
*cp++ = c;
|
||||
}
|
||||
*cp = 0;
|
||||
ep = strchr(lexbuf, ' ');
|
||||
if(ep != nil)
|
||||
*ep = 0;
|
||||
|
||||
if(strcmp(lexbuf, "go:nointerface") == 0 && fieldtrack_enabled) {
|
||||
nointerface = 1;
|
||||
goto out;
|
||||
}
|
||||
if(strcmp(lexbuf, "go:noescape") == 0) {
|
||||
noescape = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
return c;
|
||||
}
|
||||
|
@ -676,21 +676,21 @@ static const yytype_uint16 yyrline[] =
|
||||
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, 1286, 1315, 1355, 1380, 1398, 1407, 1410,
|
||||
1418, 1422, 1426, 1433, 1439, 1444, 1456, 1459, 1468, 1469,
|
||||
1475, 1476, 1482, 1486, 1492, 1493, 1499, 1503, 1509, 1532,
|
||||
1537, 1543, 1549, 1556, 1565, 1574, 1589, 1595, 1600, 1604,
|
||||
1611, 1624, 1625, 1631, 1637, 1640, 1644, 1650, 1653, 1662,
|
||||
1665, 1666, 1670, 1671, 1677, 1678, 1679, 1680, 1681, 1683,
|
||||
1682, 1697, 1702, 1706, 1710, 1714, 1718, 1723, 1742, 1748,
|
||||
1756, 1760, 1766, 1770, 1776, 1780, 1786, 1790, 1799, 1803,
|
||||
1807, 1811, 1817, 1820, 1828, 1829, 1831, 1832, 1835, 1838,
|
||||
1841, 1844, 1847, 1850, 1853, 1856, 1859, 1862, 1865, 1868,
|
||||
1871, 1874, 1880, 1884, 1888, 1892, 1896, 1900, 1920, 1927,
|
||||
1938, 1939, 1940, 1943, 1944, 1947, 1951, 1961, 1965, 1969,
|
||||
1973, 1977, 1981, 1985, 1991, 1997, 2005, 2013, 2019, 2026,
|
||||
2042, 2060, 2064, 2070, 2073, 2076, 2080, 2090, 2094, 2109,
|
||||
2117, 2118, 2130, 2131, 2134, 2138, 2144, 2148, 2154, 2158
|
||||
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
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -3767,14 +3767,17 @@ yyreduce:
|
||||
(yyval.node) = (yyvsp[(2) - (3)].node);
|
||||
if((yyval.node) == N)
|
||||
break;
|
||||
if(noescape && (yyvsp[(3) - (3)].list) != nil)
|
||||
yyerror("can only use //go:noescape with external func implementations");
|
||||
(yyval.node)->nbody = (yyvsp[(3) - (3)].list);
|
||||
(yyval.node)->endlineno = lineno;
|
||||
(yyval.node)->noescape = noescape;
|
||||
funcbody((yyval.node));
|
||||
}
|
||||
break;
|
||||
|
||||
case 203:
|
||||
#line 1287 "go.y"
|
||||
#line 1290 "go.y"
|
||||
{
|
||||
Node *t;
|
||||
|
||||
@ -3806,7 +3809,7 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 204:
|
||||
#line 1316 "go.y"
|
||||
#line 1319 "go.y"
|
||||
{
|
||||
Node *rcvr, *t;
|
||||
|
||||
@ -3847,7 +3850,7 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 205:
|
||||
#line 1356 "go.y"
|
||||
#line 1359 "go.y"
|
||||
{
|
||||
Sym *s;
|
||||
Type *t;
|
||||
@ -3875,7 +3878,7 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 206:
|
||||
#line 1381 "go.y"
|
||||
#line 1384 "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));
|
||||
@ -3894,7 +3897,7 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 207:
|
||||
#line 1399 "go.y"
|
||||
#line 1402 "go.y"
|
||||
{
|
||||
(yyvsp[(3) - (5)].list) = checkarglist((yyvsp[(3) - (5)].list), 1);
|
||||
(yyval.node) = nod(OTFUNC, N, N);
|
||||
@ -3904,14 +3907,14 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 208:
|
||||
#line 1407 "go.y"
|
||||
#line 1410 "go.y"
|
||||
{
|
||||
(yyval.list) = nil;
|
||||
}
|
||||
break;
|
||||
|
||||
case 209:
|
||||
#line 1411 "go.y"
|
||||
#line 1414 "go.y"
|
||||
{
|
||||
(yyval.list) = (yyvsp[(2) - (3)].list);
|
||||
if((yyval.list) == nil)
|
||||
@ -3920,21 +3923,21 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 210:
|
||||
#line 1419 "go.y"
|
||||
#line 1422 "go.y"
|
||||
{
|
||||
(yyval.list) = nil;
|
||||
}
|
||||
break;
|
||||
|
||||
case 211:
|
||||
#line 1423 "go.y"
|
||||
#line 1426 "go.y"
|
||||
{
|
||||
(yyval.list) = list1(nod(ODCLFIELD, N, (yyvsp[(1) - (1)].node)));
|
||||
}
|
||||
break;
|
||||
|
||||
case 212:
|
||||
#line 1427 "go.y"
|
||||
#line 1430 "go.y"
|
||||
{
|
||||
(yyvsp[(2) - (3)].list) = checkarglist((yyvsp[(2) - (3)].list), 0);
|
||||
(yyval.list) = (yyvsp[(2) - (3)].list);
|
||||
@ -3942,14 +3945,14 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 213:
|
||||
#line 1434 "go.y"
|
||||
#line 1437 "go.y"
|
||||
{
|
||||
closurehdr((yyvsp[(1) - (1)].node));
|
||||
}
|
||||
break;
|
||||
|
||||
case 214:
|
||||
#line 1440 "go.y"
|
||||
#line 1443 "go.y"
|
||||
{
|
||||
(yyval.node) = closurebody((yyvsp[(3) - (4)].list));
|
||||
fixlbrace((yyvsp[(2) - (4)].i));
|
||||
@ -3957,80 +3960,81 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 215:
|
||||
#line 1445 "go.y"
|
||||
#line 1448 "go.y"
|
||||
{
|
||||
(yyval.node) = closurebody(nil);
|
||||
}
|
||||
break;
|
||||
|
||||
case 216:
|
||||
#line 1456 "go.y"
|
||||
#line 1459 "go.y"
|
||||
{
|
||||
(yyval.list) = nil;
|
||||
}
|
||||
break;
|
||||
|
||||
case 217:
|
||||
#line 1460 "go.y"
|
||||
#line 1463 "go.y"
|
||||
{
|
||||
(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(2) - (3)].list));
|
||||
if(nsyntaxerrors == 0)
|
||||
testdclstack();
|
||||
nointerface = 0;
|
||||
noescape = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 219:
|
||||
#line 1470 "go.y"
|
||||
#line 1474 "go.y"
|
||||
{
|
||||
(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list));
|
||||
}
|
||||
break;
|
||||
|
||||
case 221:
|
||||
#line 1477 "go.y"
|
||||
#line 1481 "go.y"
|
||||
{
|
||||
(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list));
|
||||
}
|
||||
break;
|
||||
|
||||
case 222:
|
||||
#line 1483 "go.y"
|
||||
#line 1487 "go.y"
|
||||
{
|
||||
(yyval.list) = list1((yyvsp[(1) - (1)].node));
|
||||
}
|
||||
break;
|
||||
|
||||
case 223:
|
||||
#line 1487 "go.y"
|
||||
#line 1491 "go.y"
|
||||
{
|
||||
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
|
||||
}
|
||||
break;
|
||||
|
||||
case 225:
|
||||
#line 1494 "go.y"
|
||||
#line 1498 "go.y"
|
||||
{
|
||||
(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list));
|
||||
}
|
||||
break;
|
||||
|
||||
case 226:
|
||||
#line 1500 "go.y"
|
||||
#line 1504 "go.y"
|
||||
{
|
||||
(yyval.list) = list1((yyvsp[(1) - (1)].node));
|
||||
}
|
||||
break;
|
||||
|
||||
case 227:
|
||||
#line 1504 "go.y"
|
||||
#line 1508 "go.y"
|
||||
{
|
||||
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
|
||||
}
|
||||
break;
|
||||
|
||||
case 228:
|
||||
#line 1510 "go.y"
|
||||
#line 1514 "go.y"
|
||||
{
|
||||
NodeList *l;
|
||||
|
||||
@ -4056,7 +4060,7 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 229:
|
||||
#line 1533 "go.y"
|
||||
#line 1537 "go.y"
|
||||
{
|
||||
(yyvsp[(1) - (2)].node)->val = (yyvsp[(2) - (2)].val);
|
||||
(yyval.list) = list1((yyvsp[(1) - (2)].node));
|
||||
@ -4064,7 +4068,7 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 230:
|
||||
#line 1538 "go.y"
|
||||
#line 1542 "go.y"
|
||||
{
|
||||
(yyvsp[(2) - (4)].node)->val = (yyvsp[(4) - (4)].val);
|
||||
(yyval.list) = list1((yyvsp[(2) - (4)].node));
|
||||
@ -4073,7 +4077,7 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 231:
|
||||
#line 1544 "go.y"
|
||||
#line 1548 "go.y"
|
||||
{
|
||||
(yyvsp[(2) - (3)].node)->right = nod(OIND, (yyvsp[(2) - (3)].node)->right, N);
|
||||
(yyvsp[(2) - (3)].node)->val = (yyvsp[(3) - (3)].val);
|
||||
@ -4082,7 +4086,7 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 232:
|
||||
#line 1550 "go.y"
|
||||
#line 1554 "go.y"
|
||||
{
|
||||
(yyvsp[(3) - (5)].node)->right = nod(OIND, (yyvsp[(3) - (5)].node)->right, N);
|
||||
(yyvsp[(3) - (5)].node)->val = (yyvsp[(5) - (5)].val);
|
||||
@ -4092,7 +4096,7 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 233:
|
||||
#line 1557 "go.y"
|
||||
#line 1561 "go.y"
|
||||
{
|
||||
(yyvsp[(3) - (5)].node)->right = nod(OIND, (yyvsp[(3) - (5)].node)->right, N);
|
||||
(yyvsp[(3) - (5)].node)->val = (yyvsp[(5) - (5)].val);
|
||||
@ -4102,7 +4106,7 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 234:
|
||||
#line 1566 "go.y"
|
||||
#line 1570 "go.y"
|
||||
{
|
||||
Node *n;
|
||||
|
||||
@ -4114,7 +4118,7 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 235:
|
||||
#line 1575 "go.y"
|
||||
#line 1579 "go.y"
|
||||
{
|
||||
Pkg *pkg;
|
||||
|
||||
@ -4130,14 +4134,14 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 236:
|
||||
#line 1590 "go.y"
|
||||
#line 1594 "go.y"
|
||||
{
|
||||
(yyval.node) = embedded((yyvsp[(1) - (1)].sym));
|
||||
}
|
||||
break;
|
||||
|
||||
case 237:
|
||||
#line 1596 "go.y"
|
||||
#line 1600 "go.y"
|
||||
{
|
||||
(yyval.node) = nod(ODCLFIELD, (yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node));
|
||||
ifacedcl((yyval.node));
|
||||
@ -4145,14 +4149,14 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 238:
|
||||
#line 1601 "go.y"
|
||||
#line 1605 "go.y"
|
||||
{
|
||||
(yyval.node) = nod(ODCLFIELD, N, oldname((yyvsp[(1) - (1)].sym)));
|
||||
}
|
||||
break;
|
||||
|
||||
case 239:
|
||||
#line 1605 "go.y"
|
||||
#line 1609 "go.y"
|
||||
{
|
||||
(yyval.node) = nod(ODCLFIELD, N, oldname((yyvsp[(2) - (3)].sym)));
|
||||
yyerror("cannot parenthesize embedded type");
|
||||
@ -4160,7 +4164,7 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 240:
|
||||
#line 1612 "go.y"
|
||||
#line 1616 "go.y"
|
||||
{
|
||||
// without func keyword
|
||||
(yyvsp[(2) - (4)].list) = checkarglist((yyvsp[(2) - (4)].list), 1);
|
||||
@ -4171,7 +4175,7 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 242:
|
||||
#line 1626 "go.y"
|
||||
#line 1630 "go.y"
|
||||
{
|
||||
(yyval.node) = nod(ONONAME, N, N);
|
||||
(yyval.node)->sym = (yyvsp[(1) - (2)].sym);
|
||||
@ -4180,7 +4184,7 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 243:
|
||||
#line 1632 "go.y"
|
||||
#line 1636 "go.y"
|
||||
{
|
||||
(yyval.node) = nod(ONONAME, N, N);
|
||||
(yyval.node)->sym = (yyvsp[(1) - (2)].sym);
|
||||
@ -4189,56 +4193,56 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 245:
|
||||
#line 1641 "go.y"
|
||||
#line 1645 "go.y"
|
||||
{
|
||||
(yyval.list) = list1((yyvsp[(1) - (1)].node));
|
||||
}
|
||||
break;
|
||||
|
||||
case 246:
|
||||
#line 1645 "go.y"
|
||||
#line 1649 "go.y"
|
||||
{
|
||||
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
|
||||
}
|
||||
break;
|
||||
|
||||
case 247:
|
||||
#line 1650 "go.y"
|
||||
#line 1654 "go.y"
|
||||
{
|
||||
(yyval.list) = nil;
|
||||
}
|
||||
break;
|
||||
|
||||
case 248:
|
||||
#line 1654 "go.y"
|
||||
#line 1658 "go.y"
|
||||
{
|
||||
(yyval.list) = (yyvsp[(1) - (2)].list);
|
||||
}
|
||||
break;
|
||||
|
||||
case 249:
|
||||
#line 1662 "go.y"
|
||||
#line 1666 "go.y"
|
||||
{
|
||||
(yyval.node) = N;
|
||||
}
|
||||
break;
|
||||
|
||||
case 251:
|
||||
#line 1667 "go.y"
|
||||
#line 1671 "go.y"
|
||||
{
|
||||
(yyval.node) = liststmt((yyvsp[(1) - (1)].list));
|
||||
}
|
||||
break;
|
||||
|
||||
case 253:
|
||||
#line 1672 "go.y"
|
||||
#line 1676 "go.y"
|
||||
{
|
||||
(yyval.node) = N;
|
||||
}
|
||||
break;
|
||||
|
||||
case 259:
|
||||
#line 1683 "go.y"
|
||||
#line 1687 "go.y"
|
||||
{
|
||||
(yyvsp[(1) - (2)].node) = nod(OLABEL, (yyvsp[(1) - (2)].node), N);
|
||||
(yyvsp[(1) - (2)].node)->sym = dclstack; // context, for goto restrictions
|
||||
@ -4246,7 +4250,7 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 260:
|
||||
#line 1688 "go.y"
|
||||
#line 1692 "go.y"
|
||||
{
|
||||
NodeList *l;
|
||||
|
||||
@ -4259,7 +4263,7 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 261:
|
||||
#line 1698 "go.y"
|
||||
#line 1702 "go.y"
|
||||
{
|
||||
// will be converted to OFALL
|
||||
(yyval.node) = nod(OXFALL, N, N);
|
||||
@ -4267,35 +4271,35 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 262:
|
||||
#line 1703 "go.y"
|
||||
#line 1707 "go.y"
|
||||
{
|
||||
(yyval.node) = nod(OBREAK, (yyvsp[(2) - (2)].node), N);
|
||||
}
|
||||
break;
|
||||
|
||||
case 263:
|
||||
#line 1707 "go.y"
|
||||
#line 1711 "go.y"
|
||||
{
|
||||
(yyval.node) = nod(OCONTINUE, (yyvsp[(2) - (2)].node), N);
|
||||
}
|
||||
break;
|
||||
|
||||
case 264:
|
||||
#line 1711 "go.y"
|
||||
#line 1715 "go.y"
|
||||
{
|
||||
(yyval.node) = nod(OPROC, (yyvsp[(2) - (2)].node), N);
|
||||
}
|
||||
break;
|
||||
|
||||
case 265:
|
||||
#line 1715 "go.y"
|
||||
#line 1719 "go.y"
|
||||
{
|
||||
(yyval.node) = nod(ODEFER, (yyvsp[(2) - (2)].node), N);
|
||||
}
|
||||
break;
|
||||
|
||||
case 266:
|
||||
#line 1719 "go.y"
|
||||
#line 1723 "go.y"
|
||||
{
|
||||
(yyval.node) = nod(OGOTO, (yyvsp[(2) - (2)].node), N);
|
||||
(yyval.node)->sym = dclstack; // context, for goto restrictions
|
||||
@ -4303,7 +4307,7 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 267:
|
||||
#line 1724 "go.y"
|
||||
#line 1728 "go.y"
|
||||
{
|
||||
(yyval.node) = nod(ORETURN, N, N);
|
||||
(yyval.node)->list = (yyvsp[(2) - (2)].list);
|
||||
@ -4323,7 +4327,7 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 268:
|
||||
#line 1743 "go.y"
|
||||
#line 1747 "go.y"
|
||||
{
|
||||
(yyval.list) = nil;
|
||||
if((yyvsp[(1) - (1)].node) != N)
|
||||
@ -4332,7 +4336,7 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 269:
|
||||
#line 1749 "go.y"
|
||||
#line 1753 "go.y"
|
||||
{
|
||||
(yyval.list) = (yyvsp[(1) - (3)].list);
|
||||
if((yyvsp[(3) - (3)].node) != N)
|
||||
@ -4341,189 +4345,189 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 270:
|
||||
#line 1757 "go.y"
|
||||
#line 1761 "go.y"
|
||||
{
|
||||
(yyval.list) = list1((yyvsp[(1) - (1)].node));
|
||||
}
|
||||
break;
|
||||
|
||||
case 271:
|
||||
#line 1761 "go.y"
|
||||
#line 1765 "go.y"
|
||||
{
|
||||
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
|
||||
}
|
||||
break;
|
||||
|
||||
case 272:
|
||||
#line 1767 "go.y"
|
||||
#line 1771 "go.y"
|
||||
{
|
||||
(yyval.list) = list1((yyvsp[(1) - (1)].node));
|
||||
}
|
||||
break;
|
||||
|
||||
case 273:
|
||||
#line 1771 "go.y"
|
||||
#line 1775 "go.y"
|
||||
{
|
||||
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
|
||||
}
|
||||
break;
|
||||
|
||||
case 274:
|
||||
#line 1777 "go.y"
|
||||
#line 1781 "go.y"
|
||||
{
|
||||
(yyval.list) = list1((yyvsp[(1) - (1)].node));
|
||||
}
|
||||
break;
|
||||
|
||||
case 275:
|
||||
#line 1781 "go.y"
|
||||
#line 1785 "go.y"
|
||||
{
|
||||
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
|
||||
}
|
||||
break;
|
||||
|
||||
case 276:
|
||||
#line 1787 "go.y"
|
||||
#line 1791 "go.y"
|
||||
{
|
||||
(yyval.list) = list1((yyvsp[(1) - (1)].node));
|
||||
}
|
||||
break;
|
||||
|
||||
case 277:
|
||||
#line 1791 "go.y"
|
||||
#line 1795 "go.y"
|
||||
{
|
||||
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
|
||||
}
|
||||
break;
|
||||
|
||||
case 278:
|
||||
#line 1800 "go.y"
|
||||
{
|
||||
(yyval.list) = list1((yyvsp[(1) - (1)].node));
|
||||
}
|
||||
break;
|
||||
|
||||
case 279:
|
||||
#line 1804 "go.y"
|
||||
{
|
||||
(yyval.list) = list1((yyvsp[(1) - (1)].node));
|
||||
}
|
||||
break;
|
||||
|
||||
case 280:
|
||||
case 279:
|
||||
#line 1808 "go.y"
|
||||
{
|
||||
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
|
||||
(yyval.list) = list1((yyvsp[(1) - (1)].node));
|
||||
}
|
||||
break;
|
||||
|
||||
case 281:
|
||||
case 280:
|
||||
#line 1812 "go.y"
|
||||
{
|
||||
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
|
||||
}
|
||||
break;
|
||||
|
||||
case 281:
|
||||
#line 1816 "go.y"
|
||||
{
|
||||
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
|
||||
}
|
||||
break;
|
||||
|
||||
case 282:
|
||||
#line 1817 "go.y"
|
||||
#line 1821 "go.y"
|
||||
{
|
||||
(yyval.list) = nil;
|
||||
}
|
||||
break;
|
||||
|
||||
case 283:
|
||||
#line 1821 "go.y"
|
||||
#line 1825 "go.y"
|
||||
{
|
||||
(yyval.list) = (yyvsp[(1) - (2)].list);
|
||||
}
|
||||
break;
|
||||
|
||||
case 288:
|
||||
#line 1835 "go.y"
|
||||
#line 1839 "go.y"
|
||||
{
|
||||
(yyval.node) = N;
|
||||
}
|
||||
break;
|
||||
|
||||
case 290:
|
||||
#line 1841 "go.y"
|
||||
#line 1845 "go.y"
|
||||
{
|
||||
(yyval.list) = nil;
|
||||
}
|
||||
break;
|
||||
|
||||
case 292:
|
||||
#line 1847 "go.y"
|
||||
#line 1851 "go.y"
|
||||
{
|
||||
(yyval.node) = N;
|
||||
}
|
||||
break;
|
||||
|
||||
case 294:
|
||||
#line 1853 "go.y"
|
||||
#line 1857 "go.y"
|
||||
{
|
||||
(yyval.list) = nil;
|
||||
}
|
||||
break;
|
||||
|
||||
case 296:
|
||||
#line 1859 "go.y"
|
||||
#line 1863 "go.y"
|
||||
{
|
||||
(yyval.list) = nil;
|
||||
}
|
||||
break;
|
||||
|
||||
case 298:
|
||||
#line 1865 "go.y"
|
||||
#line 1869 "go.y"
|
||||
{
|
||||
(yyval.list) = nil;
|
||||
}
|
||||
break;
|
||||
|
||||
case 300:
|
||||
#line 1871 "go.y"
|
||||
#line 1875 "go.y"
|
||||
{
|
||||
(yyval.val).ctype = CTxxx;
|
||||
}
|
||||
break;
|
||||
|
||||
case 302:
|
||||
#line 1881 "go.y"
|
||||
#line 1885 "go.y"
|
||||
{
|
||||
importimport((yyvsp[(2) - (4)].sym), (yyvsp[(3) - (4)].val).u.sval);
|
||||
}
|
||||
break;
|
||||
|
||||
case 303:
|
||||
#line 1885 "go.y"
|
||||
#line 1889 "go.y"
|
||||
{
|
||||
importvar((yyvsp[(2) - (4)].sym), (yyvsp[(3) - (4)].type));
|
||||
}
|
||||
break;
|
||||
|
||||
case 304:
|
||||
#line 1889 "go.y"
|
||||
#line 1893 "go.y"
|
||||
{
|
||||
importconst((yyvsp[(2) - (5)].sym), types[TIDEAL], (yyvsp[(4) - (5)].node));
|
||||
}
|
||||
break;
|
||||
|
||||
case 305:
|
||||
#line 1893 "go.y"
|
||||
#line 1897 "go.y"
|
||||
{
|
||||
importconst((yyvsp[(2) - (6)].sym), (yyvsp[(3) - (6)].type), (yyvsp[(5) - (6)].node));
|
||||
}
|
||||
break;
|
||||
|
||||
case 306:
|
||||
#line 1897 "go.y"
|
||||
#line 1901 "go.y"
|
||||
{
|
||||
importtype((yyvsp[(2) - (4)].type), (yyvsp[(3) - (4)].type));
|
||||
}
|
||||
break;
|
||||
|
||||
case 307:
|
||||
#line 1901 "go.y"
|
||||
#line 1905 "go.y"
|
||||
{
|
||||
if((yyvsp[(2) - (4)].node) == N) {
|
||||
dclcontext = PEXTERN; // since we skip the funcbody below
|
||||
@ -4544,7 +4548,7 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 308:
|
||||
#line 1921 "go.y"
|
||||
#line 1925 "go.y"
|
||||
{
|
||||
(yyval.sym) = (yyvsp[(1) - (1)].sym);
|
||||
structpkg = (yyval.sym)->pkg;
|
||||
@ -4552,7 +4556,7 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 309:
|
||||
#line 1928 "go.y"
|
||||
#line 1932 "go.y"
|
||||
{
|
||||
(yyval.type) = pkgtype((yyvsp[(1) - (1)].sym));
|
||||
importsym((yyvsp[(1) - (1)].sym), OTYPE);
|
||||
@ -4560,14 +4564,14 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 315:
|
||||
#line 1948 "go.y"
|
||||
#line 1952 "go.y"
|
||||
{
|
||||
(yyval.type) = pkgtype((yyvsp[(1) - (1)].sym));
|
||||
}
|
||||
break;
|
||||
|
||||
case 316:
|
||||
#line 1952 "go.y"
|
||||
#line 1956 "go.y"
|
||||
{
|
||||
// predefined name like uint8
|
||||
(yyvsp[(1) - (1)].sym) = pkglookup((yyvsp[(1) - (1)].sym)->name, builtinpkg);
|
||||
@ -4580,49 +4584,49 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 317:
|
||||
#line 1962 "go.y"
|
||||
#line 1966 "go.y"
|
||||
{
|
||||
(yyval.type) = aindex(N, (yyvsp[(3) - (3)].type));
|
||||
}
|
||||
break;
|
||||
|
||||
case 318:
|
||||
#line 1966 "go.y"
|
||||
#line 1970 "go.y"
|
||||
{
|
||||
(yyval.type) = aindex(nodlit((yyvsp[(2) - (4)].val)), (yyvsp[(4) - (4)].type));
|
||||
}
|
||||
break;
|
||||
|
||||
case 319:
|
||||
#line 1970 "go.y"
|
||||
#line 1974 "go.y"
|
||||
{
|
||||
(yyval.type) = maptype((yyvsp[(3) - (5)].type), (yyvsp[(5) - (5)].type));
|
||||
}
|
||||
break;
|
||||
|
||||
case 320:
|
||||
#line 1974 "go.y"
|
||||
#line 1978 "go.y"
|
||||
{
|
||||
(yyval.type) = tostruct((yyvsp[(3) - (4)].list));
|
||||
}
|
||||
break;
|
||||
|
||||
case 321:
|
||||
#line 1978 "go.y"
|
||||
#line 1982 "go.y"
|
||||
{
|
||||
(yyval.type) = tointerface((yyvsp[(3) - (4)].list));
|
||||
}
|
||||
break;
|
||||
|
||||
case 322:
|
||||
#line 1982 "go.y"
|
||||
#line 1986 "go.y"
|
||||
{
|
||||
(yyval.type) = ptrto((yyvsp[(2) - (2)].type));
|
||||
}
|
||||
break;
|
||||
|
||||
case 323:
|
||||
#line 1986 "go.y"
|
||||
#line 1990 "go.y"
|
||||
{
|
||||
(yyval.type) = typ(TCHAN);
|
||||
(yyval.type)->type = (yyvsp[(2) - (2)].type);
|
||||
@ -4631,7 +4635,7 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 324:
|
||||
#line 1992 "go.y"
|
||||
#line 1996 "go.y"
|
||||
{
|
||||
(yyval.type) = typ(TCHAN);
|
||||
(yyval.type)->type = (yyvsp[(3) - (4)].type);
|
||||
@ -4640,7 +4644,7 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 325:
|
||||
#line 1998 "go.y"
|
||||
#line 2002 "go.y"
|
||||
{
|
||||
(yyval.type) = typ(TCHAN);
|
||||
(yyval.type)->type = (yyvsp[(3) - (3)].type);
|
||||
@ -4649,7 +4653,7 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 326:
|
||||
#line 2006 "go.y"
|
||||
#line 2010 "go.y"
|
||||
{
|
||||
(yyval.type) = typ(TCHAN);
|
||||
(yyval.type)->type = (yyvsp[(3) - (3)].type);
|
||||
@ -4658,14 +4662,14 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 327:
|
||||
#line 2014 "go.y"
|
||||
#line 2018 "go.y"
|
||||
{
|
||||
(yyval.type) = functype(nil, (yyvsp[(3) - (5)].list), (yyvsp[(5) - (5)].list));
|
||||
}
|
||||
break;
|
||||
|
||||
case 328:
|
||||
#line 2020 "go.y"
|
||||
#line 2024 "go.y"
|
||||
{
|
||||
(yyval.node) = nod(ODCLFIELD, N, typenod((yyvsp[(2) - (3)].type)));
|
||||
if((yyvsp[(1) - (3)].sym))
|
||||
@ -4675,7 +4679,7 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 329:
|
||||
#line 2027 "go.y"
|
||||
#line 2031 "go.y"
|
||||
{
|
||||
Type *t;
|
||||
|
||||
@ -4692,7 +4696,7 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 330:
|
||||
#line 2043 "go.y"
|
||||
#line 2047 "go.y"
|
||||
{
|
||||
Sym *s;
|
||||
|
||||
@ -4711,49 +4715,49 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 331:
|
||||
#line 2061 "go.y"
|
||||
#line 2065 "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 2065 "go.y"
|
||||
#line 2069 "go.y"
|
||||
{
|
||||
(yyval.node) = nod(ODCLFIELD, N, typenod((yyvsp[(1) - (1)].type)));
|
||||
}
|
||||
break;
|
||||
|
||||
case 333:
|
||||
#line 2070 "go.y"
|
||||
#line 2074 "go.y"
|
||||
{
|
||||
(yyval.list) = nil;
|
||||
}
|
||||
break;
|
||||
|
||||
case 335:
|
||||
#line 2077 "go.y"
|
||||
#line 2081 "go.y"
|
||||
{
|
||||
(yyval.list) = (yyvsp[(2) - (3)].list);
|
||||
}
|
||||
break;
|
||||
|
||||
case 336:
|
||||
#line 2081 "go.y"
|
||||
#line 2085 "go.y"
|
||||
{
|
||||
(yyval.list) = list1(nod(ODCLFIELD, N, typenod((yyvsp[(1) - (1)].type))));
|
||||
}
|
||||
break;
|
||||
|
||||
case 337:
|
||||
#line 2091 "go.y"
|
||||
#line 2095 "go.y"
|
||||
{
|
||||
(yyval.node) = nodlit((yyvsp[(1) - (1)].val));
|
||||
}
|
||||
break;
|
||||
|
||||
case 338:
|
||||
#line 2095 "go.y"
|
||||
#line 2099 "go.y"
|
||||
{
|
||||
(yyval.node) = nodlit((yyvsp[(2) - (2)].val));
|
||||
switch((yyval.node)->val.ctype){
|
||||
@ -4771,7 +4775,7 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 339:
|
||||
#line 2110 "go.y"
|
||||
#line 2114 "go.y"
|
||||
{
|
||||
(yyval.node) = oldname(pkglookup((yyvsp[(1) - (1)].sym)->name, builtinpkg));
|
||||
if((yyval.node)->op != OLITERAL)
|
||||
@ -4780,7 +4784,7 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 341:
|
||||
#line 2119 "go.y"
|
||||
#line 2123 "go.y"
|
||||
{
|
||||
if((yyvsp[(2) - (5)].node)->val.ctype == CTRUNE && (yyvsp[(4) - (5)].node)->val.ctype == CTINT) {
|
||||
(yyval.node) = (yyvsp[(2) - (5)].node);
|
||||
@ -4794,42 +4798,42 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 344:
|
||||
#line 2135 "go.y"
|
||||
#line 2139 "go.y"
|
||||
{
|
||||
(yyval.list) = list1((yyvsp[(1) - (1)].node));
|
||||
}
|
||||
break;
|
||||
|
||||
case 345:
|
||||
#line 2139 "go.y"
|
||||
#line 2143 "go.y"
|
||||
{
|
||||
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
|
||||
}
|
||||
break;
|
||||
|
||||
case 346:
|
||||
#line 2145 "go.y"
|
||||
#line 2149 "go.y"
|
||||
{
|
||||
(yyval.list) = list1((yyvsp[(1) - (1)].node));
|
||||
}
|
||||
break;
|
||||
|
||||
case 347:
|
||||
#line 2149 "go.y"
|
||||
#line 2153 "go.y"
|
||||
{
|
||||
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
|
||||
}
|
||||
break;
|
||||
|
||||
case 348:
|
||||
#line 2155 "go.y"
|
||||
#line 2159 "go.y"
|
||||
{
|
||||
(yyval.list) = list1((yyvsp[(1) - (1)].node));
|
||||
}
|
||||
break;
|
||||
|
||||
case 349:
|
||||
#line 2159 "go.y"
|
||||
#line 2163 "go.y"
|
||||
{
|
||||
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
|
||||
}
|
||||
@ -4837,7 +4841,7 @@ yyreduce:
|
||||
|
||||
|
||||
/* Line 1267 of yacc.c. */
|
||||
#line 4842 "y.tab.c"
|
||||
#line 4846 "y.tab.c"
|
||||
default: break;
|
||||
}
|
||||
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
|
||||
@ -5051,7 +5055,7 @@ yyreturn:
|
||||
}
|
||||
|
||||
|
||||
#line 2163 "go.y"
|
||||
#line 2167 "go.y"
|
||||
|
||||
|
||||
static void
|
||||
|
@ -1274,3 +1274,29 @@ func foo140() interface{} {
|
||||
T: t,
|
||||
}
|
||||
}
|
||||
|
||||
//go:noescape
|
||||
|
||||
func F1([]byte)
|
||||
|
||||
func F2([]byte)
|
||||
|
||||
//go:noescape
|
||||
|
||||
func F3(x []byte) // ERROR "F3 x does not escape"
|
||||
|
||||
func F4(x []byte)
|
||||
|
||||
func G() {
|
||||
var buf1 [10]byte
|
||||
F1(buf1[:]) // ERROR "buf1 does not escape"
|
||||
|
||||
var buf2 [10]byte // ERROR "moved to heap: buf2"
|
||||
F2(buf2[:]) // ERROR "buf2 escapes to heap"
|
||||
|
||||
var buf3 [10]byte
|
||||
F3(buf3[:]) // ERROR "buf3 does not escape"
|
||||
|
||||
var buf4 [10]byte // ERROR "moved to heap: buf4"
|
||||
F4(buf4[:]) // ERROR "buf4 escapes to heap"
|
||||
}
|
||||
|
26
test/fixedbugs/issue4099.go
Normal file
26
test/fixedbugs/issue4099.go
Normal file
@ -0,0 +1,26 @@
|
||||
// errorcheck -0 -m
|
||||
|
||||
// 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.
|
||||
|
||||
// Check go:noescape annotations.
|
||||
|
||||
package p
|
||||
|
||||
// The noescape comment only applies to the next func,
|
||||
// which must not have a body.
|
||||
|
||||
//go:noescape
|
||||
|
||||
func F1([]byte)
|
||||
|
||||
func F2([]byte)
|
||||
|
||||
func G() {
|
||||
var buf1 [10]byte
|
||||
F1(buf1[:]) // ERROR "buf1 does not escape"
|
||||
|
||||
var buf2 [10]byte // ERROR "moved to heap: buf2"
|
||||
F2(buf2[:]) // ERROR "buf2 escapes to heap"
|
||||
}
|
Loading…
Reference in New Issue
Block a user