1
0
mirror of https://github.com/golang/go synced 2024-11-25 04:47:57 -07:00

gc: fix parenthesization check

Cannot use paren field in Node because all
instances of a given symbol name use the same Node.

Fixes #1022.

R=ken2
CC=golang-dev
https://golang.org/cl/2015043
This commit is contained in:
Russ Cox 2010-08-23 23:10:25 -04:00
parent 7ddbe79842
commit b1311cbc93
4 changed files with 38 additions and 16 deletions

View File

@ -209,7 +209,6 @@ struct Node
uchar dodata; // compile literal assignment as data statement uchar dodata; // compile literal assignment as data statement
uchar used; uchar used;
uchar isddd; uchar isddd;
uchar paren; // was parenthesized
uchar pun; // dont registerize variable ONAME uchar pun; // dont registerize variable ONAME
// most nodes // most nodes
@ -411,6 +410,7 @@ enum
OTINTER, OTINTER,
OTFUNC, OTFUNC,
OTARRAY, OTARRAY,
OTPAREN,
// misc // misc
ODDD, ODDD,

View File

@ -58,7 +58,7 @@
%type <node> name_or_type non_expr_type %type <node> name_or_type non_expr_type
%type <node> new_name dcl_name oexpr typedclname %type <node> new_name dcl_name oexpr typedclname
%type <node> onew_name %type <node> onew_name
%type <node> osimple_stmt pexpr %type <node> osimple_stmt pexpr pexpr_no_paren
%type <node> pseudocall range_stmt select_stmt %type <node> pseudocall range_stmt select_stmt
%type <node> simple_stmt %type <node> simple_stmt
%type <node> switch_stmt uexpr %type <node> switch_stmt uexpr
@ -812,7 +812,7 @@ pseudocall:
$$->list = $3; $$->list = $3;
} }
pexpr: pexpr_no_paren:
LLITERAL LLITERAL
{ {
$$ = nodlit($1); $$ = nodlit($1);
@ -829,11 +829,6 @@ pexpr:
} }
$$ = nod(OXDOT, $1, newname($3)); $$ = nod(OXDOT, $1, newname($3));
} }
| '(' expr_or_type ')'
{
$$ = $2;
$$->paren++;
}
| pexpr '.' '(' expr_or_type ')' | pexpr '.' '(' expr_or_type ')'
{ {
$$ = nod(ODOTTYPE, $1, $4); $$ = nod(ODOTTYPE, $1, $4);
@ -873,16 +868,28 @@ pexpr:
if($2 == LBODY) if($2 == LBODY)
loophack = 1; loophack = 1;
} }
| pexpr '{' braced_keyval_list '}' | pexpr_no_paren '{' braced_keyval_list '}'
{ {
if($1->paren)
yyerror("cannot parenthesize type in composite literal");
// composite expression // composite expression
$$ = nod(OCOMPLIT, N, $1); $$ = nod(OCOMPLIT, N, $1);
$$->list = $3; $$->list = $3;
} }
| '(' expr_or_type ')' '{' braced_keyval_list '}'
{
yyerror("cannot parenthesize type in composite literal");
// composite expression
$$ = nod(OCOMPLIT, N, $2);
$$->list = $5;
}
| fnliteral | fnliteral
pexpr:
pexpr_no_paren
| '(' expr_or_type ')'
{
$$ = $2;
}
expr_or_type: expr_or_type:
expr expr
| non_expr_type %prec PreferToRightParen | non_expr_type %prec PreferToRightParen
@ -965,8 +972,7 @@ ntype:
| dotname | dotname
| '(' ntype ')' | '(' ntype ')'
{ {
$$ = $2; $$ = nod(OTPAREN, $2, N);
$$->paren++;
} }
non_expr_type: non_expr_type:
@ -985,8 +991,7 @@ non_recvchantype:
| dotname | dotname
| '(' ntype ')' | '(' ntype ')'
{ {
$$ = $2; $$ = nod(OTPAREN, $2, N);
$$->paren++;
} }
convtype: convtype:
@ -1146,7 +1151,7 @@ fndcl:
yyerror("bad receiver in method"); yyerror("bad receiver in method");
break; break;
} }
if(rcvr->right->paren || (rcvr->right->op == OIND && rcvr->right->left->paren)) if(rcvr->right->op == OTPAREN || (rcvr->right->op == OIND && rcvr->right->left->op == OTPAREN))
yyerror("cannot parenthesize receiver type"); yyerror("cannot parenthesize receiver type");
$$ = nod(ODCLFUNC, N, N); $$ = nod(ODCLFUNC, N, N);

View File

@ -66,6 +66,7 @@ exprfmt(Fmt *f, Node *n, int prec)
case OPLUS: case OPLUS:
case ORECV: case ORECV:
case OCONVIFACE: case OCONVIFACE:
case OTPAREN:
nprec = 7; nprec = 7;
break; break;
@ -165,6 +166,12 @@ exprfmt(Fmt *f, Node *n, int prec)
fmtprint(f, "[]"); fmtprint(f, "[]");
exprfmt(f, n->left, PFIXME); exprfmt(f, n->left, PFIXME);
break; break;
case OTPAREN:
fmtprint(f, "(");
exprfmt(f, n->left, 0);
fmtprint(f, ")");
break;
case OTMAP: case OTMAP:
fmtprint(f, "map["); fmtprint(f, "map[");

View File

@ -169,6 +169,16 @@ reswitch:
goto error; goto error;
break; break;
case OTPAREN:
ok |= Etype;
l = typecheck(&n->left, Etype);
if(l->type == T)
goto error;
n->op = OTYPE;
n->type = l->type;
n->left = N;
break;
case OTARRAY: case OTARRAY:
ok |= Etype; ok |= Etype;
t = typ(TARRAY); t = typ(TARRAY);