mirror of
https://github.com/golang/go
synced 2024-11-25 12:17:56 -07:00
back to T{x}, stricter handling of T(x) vs x.(T)
R=ken DELTA=131 (60 added, 41 deleted, 30 changed) OCL=25617 CL=25633
This commit is contained in:
parent
be2edb5761
commit
49cc649e59
@ -327,9 +327,9 @@ enum
|
|||||||
ONOT, OCOM, OPLUS, OMINUS, OSEND, ORECV,
|
ONOT, OCOM, OPLUS, OMINUS, OSEND, ORECV,
|
||||||
OLITERAL, OREGISTER, OINDREG,
|
OLITERAL, OREGISTER, OINDREG,
|
||||||
OKEY, OPARAM,
|
OKEY, OPARAM,
|
||||||
|
OCOMPOS,
|
||||||
OCONV,
|
OCONV,
|
||||||
OCONVDOT,
|
ODOTTYPE,
|
||||||
OCONVPAREN,
|
|
||||||
OBAD,
|
OBAD,
|
||||||
|
|
||||||
OEXTEND, // 6g internal
|
OEXTEND, // 6g internal
|
||||||
|
@ -51,7 +51,7 @@
|
|||||||
%type <node> stmt_list_r Astmt_list_r Bstmt_list_r
|
%type <node> stmt_list_r Astmt_list_r Bstmt_list_r
|
||||||
%type <node> Astmt Bstmt
|
%type <node> Astmt Bstmt
|
||||||
%type <node> for_stmt for_body for_header
|
%type <node> for_stmt for_body for_header
|
||||||
%type <node> if_stmt if_body if_header select_stmt
|
%type <node> if_stmt if_body if_header select_stmt condition
|
||||||
%type <node> simple_stmt osimple_stmt range_stmt semi_stmt
|
%type <node> simple_stmt osimple_stmt range_stmt semi_stmt
|
||||||
%type <node> expr uexpr pexpr expr_list oexpr oexpr_list expr_list_r
|
%type <node> expr uexpr pexpr expr_list oexpr oexpr_list expr_list_r
|
||||||
%type <node> exprsym3_list_r exprsym3
|
%type <node> exprsym3_list_r exprsym3
|
||||||
@ -89,6 +89,13 @@
|
|||||||
%left '+' '-' '|' '^'
|
%left '+' '-' '|' '^'
|
||||||
%left '*' '/' '%' '&' LLSH LRSH
|
%left '*' '/' '%' '&' LLSH LRSH
|
||||||
|
|
||||||
|
/*
|
||||||
|
* resolve { vs condition in favor of condition
|
||||||
|
*/
|
||||||
|
%left '{'
|
||||||
|
%left Condition
|
||||||
|
|
||||||
|
|
||||||
%%
|
%%
|
||||||
file:
|
file:
|
||||||
package import_there imports oxdcl_list
|
package import_there imports oxdcl_list
|
||||||
@ -562,7 +569,7 @@ for_header:
|
|||||||
$$->ntest = $3;
|
$$->ntest = $3;
|
||||||
$$->nincr = $5;
|
$$->nincr = $5;
|
||||||
}
|
}
|
||||||
| osimple_stmt
|
| condition
|
||||||
{
|
{
|
||||||
// normal test
|
// normal test
|
||||||
$$ = nod(OFOR, N, N);
|
$$ = nod(OFOR, N, N);
|
||||||
@ -591,15 +598,30 @@ for_stmt:
|
|||||||
$$ = $2;
|
$$ = $2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* using cond instead of osimple_stmt creates
|
||||||
|
* a shift/reduce conflict on an input like
|
||||||
|
*
|
||||||
|
* if x == []int { true } { true }
|
||||||
|
*
|
||||||
|
* at the first {, giving us an opportunity
|
||||||
|
* to resolve it by reduce, which implements
|
||||||
|
* the rule about { } inside if conditions
|
||||||
|
* needing parens.
|
||||||
|
*/
|
||||||
|
condition:
|
||||||
|
osimple_stmt %prec Condition
|
||||||
|
|
||||||
|
|
||||||
if_header:
|
if_header:
|
||||||
osimple_stmt
|
condition
|
||||||
{
|
{
|
||||||
// test
|
// test
|
||||||
$$ = nod(OIF, N, N);
|
$$ = nod(OIF, N, N);
|
||||||
$$->ninit = N;
|
$$->ninit = N;
|
||||||
$$->ntest = $1;
|
$$->ntest = $1;
|
||||||
}
|
}
|
||||||
| osimple_stmt ';' osimple_stmt
|
| osimple_stmt ';' condition
|
||||||
{
|
{
|
||||||
// init ; test
|
// init ; test
|
||||||
$$ = nod(OIF, N, N);
|
$$ = nod(OIF, N, N);
|
||||||
@ -791,7 +813,7 @@ pexpr:
|
|||||||
}
|
}
|
||||||
| pexpr '.' '(' type ')'
|
| pexpr '.' '(' type ')'
|
||||||
{
|
{
|
||||||
$$ = nod(OCONVDOT, $1, N);
|
$$ = nod(ODOTTYPE, $1, N);
|
||||||
$$->type = $4;
|
$$->type = $4;
|
||||||
}
|
}
|
||||||
| pexpr '[' expr ']'
|
| pexpr '[' expr ']'
|
||||||
@ -841,24 +863,22 @@ pexpr:
|
|||||||
$$ = nod(OMAKE, $5, N);
|
$$ = nod(OMAKE, $5, N);
|
||||||
$$->type = $3;
|
$$->type = $3;
|
||||||
}
|
}
|
||||||
| convtype '(' braced_keyexpr_list ')'
|
| convtype '(' expr ')'
|
||||||
{
|
{
|
||||||
// typed literal
|
// conversion
|
||||||
$$ = rev($3);
|
$$ = rev($3);
|
||||||
if($$ == N)
|
if($$ == N)
|
||||||
$$ = nod(OEMPTY, N, N);
|
$$ = nod(OEMPTY, N, N);
|
||||||
$$ = nod(OCONVPAREN, $$, N);
|
$$ = nod(OCONV, $$, N);
|
||||||
$$->type = $1;
|
$$->type = $1;
|
||||||
}
|
}
|
||||||
| convtype '{' braced_keyexpr_list '}'
|
| convtype '{' braced_keyexpr_list '}'
|
||||||
{
|
{
|
||||||
if(!debug['{'])
|
// composite expression
|
||||||
warn("braces should now be parens");
|
|
||||||
// composite literal
|
|
||||||
$$ = rev($3);
|
$$ = rev($3);
|
||||||
if($$ == N)
|
if($$ == N)
|
||||||
$$ = nod(OEMPTY, N, N);
|
$$ = nod(OEMPTY, N, N);
|
||||||
$$ = nod(OCONVPAREN, $$, N);
|
$$ = nod(OCOMPOS, $$, N);
|
||||||
$$->type = $1;
|
$$->type = $1;
|
||||||
}
|
}
|
||||||
| fnliteral
|
| fnliteral
|
||||||
|
@ -634,9 +634,9 @@ opnames[] =
|
|||||||
[OXCASE] = "XCASE",
|
[OXCASE] = "XCASE",
|
||||||
[OCMP] = "CMP",
|
[OCMP] = "CMP",
|
||||||
[OFALL] = "FALL",
|
[OFALL] = "FALL",
|
||||||
|
[OCOMPOS] = "COMPOS",
|
||||||
|
[ODOTTYPE] = "DOTTYPE",
|
||||||
[OCONV] = "CONV",
|
[OCONV] = "CONV",
|
||||||
[OCONVDOT] = "CONVDOT",
|
|
||||||
[OCONVPAREN] = "CONVPAREN",
|
|
||||||
[OCOM] = "COM",
|
[OCOM] = "COM",
|
||||||
[OCONST] = "CONST",
|
[OCONST] = "CONST",
|
||||||
[OCONTINUE] = "CONTINUE",
|
[OCONTINUE] = "CONTINUE",
|
||||||
|
@ -510,7 +510,7 @@ loop:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OCONVDOT:
|
case ODOTTYPE:
|
||||||
if(cl == 2 && cr == 1) {
|
if(cl == 2 && cr == 1) {
|
||||||
// a,b = i.(T)
|
// a,b = i.(T)
|
||||||
walktype(r->left, Erv);
|
walktype(r->left, Erv);
|
||||||
@ -593,13 +593,41 @@ loop:
|
|||||||
goto ret;
|
goto ret;
|
||||||
|
|
||||||
case OCONV:
|
case OCONV:
|
||||||
case OCONVDOT:
|
case ODOTTYPE:
|
||||||
case OCONVPAREN:
|
|
||||||
if(top != Erv)
|
if(top != Erv)
|
||||||
goto nottop;
|
goto nottop;
|
||||||
walkconv(n);
|
walkconv(n);
|
||||||
goto ret;
|
goto ret;
|
||||||
|
|
||||||
|
case OCOMPOS:
|
||||||
|
t = n->type;
|
||||||
|
if(t == T)
|
||||||
|
goto ret;
|
||||||
|
l = n->left;
|
||||||
|
if(l == N)
|
||||||
|
goto ret;
|
||||||
|
walktype(l, Erv);
|
||||||
|
|
||||||
|
// structure literal
|
||||||
|
if(t->etype == TSTRUCT) {
|
||||||
|
indir(n, structlit(n, N));
|
||||||
|
goto ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// array literal
|
||||||
|
if(t->etype == TARRAY) {
|
||||||
|
indir(n, arraylit(n, N));
|
||||||
|
goto ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// map literal
|
||||||
|
if(t->etype == TMAP) {
|
||||||
|
indir(n, maplit(n, N));
|
||||||
|
goto ret;
|
||||||
|
}
|
||||||
|
yyerror("invalid type for composite literal: %T", t);
|
||||||
|
goto ret;
|
||||||
|
|
||||||
case ORETURN:
|
case ORETURN:
|
||||||
if(top != Etop)
|
if(top != Etop)
|
||||||
goto nottop;
|
goto nottop;
|
||||||
@ -887,11 +915,7 @@ loop:
|
|||||||
case OADDR:
|
case OADDR:
|
||||||
if(top != Erv)
|
if(top != Erv)
|
||||||
goto nottop;
|
goto nottop;
|
||||||
if(n->left->op == OCONVPAREN && n->left->type != T)
|
if(n->left->op == OCOMPOS && n->left->type != T) {
|
||||||
switch(n->left->type->etype) {
|
|
||||||
case TSTRUCT:
|
|
||||||
case TARRAY:
|
|
||||||
case TMAP:
|
|
||||||
// turn &Point(1, 2) or &[]int(1, 2) or &[...]int(1, 2) into allocation.
|
// turn &Point(1, 2) or &[]int(1, 2) or &[...]int(1, 2) into allocation.
|
||||||
// initialize with
|
// initialize with
|
||||||
// nvar := new(*Point);
|
// nvar := new(*Point);
|
||||||
@ -920,13 +944,14 @@ loop:
|
|||||||
maplit(n->left, nstar);
|
maplit(n->left, nstar);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fatal("addr lit %T", n->left->type);
|
goto badlit;
|
||||||
}
|
}
|
||||||
|
|
||||||
indir(n, nvar);
|
indir(n, nvar);
|
||||||
goto ret;
|
goto ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
badlit:
|
||||||
if(istype(n->left->type, TFUNC) && n->left->class == PFUNC) {
|
if(istype(n->left->type, TFUNC) && n->left->class == PFUNC) {
|
||||||
if(!n->diag) {
|
if(!n->diag) {
|
||||||
n->diag = 1;
|
n->diag = 1;
|
||||||
@ -1130,10 +1155,12 @@ walkbool(Node *n)
|
|||||||
yyerror("IF and FOR require a boolean type");
|
yyerror("IF and FOR require a boolean type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
walkconv(Node *n)
|
walkconv(Node *n)
|
||||||
{
|
{
|
||||||
int et, op;
|
int et;
|
||||||
Type *t;
|
Type *t;
|
||||||
Node *l;
|
Node *l;
|
||||||
|
|
||||||
@ -1145,17 +1172,20 @@ walkconv(Node *n)
|
|||||||
return;
|
return;
|
||||||
walktype(l, Erv);
|
walktype(l, Erv);
|
||||||
|
|
||||||
switch(t->etype) {
|
convlit1(l, t, 1);
|
||||||
case TSTRUCT:
|
|
||||||
case TMAP:
|
// if using .(T), interface assertion.
|
||||||
case TARRAY:
|
if(n->op == ODOTTYPE) {
|
||||||
break;
|
// interface conversion
|
||||||
default:
|
et = ifaceas(n->type, l->type, 1);
|
||||||
convlit1(l, t, 1);
|
if(et != Inone) {
|
||||||
|
indir(n, ifaceop(n->type, l, et));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
op = n->op;
|
// otherwise, conversion.
|
||||||
n->op = OCONV; // generic conversion
|
|
||||||
|
|
||||||
// nil conversion
|
// nil conversion
|
||||||
if(eqtype(t, l->type, 0)) {
|
if(eqtype(t, l->type, 0)) {
|
||||||
@ -1218,37 +1248,7 @@ walkconv(Node *n)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// possible interface conversion if using .(T)
|
bad:
|
||||||
if(op == OCONVDOT) {
|
|
||||||
// interface conversion
|
|
||||||
et = ifaceas(n->type, l->type, 1);
|
|
||||||
if(et != Inone) {
|
|
||||||
indir(n, ifaceop(n->type, l, et));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// possible composite literal if using T()
|
|
||||||
if(op == OCONVPAREN) {
|
|
||||||
// structure literal
|
|
||||||
if(t->etype == TSTRUCT) {
|
|
||||||
indir(n, structlit(n, N));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// array literal
|
|
||||||
if(t->etype == TARRAY) {
|
|
||||||
indir(n, arraylit(n, N));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// map literal
|
|
||||||
if(t->etype == TMAP) {
|
|
||||||
indir(n, maplit(n, N));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(l->type != T)
|
if(l->type != T)
|
||||||
yyerror("invalid conversion: %T to %T", l->type, t);
|
yyerror("invalid conversion: %T to %T", l->type, t);
|
||||||
else if(n->left->op == OLIST)
|
else if(n->left->op == OLIST)
|
||||||
@ -1256,7 +1256,6 @@ walkconv(Node *n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* return the first type
|
* return the first type
|
||||||
*/
|
*/
|
||||||
@ -3146,7 +3145,7 @@ multi:
|
|||||||
n = list(n, a);
|
n = list(n, a);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OCONVDOT:
|
case ODOTTYPE:
|
||||||
// a,b := i.(T)
|
// a,b := i.(T)
|
||||||
if(cl != 2)
|
if(cl != 2)
|
||||||
goto badt;
|
goto badt;
|
||||||
|
Loading…
Reference in New Issue
Block a user