Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(399)

Delta Between Two Patch Sets: src/cmd/gc/typecheck.c

Issue 4634073: code review 4634073: gc: Escape analysis. (Closed)
Left Patch Set: diff -r 67b160cd5fa4 https://go.googlecode.com/hg/ Created 13 years, 8 months ago
Right Patch Set: diff -r adfa9f5cca40 https://go.googlecode.com/hg/ Created 13 years, 7 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « src/cmd/gc/subr.c ('k') | test/escape2.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 // Copyright 2009 The Go Authors. All rights reserved. 1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 /* 5 /*
6 * type check the whole tree of an expression. 6 * type check the whole tree of an expression.
7 * calculates expression types. 7 * calculates expression types.
8 * evaluates compile time constants. 8 * evaluates compile time constants.
9 * marks variables that escape the local frame. 9 * marks variables that escape the local frame.
10 * rewrites n->op to be more specific in some cases. 10 * rewrites n->op to be more specific in some cases.
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 Val v; 116 Val v;
117 char *why; 117 char *why;
118 118
119 // cannot type check until all the source has been parsed 119 // cannot type check until all the source has been parsed
120 if(!typecheckok) 120 if(!typecheckok)
121 fatal("early typecheck"); 121 fatal("early typecheck");
122 122
123 n = *np; 123 n = *np;
124 if(n == N) 124 if(n == N)
125 return N; 125 return N;
126 ········
127 lno = setlineno(n);
128
129 // Skip over parens.
130 while(n->op == OPAREN)
131 n = n->left;
126 132
127 // Resolve definition of name and value of iota lazily. 133 // Resolve definition of name and value of iota lazily.
128 n = resolve(n); 134 n = resolve(n);
135
129 *np = n; 136 *np = n;
130 137
131 // Skip typecheck if already done. 138 // Skip typecheck if already done.
132 // But re-typecheck ONAME/OTYPE/OLITERAL/OPACK node in case context has changed. 139 // But re-typecheck ONAME/OTYPE/OLITERAL/OPACK node in case context has changed.
133 if(n->typecheck == 1) { 140 if(n->typecheck == 1) {
134 switch(n->op) { 141 switch(n->op) {
135 case ONAME: 142 case ONAME:
136 case OTYPE: 143 case OTYPE:
137 case OLITERAL: 144 case OLITERAL:
138 case OPACK: 145 case OPACK:
139 break; 146 break;
140 default: 147 default:
148 lineno = lno;
141 return n; 149 return n;
142 } 150 }
143 } 151 }
144 152
145 if(n->typecheck == 2) { 153 if(n->typecheck == 2) {
146 yyerror("typechecking loop"); 154 yyerror("typechecking loop");
155 lineno = lno;
147 return n; 156 return n;
148 } 157 }
149 n->typecheck = 2; 158 n->typecheck = 2;
150 159
151 lno = setlineno(n);
152 if(n->sym) { 160 if(n->sym) {
153 if(n->op == ONAME && n->etype != 0 && !(top & Ecall)) { 161 if(n->op == ONAME && n->etype != 0 && !(top & Ecall)) {
154 yyerror("use of builtin %S not in function call", n->sym ); 162 yyerror("use of builtin %S not in function call", n->sym );
155 goto error; 163 goto error;
156 } 164 }
157 165
158 // a dance to handle forward-declared recursive pointer types. 166 // a dance to handle forward-declared recursive pointer types.
159 if(n->op == OTYPE && (ft = getforwtype(n->ntype)) != T) 167 if(n->op == OTYPE && (ft = getforwtype(n->ntype)) != T)
160 defertypecopy(n, ft); 168 defertypecopy(n, ft);
161 169
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 ········ 239 ········
232 case OTARRAY: 240 case OTARRAY:
233 ok |= Etype; 241 ok |= Etype;
234 t = typ(TARRAY); 242 t = typ(TARRAY);
235 l = n->left; 243 l = n->left;
236 r = n->right; 244 r = n->right;
237 if(l == nil) { 245 if(l == nil) {
238 t->bound = -1; // slice 246 t->bound = -1; // slice
239 } else if(l->op == ODDD) { 247 } else if(l->op == ODDD) {
240 t->bound = -100; // to be filled in 248 t->bound = -100; // to be filled in
249 if(!(top&Ecomplit))
250 yyerror("use of [...] array outside of array lit eral");
241 } else { 251 } else {
242 l = typecheck(&n->left, Erv); 252 l = typecheck(&n->left, Erv);
243 switch(consttype(l)) { 253 switch(consttype(l)) {
244 case CTINT: 254 case CTINT:
245 v = l->val; 255 v = l->val;
246 break; 256 break;
247 case CTFLT: 257 case CTFLT:
248 v = toint(l->val); 258 v = toint(l->val);
249 break; 259 break;
250 default: 260 default:
(...skipping 773 matching lines...) Expand 10 before | Expand all | Expand 10 after
1024 n->type = types[TINT]; 1034 n->type = types[TINT];
1025 typecheck(&n->left, Erv); 1035 typecheck(&n->left, Erv);
1026 typecheck(&n->right, Erv); 1036 typecheck(&n->right, Erv);
1027 if(n->left->type == T || n->right->type == T) 1037 if(n->left->type == T || n->right->type == T)
1028 goto error; 1038 goto error;
1029 defaultlit(&n->left, T); 1039 defaultlit(&n->left, T);
1030 defaultlit(&n->right, T); 1040 defaultlit(&n->right, T);
1031 ················ 1041 ················
1032 // copy([]byte, string) 1042 // copy([]byte, string)
1033 if(isslice(n->left->type) && n->right->type->etype == TSTRING) { 1043 if(isslice(n->left->type) && n->right->type->etype == TSTRING) {
1034 » » » if (n->left->type->type == types[TUINT8]) 1044 » » » if(n->left->type->type == types[TUINT8])
1035 goto ret; 1045 goto ret;
1036 yyerror("arguments to copy have different element types: %lT and string", n->left->type); 1046 yyerror("arguments to copy have different element types: %lT and string", n->left->type);
1037 goto error; 1047 goto error;
1038 } 1048 }
1039 ······························· 1049 ·······························
1040 if(!isslice(n->left->type) || !isslice(n->right->type)) { 1050 if(!isslice(n->left->type) || !isslice(n->right->type)) {
1041 if(!isslice(n->left->type) && !isslice(n->right->type)) 1051 if(!isslice(n->left->type) && !isslice(n->right->type))
1042 yyerror("arguments to copy must be slices; have %lT, %lT", n->left->type, n->right->type); 1052 yyerror("arguments to copy must be slices; have %lT, %lT", n->left->type, n->right->type);
1043 else if(!isslice(n->left->type)) 1053 else if(!isslice(n->left->type))
1044 yyerror("first argument to copy should be slice; have %lT", n->left->type); 1054 yyerror("first argument to copy should be slice; have %lT", n->left->type);
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
1338 t = n->type; 1348 t = n->type;
1339 if(t && !t->funarg && n->op != OTYPE) { 1349 if(t && !t->funarg && n->op != OTYPE) {
1340 switch(t->etype) { 1350 switch(t->etype) {
1341 case TFUNC: // might have TANY; wait until its called 1351 case TFUNC: // might have TANY; wait until its called
1342 case TANY: 1352 case TANY:
1343 case TFORW: 1353 case TFORW:
1344 case TIDEAL: 1354 case TIDEAL:
1345 case TNIL: 1355 case TNIL:
1346 case TBLANK: 1356 case TBLANK:
1347 break; 1357 break;
1348 case TARRAY:
1349 if(t->bound == -100) {
1350 yyerror("use of [...] array outside of array lit eral");
1351 t->bound = 1;
1352 }
1353 default: 1358 default:
1354 checkwidth(t); 1359 checkwidth(t);
1355 } 1360 }
1356 } 1361 }
1357 1362
1358 // TODO(rsc): should not need to check importpkg, 1363 // TODO(rsc): should not need to check importpkg,
1359 // but reflect mentions unsafe.Pointer. 1364 // but reflect mentions unsafe.Pointer.
1360 if(safemode && !incannedimport && !importpkg && t && t->etype == TUNSAFE PTR) 1365 if(safemode && !incannedimport && !importpkg && t && t->etype == TUNSAFE PTR)
1361 yyerror("cannot use unsafe.Pointer"); 1366 yyerror("cannot use unsafe.Pointer");
1362 1367
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
1593 return 1; 1598 return 1;
1594 } 1599 }
1595 1600
1596 if(f2 != T) { 1601 if(f2 != T) {
1597 tt = n->left->type; 1602 tt = n->left->type;
1598 dowidth(tt); 1603 dowidth(tt);
1599 rcvr = getthisx(f2->type)->type->type; 1604 rcvr = getthisx(f2->type)->type->type;
1600 if(!eqtype(rcvr, tt)) { 1605 if(!eqtype(rcvr, tt)) {
1601 if(rcvr->etype == tptr && eqtype(rcvr->type, tt)) { 1606 if(rcvr->etype == tptr && eqtype(rcvr->type, tt)) {
1602 checklvalue(n->left, "call pointer method on"); 1607 checklvalue(n->left, "call pointer method on");
1603 » » » » if (!debug['s']) addrescapes(n->left); 1608 » » » » if(!debug['s'])
1609 » » » » » addrescapes(n->left);
1604 n->left = nod(OADDR, n->left, N); 1610 n->left = nod(OADDR, n->left, N);
1605 n->left->implicit = 1; 1611 n->left->implicit = 1;
1606 typecheck(&n->left, Etype|Erv); 1612 typecheck(&n->left, Etype|Erv);
1607 } else if(tt->etype == tptr && eqtype(tt->type, rcvr)) { 1613 } else if(tt->etype == tptr && eqtype(tt->type, rcvr)) {
1608 n->left = nod(OIND, n->left, N); 1614 n->left = nod(OIND, n->left, N);
1609 n->left->implicit = 1; 1615 n->left->implicit = 1;
1610 typecheck(&n->left, Etype|Erv); 1616 typecheck(&n->left, Etype|Erv);
1611 } else { 1617 } else {
1612 // method is attached to wrong type? 1618 // method is attached to wrong type?
1613 fatal("method mismatch: %T for %T", rcvr, tt); 1619 fatal("method mismatch: %T for %T", rcvr, tt);
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
1967 lno = lineno; 1973 lno = lineno;
1968 1974
1969 if(n->right == N) { 1975 if(n->right == N) {
1970 if(n->list != nil) 1976 if(n->list != nil)
1971 setlineno(n->list->n); 1977 setlineno(n->list->n);
1972 yyerror("missing type in composite literal"); 1978 yyerror("missing type in composite literal");
1973 goto error; 1979 goto error;
1974 } 1980 }
1975 1981
1976 setlineno(n->right); 1982 setlineno(n->right);
1977 » l = typecheck(&n->right /* sic */, Etype); 1983 » l = typecheck(&n->right /* sic */, Etype|Ecomplit);
1978 if((t = l->type) == T) 1984 if((t = l->type) == T)
1979 goto error; 1985 goto error;
1980 nerr = nerrors; 1986 nerr = nerrors;
1981 1987
1982 // can omit type on composite literal values if the outer 1988 // can omit type on composite literal values if the outer
1983 // composite literal is array, slice, or map, and the· 1989 // composite literal is array, slice, or map, and the·
1984 // element type is itself a struct, array, slice, or map. 1990 // element type is itself a struct, array, slice, or map.
1985 pushtype = T; 1991 pushtype = T;
1986 if(t->etype == TARRAY || t->etype == TMAP) { 1992 if(t->etype == TARRAY || t->etype == TMAP) {
1987 pushtype = t->type; 1993 pushtype = t->type;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2035 setlineno(l); 2041 setlineno(l);
2036 yyerror("array index %d out of bounds [0 :%d]", len, t->bound); 2042 yyerror("array index %d out of bounds [0 :%d]", len, t->bound);
2037 t->bound = -1; // no more errors 2043 t->bound = -1; // no more errors
2038 } 2044 }
2039 } 2045 }
2040 2046
2041 if(l->right->op == OCOMPLIT && l->right->right == N && p ushtype != T) 2047 if(l->right->op == OCOMPLIT && l->right->right == N && p ushtype != T)
2042 l->right->right = typenod(pushtype); 2048 l->right->right = typenod(pushtype);
2043 typecheck(&l->right, Erv); 2049 typecheck(&l->right, Erv);
2044 defaultlit(&l->right, t->type); 2050 defaultlit(&l->right, t->type);
2045 » » » l->right = assignconv(l->right, t->type, "array index"); 2051 » » » l->right = assignconv(l->right, t->type, "array element" );
2046 } 2052 }
2047 if(t->bound == -100) 2053 if(t->bound == -100)
2048 t->bound = len; 2054 t->bound = len;
2049 if(t->bound < 0) 2055 if(t->bound < 0)
2050 n->right = nodintconst(len); 2056 n->right = nodintconst(len);
2051 n->op = OARRAYLIT; 2057 n->op = OARRAYLIT;
2052 break; 2058 break;
2053 2059
2054 case TMAP: 2060 case TMAP:
2055 nhash = inithash(n, &hash, autohash, nelem(autohash)); 2061 nhash = inithash(n, &hash, autohash, nelem(autohash));
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
2377 } 2383 }
2378 2384
2379 /* 2385 /*
2380 * type check function definition 2386 * type check function definition
2381 */ 2387 */
2382 static void 2388 static void
2383 typecheckfunc(Node *n) 2389 typecheckfunc(Node *n)
2384 { 2390 {
2385 Type *t, *rcvr; 2391 Type *t, *rcvr;
2386 2392
2387 //dump("nname", n->nname);
2388 typecheck(&n->nname, Erv | Easgn); 2393 typecheck(&n->nname, Erv | Easgn);
2389 if((t = n->nname->type) == T) 2394 if((t = n->nname->type) == T)
2390 return; 2395 return;
2391 n->type = t; 2396 n->type = t;
2392 2397
2393 rcvr = getthisx(t)->type; 2398 rcvr = getthisx(t)->type;
2394 if(rcvr != nil && n->shortname != N && !isblank(n->shortname)) 2399 if(rcvr != nil && n->shortname != N && !isblank(n->shortname))
2395 addmethod(n->shortname->sym, t, 1); 2400 addmethod(n->shortname->sym, t, 1);
2396 } 2401 }
2397 2402
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
2687 convlit(&e, t); 2692 convlit(&e, t);
2688 } 2693 }
2689 n->val = e->val; 2694 n->val = e->val;
2690 n->type = e->type; 2695 n->type = e->type;
2691 break; 2696 break;
2692 2697
2693 case ONAME: 2698 case ONAME:
2694 if(n->ntype != N) { 2699 if(n->ntype != N) {
2695 typecheck(&n->ntype, Etype); 2700 typecheck(&n->ntype, Etype);
2696 n->type = n->ntype->type; 2701 n->type = n->ntype->type;
2702
2697 if(n->type == T) { 2703 if(n->type == T) {
2698 n->diag = 1; 2704 n->diag = 1;
2699 goto ret; 2705 goto ret;
2700 } 2706 }
2701 } 2707 }
2702 if(n->type != T) 2708 if(n->type != T)
2703 break; 2709 break;
2704 if(n->defn == N) { 2710 if(n->defn == N) {
2705 if(n->etype != 0) // like OPRINTN 2711 if(n->etype != 0) // like OPRINTN
2706 break; 2712 break;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2740 ret: 2746 ret:
2741 if(typecheckdefstack->n != n) 2747 if(typecheckdefstack->n != n)
2742 fatal("typecheckdefstack mismatch"); 2748 fatal("typecheckdefstack mismatch");
2743 l = typecheckdefstack; 2749 l = typecheckdefstack;
2744 typecheckdefstack = l->next; 2750 typecheckdefstack = l->next;
2745 2751
2746 lineno = lno; 2752 lineno = lno;
2747 n->walkdef = 1; 2753 n->walkdef = 1;
2748 return n; 2754 return n;
2749 } 2755 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b