blob: 635d2c4170a3f966a9d5af4893ba8ccc5fda0466 [file] [log] [blame]
Russ Coxff3a73b2009-07-30 16:53:08 -07001// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
Russ Cox9dc22b62009-08-03 11:58:52 -07005/*
6 * type check the whole tree of an expression.
7 * calculates expression types.
8 * evaluates compile time constants.
9 * marks variables that escape the local frame.
10 * rewrites n->op to be more specific in some cases.
Russ Cox9dc22b62009-08-03 11:58:52 -070011 */
12
Russ Cox61f84a22011-08-25 16:25:10 -040013#include <u.h>
14#include <libc.h>
Russ Coxff3a73b2009-07-30 16:53:08 -070015#include "go.h"
16
17static void implicitstar(Node**);
Russ Coxa212d172010-06-20 11:45:53 -070018static int onearg(Node*, char*, ...);
Ken Thompson426099f2010-03-05 20:16:04 -080019static int twoarg(Node*);
Russ Cox5d754bf2009-12-15 16:22:04 -080020static int lookdot(Node*, Type*, int);
Russ Cox00ffd592010-09-28 13:43:50 -040021static int looktypedot(Node*, Type*, int);
Russ Cox50387922011-01-30 16:07:57 -050022static void typecheckaste(int, Node*, int, Type*, NodeList*, char*);
Russ Cox7ae1fe42012-02-10 22:46:56 -050023static Type* lookdot1(Node*, Sym *s, Type *t, Type *f, int);
Russ Cox9dc22b62009-08-03 11:58:52 -070024static int nokeys(NodeList*);
25static void typecheckcomplit(Node**);
Russ Coxd8c19c82009-08-04 10:26:29 -070026static void typecheckas2(Node*);
Russ Cox54b40372009-08-05 00:42:44 -070027static void typecheckas(Node*);
Russ Coxb6487162009-08-07 12:50:26 -070028static void typecheckfunc(Node*);
Russ Cox9dc22b62009-08-03 11:58:52 -070029static void checklvalue(Node*, char*);
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +030030static void checkassignlist(Node*, NodeList*);
Luuk van Dijk2c4edb02011-06-01 17:02:43 +020031static void stringtoarraylit(Node**);
32static Node* resolve(Node*);
Russ Cox79a16a32013-02-01 21:02:15 -050033static void checkdefergo(Node*);
Russ Coxf02067a2013-02-03 14:28:44 -050034static int checkmake(Type*, char*, Node*);
Russ Cox870f4e12014-09-25 13:24:43 -040035static int checksliceindex(Node*, Node*, Type*);
Russ Coxb4e92ce2013-07-01 20:32:36 -040036static int checksliceconst(Node*, Node*);
Russ Coxff3a73b2009-07-30 16:53:08 -070037
Luuk van Dijkab8ed7f2011-06-03 17:44:02 +020038static NodeList* typecheckdefstack;
39
Russ Cox76da2782010-06-12 11:17:24 -070040/*
41 * resolve ONONAME to definition, if any.
42 */
Lucio De Reb3cc4892011-08-29 09:35:04 -040043static Node*
Russ Cox76da2782010-06-12 11:17:24 -070044resolve(Node *n)
45{
46 Node *r;
47
Luuk van Dijk40b2fe02011-12-05 14:40:19 -050048 if(n != N && n->op == ONONAME && n->sym != S && (r = n->sym->def) != N) {
Russ Cox76da2782010-06-12 11:17:24 -070049 if(r->op != OIOTA)
50 n = r;
51 else if(n->iota >= 0)
52 n = nodintconst(n->iota);
53 }
54 return n;
55}
56
Russ Coxff3a73b2009-07-30 16:53:08 -070057void
58typechecklist(NodeList *l, int top)
59{
60 for(; l; l=l->next)
61 typecheck(&l->n, top);
62}
63
Russ Coxbd77eed2011-04-14 09:33:53 -040064static char* _typekind[] = {
Russ Cox7e846662011-01-21 18:15:59 -050065 [TINT] = "int",
66 [TUINT] = "uint",
67 [TINT8] = "int8",
68 [TUINT8] = "uint8",
69 [TINT16] = "int16",
70 [TUINT16] = "uint16",
71 [TINT32] = "int32",
72 [TUINT32] = "uint32",
73 [TINT64] = "int64",
74 [TUINT64] = "uint64",
75 [TUINTPTR] = "uintptr",
76 [TCOMPLEX64] = "complex64",
77 [TCOMPLEX128] = "complex128",
78 [TFLOAT32] = "float32",
79 [TFLOAT64] = "float64",
80 [TBOOL] = "bool",
81 [TSTRING] = "string",
82 [TPTR32] = "pointer",
83 [TPTR64] = "pointer",
Ryan Hitchmana15448d2012-01-06 14:34:16 -080084 [TUNSAFEPTR] = "unsafe.Pointer",
Russ Cox7e846662011-01-21 18:15:59 -050085 [TSTRUCT] = "struct",
86 [TINTER] = "interface",
87 [TCHAN] = "chan",
88 [TMAP] = "map",
89 [TARRAY] = "array",
90 [TFUNC] = "func",
Russ Coxbd77eed2011-04-14 09:33:53 -040091 [TNIL] = "nil",
Rob Pike703b8972013-08-16 12:40:02 +100092 [TIDEAL] = "untyped number",
Russ Cox7e846662011-01-21 18:15:59 -050093};
94
Russ Coxbd77eed2011-04-14 09:33:53 -040095static char*
Russ Cox196b6632011-12-12 22:22:09 -050096typekind(Type *t)
Russ Coxbd77eed2011-04-14 09:33:53 -040097{
Russ Cox196b6632011-12-12 22:22:09 -050098 int et;
Russ Coxbd77eed2011-04-14 09:33:53 -040099 static char buf[50];
100 char *s;
101
Russ Cox196b6632011-12-12 22:22:09 -0500102 if(isslice(t))
103 return "slice";
104 et = t->etype;
Russ Coxbd77eed2011-04-14 09:33:53 -0400105 if(0 <= et && et < nelem(_typekind) && (s=_typekind[et]) != nil)
106 return s;
107 snprint(buf, sizeof buf, "etype=%d", et);
108 return buf;
109}
110
Russ Coxff3a73b2009-07-30 16:53:08 -0700111/*
Rémy Oudompheng892fa3a2012-10-07 17:35:21 +0200112 * sprint_depchain prints a dependency chain
113 * of nodes into fmt.
114 * It is used by typecheck in the case of OLITERAL nodes
115 * to print constant definition loops.
116 */
117static void
118sprint_depchain(Fmt *fmt, NodeList *stack, Node *cur, Node *first)
119{
120 NodeList *l;
121
122 for(l = stack; l; l=l->next) {
123 if(l->n->op == cur->op) {
124 if(l->n != first)
125 sprint_depchain(fmt, l->next, l->n, first);
126 fmtprint(fmt, "\n\t%L: %N uses %N", l->n->lineno, l->n, cur);
127 return;
128 }
129 }
130}
131
132/*
Russ Cox9dc22b62009-08-03 11:58:52 -0700133 * type check node *np.
Russ Coxff3a73b2009-07-30 16:53:08 -0700134 * replaces *np with a new pointer in some cases.
135 * returns the final value of *np as a convenience.
136 */
Russ Cox2aafad22012-02-11 01:04:33 -0500137static void typecheck1(Node **, int);
Russ Coxff3a73b2009-07-30 16:53:08 -0700138Node*
139typecheck(Node **np, int top)
140{
Russ Cox2aafad22012-02-11 01:04:33 -0500141 Node *n;
142 int lno;
143 Fmt fmt;
144 NodeList *l;
145 static NodeList *tcstack, *tcfree;
Russ Coxff3a73b2009-07-30 16:53:08 -0700146
Russ Coxb6487162009-08-07 12:50:26 -0700147 // cannot type check until all the source has been parsed
148 if(!typecheckok)
149 fatal("early typecheck");
150
Russ Coxff3a73b2009-07-30 16:53:08 -0700151 n = *np;
Russ Cox9dc22b62009-08-03 11:58:52 -0700152 if(n == N)
153 return N;
Russ Cox112267d2011-07-27 17:39:30 -0400154
155 lno = setlineno(n);
156
157 // Skip over parens.
158 while(n->op == OPAREN)
159 n = n->left;
Luuk van Dijk49a835f2010-10-15 21:25:34 +0200160
Russ Cox76da2782010-06-12 11:17:24 -0700161 // Resolve definition of name and value of iota lazily.
162 n = resolve(n);
Russ Cox112267d2011-07-27 17:39:30 -0400163
Russ Cox76da2782010-06-12 11:17:24 -0700164 *np = n;
Russ Coxaa6e81dd2009-09-09 16:59:41 -0700165
Russ Cox5438be42009-09-08 23:16:19 -0700166 // Skip typecheck if already done.
Russ Coxe780fa82009-09-09 01:01:39 -0700167 // But re-typecheck ONAME/OTYPE/OLITERAL/OPACK node in case context has changed.
168 if(n->typecheck == 1) {
169 switch(n->op) {
170 case ONAME:
171 case OTYPE:
172 case OLITERAL:
173 case OPACK:
174 break;
175 default:
Russ Cox2f8190a2011-07-28 12:31:16 -0400176 lineno = lno;
Russ Coxe780fa82009-09-09 01:01:39 -0700177 return n;
178 }
179 }
180
Russ Cox44086592010-03-22 18:51:14 -0700181 if(n->typecheck == 2) {
Rémy Oudompheng892fa3a2012-10-07 17:35:21 +0200182 // Typechecking loop. Trying printing a meaningful message,
183 // otherwise a stack trace of typechecking.
184 switch(n->op) {
185 case ONAME:
186 // We can already diagnose variables used as types.
187 if((top & (Erv|Etype)) == Etype)
188 yyerror("%N is not a type", n);
189 break;
190 case OLITERAL:
191 if((top & (Erv|Etype)) == Etype) {
192 yyerror("%N is not a type", n);
193 break;
194 }
195 fmtstrinit(&fmt);
196 sprint_depchain(&fmt, tcstack, n, n);
197 yyerrorl(n->lineno, "constant definition loop%s", fmtstrflush(&fmt));
198 break;
199 }
Russ Cox2aafad22012-02-11 01:04:33 -0500200 if(nsavederrors+nerrors == 0) {
201 fmtstrinit(&fmt);
202 for(l=tcstack; l; l=l->next)
203 fmtprint(&fmt, "\n\t%L %N", l->n->lineno, l->n);
204 yyerror("typechecking loop involving %N%s", n, fmtstrflush(&fmt));
205 }
Russ Cox2f8190a2011-07-28 12:31:16 -0400206 lineno = lno;
Russ Cox44086592010-03-22 18:51:14 -0700207 return n;
208 }
Russ Coxff3a73b2009-07-30 16:53:08 -0700209 n->typecheck = 2;
Rémy Oudompheng892fa3a2012-10-07 17:35:21 +0200210
Russ Cox2aafad22012-02-11 01:04:33 -0500211 if(tcfree != nil) {
212 l = tcfree;
213 tcfree = l->next;
214 } else
215 l = mal(sizeof *l);
216 l->next = tcstack;
217 l->n = n;
218 tcstack = l;
219
220 typecheck1(&n, top);
221 *np = n;
222 n->typecheck = 1;
223
224 if(tcstack != l)
225 fatal("typecheck stack out of sync");
226 tcstack = l->next;
227 l->next = tcfree;
228 tcfree = l;
229
230 lineno = lno;
231 return n;
232}
233
Russ Coxd4fb5682012-03-07 22:43:28 -0500234/*
235 * does n contain a call or receive operation?
236 */
237static int callrecvlist(NodeList*);
238
239static int
240callrecv(Node *n)
241{
242 if(n == nil)
243 return 0;
244
245 switch(n->op) {
246 case OCALL:
247 case OCALLMETH:
248 case OCALLINTER:
249 case OCALLFUNC:
250 case ORECV:
Daniel Morsing48af64b2012-10-22 19:14:30 +0200251 case OCAP:
252 case OLEN:
253 case OCOPY:
254 case ONEW:
255 case OAPPEND:
256 case ODELETE:
Russ Coxd4fb5682012-03-07 22:43:28 -0500257 return 1;
258 }
259
260 return callrecv(n->left) ||
261 callrecv(n->right) ||
262 callrecv(n->ntest) ||
263 callrecv(n->nincr) ||
264 callrecvlist(n->ninit) ||
265 callrecvlist(n->nbody) ||
266 callrecvlist(n->nelse) ||
267 callrecvlist(n->list) ||
268 callrecvlist(n->rlist);
269}
270
271static int
272callrecvlist(NodeList *l)
273{
274 for(; l; l=l->next)
275 if(callrecv(l->n))
276 return 1;
277 return 0;
278}
279
Rémy Oudompheng88b98ff2013-03-22 00:38:23 +0100280// indexlit implements typechecking of untyped values as
281// array/slice indexes. It is equivalent to defaultlit
282// except for constants of numerical kind, which are acceptable
283// whenever they can be represented by a value of type int.
284static void
285indexlit(Node **np)
286{
287 Node *n;
288
289 n = *np;
290 if(n == N || !isideal(n->type))
291 return;
292 switch(consttype(n)) {
293 case CTINT:
294 case CTRUNE:
295 case CTFLT:
296 case CTCPLX:
297 defaultlit(np, types[TINT]);
298 break;
299 }
300 defaultlit(np, T);
301}
302
Russ Cox2aafad22012-02-11 01:04:33 -0500303static void
304typecheck1(Node **np, int top)
305{
306 int et, aop, op, ptr;
Russ Coxb4e92ce2013-07-01 20:32:36 -0400307 Node *n, *l, *r, *lo, *mid, *hi;
Russ Cox2aafad22012-02-11 01:04:33 -0500308 NodeList *args;
309 int ok, ntop;
Russ Cox6363fc52012-06-07 03:06:40 -0400310 Type *t, *tp, *missing, *have, *badtype;
Russ Cox2aafad22012-02-11 01:04:33 -0500311 Val v;
Jan Ziaka599b482014-04-11 15:57:30 +0200312 char *why, *desc, descbuf[64];
Russ Cox870f4e12014-09-25 13:24:43 -0400313 vlong x;
Russ Cox2aafad22012-02-11 01:04:33 -0500314
315 n = *np;
Russ Coxff3a73b2009-07-30 16:53:08 -0700316
Russ Cox680ee6a2009-10-08 23:03:34 -0700317 if(n->sym) {
Russ Cox76da2782010-06-12 11:17:24 -0700318 if(n->op == ONAME && n->etype != 0 && !(top & Ecall)) {
Russ Cox709c5b22010-05-20 22:57:08 -0700319 yyerror("use of builtin %S not in function call", n->sym);
320 goto error;
321 }
Lorenzo Stoakesb6f06322011-04-28 00:13:49 -0400322
Luuk van Dijkab8ed7f2011-06-03 17:44:02 +0200323 typecheckdef(n);
Russ Cox680ee6a2009-10-08 23:03:34 -0700324 if(n->op == ONONAME)
325 goto error;
326 }
Russ Cox76da2782010-06-12 11:17:24 -0700327 *np = n;
Russ Coxff3a73b2009-07-30 16:53:08 -0700328
329reswitch:
330 ok = 0;
331 switch(n->op) {
332 default:
333 // until typecheck is complete, do nothing.
334 dump("typecheck", n);
335 fatal("typecheck %O", n->op);
336
337 /*
338 * names
339 */
340 case OLITERAL:
341 ok |= Erv;
Russ Cox5d754bf2009-12-15 16:22:04 -0800342 if(n->type == T && n->val.ctype == CTSTR)
Russ Cox14be7332009-08-24 13:41:47 -0700343 n->type = idealstring;
Russ Coxff3a73b2009-07-30 16:53:08 -0700344 goto ret;
345
346 case ONONAME:
Russ Cox9dc22b62009-08-03 11:58:52 -0700347 ok |= Erv;
Russ Coxff3a73b2009-07-30 16:53:08 -0700348 goto ret;
349
350 case ONAME:
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +0300351 if(n->decldepth == 0)
352 n->decldepth = decldepth;
Russ Coxff3a73b2009-07-30 16:53:08 -0700353 if(n->etype != 0) {
Russ Cox54b40372009-08-05 00:42:44 -0700354 ok |= Ecall;
355 goto ret;
Russ Coxff3a73b2009-07-30 16:53:08 -0700356 }
Russ Cox59914722009-09-14 18:38:30 -0700357 if(!(top & Easgn)) {
358 // not a write to the variable
359 if(isblank(n)) {
360 yyerror("cannot use _ as value");
361 goto error;
362 }
363 n->used = 1;
Russ Cox5438be42009-09-08 23:16:19 -0700364 }
Luuk van Dijk924ea512011-11-09 18:30:54 +0100365 if(!(top &Ecall) && isunsafebuiltin(n)) {
366 yyerror("%N is not an expression, must be called", n);
367 goto error;
368 }
Russ Coxff3a73b2009-07-30 16:53:08 -0700369 ok |= Erv;
Russ Coxff3a73b2009-07-30 16:53:08 -0700370 goto ret;
371
Russ Cox3e98a402009-08-12 15:58:31 -0700372 case OPACK:
Brendan Daniel Traceyd3094962014-02-10 20:27:31 -0500373 yyerror("use of package %S without selector", n->sym);
Russ Cox3e98a402009-08-12 15:58:31 -0700374 goto error;
375
Russ Cox68796b02010-02-01 00:25:59 -0800376 case ODDD:
377 break;
378
Russ Coxff3a73b2009-07-30 16:53:08 -0700379 /*
380 * types (OIND is with exprs)
381 */
382 case OTYPE:
383 ok |= Etype;
384 if(n->type == T)
385 goto error;
386 break;
Russ Coxb1311cb2010-08-23 23:10:25 -0400387
Russ Coxff3a73b2009-07-30 16:53:08 -0700388 case OTARRAY:
389 ok |= Etype;
390 t = typ(TARRAY);
391 l = n->left;
392 r = n->right;
393 if(l == nil) {
Russ Cox5ab8f002010-02-12 13:59:02 -0800394 t->bound = -1; // slice
395 } else if(l->op == ODDD) {
396 t->bound = -100; // to be filled in
Russ Coxf607c472013-02-01 21:21:27 -0500397 if(!(top&Ecomplit) && !n->diag) {
398 t->broke = 1;
399 n->diag = 1;
Russ Coxbf899be2011-07-26 00:52:02 -0400400 yyerror("use of [...] array outside of array literal");
Russ Coxf607c472013-02-01 21:21:27 -0500401 }
Russ Coxff3a73b2009-07-30 16:53:08 -0700402 } else {
Russ Cox5ab8f002010-02-12 13:59:02 -0800403 l = typecheck(&n->left, Erv);
404 switch(consttype(l)) {
405 case CTINT:
Russ Coxbe0ffbf2011-12-08 22:07:43 -0500406 case CTRUNE:
Russ Cox5ab8f002010-02-12 13:59:02 -0800407 v = l->val;
408 break;
409 case CTFLT:
410 v = toint(l->val);
411 break;
Russ Coxff3a73b2009-07-30 16:53:08 -0700412 default:
Russ Cox8d613342014-09-16 10:21:54 -0400413 if(l->type != T && isint[l->type->etype] && l->op != OLITERAL)
414 yyerror("non-constant array bound %N", l);
415 else
416 yyerror("invalid array bound %N", l);
Russ Coxff3a73b2009-07-30 16:53:08 -0700417 goto error;
Russ Coxff3a73b2009-07-30 16:53:08 -0700418 }
Russ Cox5ab8f002010-02-12 13:59:02 -0800419 t->bound = mpgetfix(v.u.xval);
Daniel Morsingbf9a00b2013-06-01 16:33:54 +0200420 if(doesoverflow(v, types[TINT])) {
Daniel Morsinga7a3fe72012-10-21 19:22:51 +0200421 yyerror("array bound is too large");
422 goto error;
Daniel Morsingbf9a00b2013-06-01 16:33:54 +0200423 } else if(t->bound < 0) {
424 yyerror("array bound must be non-negative");
425 goto error;
Daniel Morsinga7a3fe72012-10-21 19:22:51 +0200426 }
Russ Coxff3a73b2009-07-30 16:53:08 -0700427 }
428 typecheck(&r, Etype);
429 if(r->type == T)
430 goto error;
431 t->type = r->type;
432 n->op = OTYPE;
433 n->type = t;
434 n->left = N;
435 n->right = N;
Russ Coxa1391c22009-09-02 23:26:13 -0700436 if(t->bound != -100)
437 checkwidth(t);
Russ Coxff3a73b2009-07-30 16:53:08 -0700438 break;
439
440 case OTMAP:
441 ok |= Etype;
442 l = typecheck(&n->left, Etype);
443 r = typecheck(&n->right, Etype);
444 if(l->type == T || r->type == T)
445 goto error;
446 n->op = OTYPE;
447 n->type = maptype(l->type, r->type);
448 n->left = N;
449 n->right = N;
450 break;
451
452 case OTCHAN:
453 ok |= Etype;
454 l = typecheck(&n->left, Etype);
455 if(l->type == T)
456 goto error;
457 t = typ(TCHAN);
458 t->type = l->type;
459 t->chan = n->etype;
460 n->op = OTYPE;
461 n->type = t;
462 n->left = N;
463 n->etype = 0;
464 break;
465
466 case OTSTRUCT:
467 ok |= Etype;
468 n->op = OTYPE;
Luuk van Dijk087bec32011-11-07 21:35:13 +0100469 n->type = tostruct(n->list);
Rémy Oudomphengc208a3a2012-11-07 23:09:01 +0100470 if(n->type == T || n->type->broke)
Russ Coxff3a73b2009-07-30 16:53:08 -0700471 goto error;
472 n->list = nil;
473 break;
474
475 case OTINTER:
476 ok |= Etype;
477 n->op = OTYPE;
Luuk van Dijk087bec32011-11-07 21:35:13 +0100478 n->type = tointerface(n->list);
Russ Coxff3a73b2009-07-30 16:53:08 -0700479 if(n->type == T)
480 goto error;
Russ Coxff3a73b2009-07-30 16:53:08 -0700481 break;
482
483 case OTFUNC:
484 ok |= Etype;
485 n->op = OTYPE;
486 n->type = functype(n->left, n->list, n->rlist);
487 if(n->type == T)
488 goto error;
489 break;
490
491 /*
492 * type or expr
493 */
494 case OIND:
Russ Coxa75e3472009-10-15 16:03:01 -0700495 ntop = Erv | Etype;
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200496 if(!(top & Eaddr)) // The *x in &*x is not an indirect.
Russ Coxa75e3472009-10-15 16:03:01 -0700497 ntop |= Eindir;
Russ Cox7dc9d8c2011-12-02 14:13:12 -0500498 ntop |= top & Ecomplit;
Russ Coxa75e3472009-10-15 16:03:01 -0700499 l = typecheck(&n->left, ntop);
Russ Coxff3a73b2009-07-30 16:53:08 -0700500 if((t = l->type) == T)
501 goto error;
502 if(l->op == OTYPE) {
503 ok |= Etype;
504 n->op = OTYPE;
505 n->type = ptrto(l->type);
506 n->left = N;
507 goto ret;
508 }
Daniel Morsingc0d9bf52013-01-18 22:46:10 +0100509 if(!isptr[t->etype]) {
510 if(top & (Erv | Etop)) {
511 yyerror("invalid indirect of %lN", n->left);
512 goto error;
513 }
514 goto ret;
Russ Coxff3a73b2009-07-30 16:53:08 -0700515 }
Russ Cox9dc22b62009-08-03 11:58:52 -0700516 ok |= Erv;
Russ Coxff3a73b2009-07-30 16:53:08 -0700517 n->type = t->type;
518 goto ret;
519
520 /*
521 * arithmetic exprs
522 */
523 case OASOP:
524 ok |= Etop;
Russ Cox9dc22b62009-08-03 11:58:52 -0700525 l = typecheck(&n->left, Erv);
Russ Coxff3a73b2009-07-30 16:53:08 -0700526 r = typecheck(&n->right, Erv);
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +0300527 checkassign(n, n->left);
Russ Coxff3a73b2009-07-30 16:53:08 -0700528 if(l->type == T || r->type == T)
529 goto error;
530 op = n->etype;
531 goto arith;
532
533 case OADD:
534 case OAND:
535 case OANDAND:
536 case OANDNOT:
537 case ODIV:
538 case OEQ:
539 case OGE:
540 case OGT:
541 case OLE:
542 case OLT:
543 case OLSH:
544 case ORSH:
545 case OMOD:
546 case OMUL:
547 case ONE:
548 case OOR:
549 case OOROR:
550 case OSUB:
551 case OXOR:
552 ok |= Erv;
Russ Cox866b2722009-08-11 17:05:22 -0700553 l = typecheck(&n->left, Erv | (top & Eiota));
554 r = typecheck(&n->right, Erv | (top & Eiota));
Russ Coxff3a73b2009-07-30 16:53:08 -0700555 if(l->type == T || r->type == T)
556 goto error;
557 op = n->op;
558 arith:
559 if(op == OLSH || op == ORSH)
560 goto shift;
561 // ideal mixed with non-ideal
562 defaultlit2(&l, &r, 0);
563 n->left = l;
564 n->right = r;
Russ Cox83bdb802009-09-09 01:21:20 -0700565 if(l->type == T || r->type == T)
566 goto error;
Russ Coxff3a73b2009-07-30 16:53:08 -0700567 t = l->type;
568 if(t->etype == TIDEAL)
569 t = r->type;
570 et = t->etype;
571 if(et == TIDEAL)
572 et = TINT;
Russ Cox23bd2142010-09-13 15:42:47 -0400573 if(iscmp[n->op] && t->etype != TIDEAL && !eqtype(l->type, r->type)) {
574 // comparison is okay as long as one side is
575 // assignable to the other. convert so they have
Russ Cox196b6632011-12-12 22:22:09 -0500576 // the same type.
577 //
578 // the only conversion that isn't a no-op is concrete == interface.
579 // in that case, check comparability of the concrete type.
Russ Cox23bd2142010-09-13 15:42:47 -0400580 if(r->type->etype != TBLANK && (aop = assignop(l->type, r->type, nil)) != 0) {
Russ Cox196b6632011-12-12 22:22:09 -0500581 if(isinter(r->type) && !isinter(l->type) && algtype1(l->type, nil) == ANOEQ) {
582 yyerror("invalid operation: %N (operator %O not defined on %s)", n, op, typekind(l->type));
583 goto error;
584 }
Russ Cox23bd2142010-09-13 15:42:47 -0400585 l = nod(aop, l, N);
586 l->type = r->type;
587 l->typecheck = 1;
588 n->left = l;
589 t = l->type;
Russ Coxe82003e2015-01-21 22:19:15 -0500590 goto converted;
591 }
592 if(l->type->etype != TBLANK && (aop = assignop(r->type, l->type, nil)) != 0) {
Russ Cox196b6632011-12-12 22:22:09 -0500593 if(isinter(l->type) && !isinter(r->type) && algtype1(r->type, nil) == ANOEQ) {
594 yyerror("invalid operation: %N (operator %O not defined on %s)", n, op, typekind(r->type));
595 goto error;
596 }
Russ Cox23bd2142010-09-13 15:42:47 -0400597 r = nod(aop, r, N);
598 r->type = l->type;
599 r->typecheck = 1;
600 n->right = r;
601 t = r->type;
602 }
Russ Coxe82003e2015-01-21 22:19:15 -0500603 converted:
Russ Cox23bd2142010-09-13 15:42:47 -0400604 et = t->etype;
605 }
Russ Coxff3a73b2009-07-30 16:53:08 -0700606 if(t->etype != TIDEAL && !eqtype(l->type, r->type)) {
Russ Coxb754b432009-07-30 18:56:44 -0700607 defaultlit2(&l, &r, 1);
Russ Cox52e9bca2014-09-25 13:13:02 -0400608 if(n->op == OASOP && n->implicit) {
609 yyerror("invalid operation: %N (non-numeric type %T)", n, l->type);
610 goto error;
611 }
Luuk van Dijk50110c92011-10-31 18:09:40 +0100612 yyerror("invalid operation: %N (mismatched types %T and %T)", n, l->type, r->type);
Russ Coxff3a73b2009-07-30 16:53:08 -0700613 goto error;
614 }
Russ Cox7e846662011-01-21 18:15:59 -0500615 if(!okfor[op][et]) {
Russ Cox196b6632011-12-12 22:22:09 -0500616 yyerror("invalid operation: %N (operator %O not defined on %s)", n, op, typekind(t));
Russ Cox7e846662011-01-21 18:15:59 -0500617 goto error;
618 }
Russ Cox5bb54b82011-11-13 22:58:08 -0500619 // okfor allows any array == array, map == map, func == func.
620 // restrict to slice/map/func == nil and nil == slice/map/func.
Russ Cox196b6632011-12-12 22:22:09 -0500621 if(isfixedarray(l->type) && algtype1(l->type, nil) == ANOEQ) {
622 yyerror("invalid operation: %N (%T cannot be compared)", n, l->type);
623 goto error;
624 }
Russ Cox7e846662011-01-21 18:15:59 -0500625 if(isslice(l->type) && !isnil(l) && !isnil(r)) {
Luuk van Dijk50110c92011-10-31 18:09:40 +0100626 yyerror("invalid operation: %N (slice can only be compared to nil)", n);
Russ Cox7e846662011-01-21 18:15:59 -0500627 goto error;
628 }
Russ Cox5bb54b82011-11-13 22:58:08 -0500629 if(l->type->etype == TMAP && !isnil(l) && !isnil(r)) {
630 yyerror("invalid operation: %N (map can only be compared to nil)", n);
631 goto error;
632 }
633 if(l->type->etype == TFUNC && !isnil(l) && !isnil(r)) {
634 yyerror("invalid operation: %N (func can only be compared to nil)", n);
635 goto error;
636 }
Russ Cox196b6632011-12-12 22:22:09 -0500637 if(l->type->etype == TSTRUCT && algtype1(l->type, &badtype) == ANOEQ) {
638 yyerror("invalid operation: %N (struct containing %T cannot be compared)", n, badtype);
639 goto error;
640 }
Russ Cox5bb54b82011-11-13 22:58:08 -0500641
Russ Coxff3a73b2009-07-30 16:53:08 -0700642 t = l->type;
Russ Coxb754b432009-07-30 18:56:44 -0700643 if(iscmp[n->op]) {
Russ Coxb754b432009-07-30 18:56:44 -0700644 evconst(n);
Russ Coxe29d3df2012-02-22 00:29:37 -0500645 t = idealbool;
Russ Coxb754b432009-07-30 18:56:44 -0700646 if(n->op != OLITERAL) {
647 defaultlit2(&l, &r, 1);
648 n->left = l;
649 n->right = r;
650 }
Chris Manghane5cc29ab2014-12-09 07:16:38 -0800651 } else if(n->op == OANDAND || n->op == OOROR) {
652 if(l->type == r->type)
653 t = l->type;
654 else if(l->type == idealbool)
655 t = r->type;
656 else if(r->type == idealbool)
657 t = l->type;
Daniel Morsing5188c0b2012-11-26 22:23:13 +0100658 // non-comparison operators on ideal bools should make them lose their ideal-ness
659 } else if(t == idealbool)
660 t = types[TBOOL];
661
Russ Cox9dc22b62009-08-03 11:58:52 -0700662 if(et == TSTRING) {
663 if(iscmp[n->op]) {
664 n->etype = n->op;
665 n->op = OCMPSTR;
Russ Coxdaca06f2014-04-01 20:02:54 -0400666 } else if(n->op == OADD) {
667 // create OADDSTR node with list of strings in x + y + z + (w + v) + ...
Russ Cox9dc22b62009-08-03 11:58:52 -0700668 n->op = OADDSTR;
Russ Coxdaca06f2014-04-01 20:02:54 -0400669 if(l->op == OADDSTR)
670 n->list = l->list;
671 else
672 n->list = list1(l);
673 if(r->op == OADDSTR)
674 n->list = concat(n->list, r->list);
675 else
676 n->list = list(n->list, r);
677 n->left = N;
678 n->right = N;
679 }
Russ Cox9dc22b62009-08-03 11:58:52 -0700680 }
681 if(et == TINTER) {
Russ Cox89f69bb2009-08-24 15:20:37 -0700682 if(l->op == OLITERAL && l->val.ctype == CTNIL) {
683 // swap for back end
684 n->left = r;
685 n->right = l;
686 } else if(r->op == OLITERAL && r->val.ctype == CTNIL) {
687 // leave alone for back end
688 } else {
689 n->etype = n->op;
690 n->op = OCMPIFACE;
691 }
Russ Cox9dc22b62009-08-03 11:58:52 -0700692 }
Daniel Morsingba05a432013-01-30 20:21:08 +0100693
694 if((op == ODIV || op == OMOD) && isconst(r, CTINT))
695 if(mpcmpfixc(r->val.u.xval, 0) == 0) {
696 yyerror("division by zero");
697 goto error;
698 }
699
Russ Coxff3a73b2009-07-30 16:53:08 -0700700 n->type = t;
701 goto ret;
702
703 shift:
704 defaultlit(&r, types[TUINT]);
705 n->right = r;
706 t = r->type;
707 if(!isint[t->etype] || issigned[t->etype]) {
Luuk van Dijk50110c92011-10-31 18:09:40 +0100708 yyerror("invalid operation: %N (shift count type %T, must be unsigned integer)", n, r->type);
Russ Coxff3a73b2009-07-30 16:53:08 -0700709 goto error;
710 }
Russ Coxac9d8332009-08-23 18:09:44 -0700711 t = l->type;
712 if(t != T && t->etype != TIDEAL && !isint[t->etype]) {
Luuk van Dijk50110c92011-10-31 18:09:40 +0100713 yyerror("invalid operation: %N (shift of type %T)", n, t);
Russ Coxac9d8332009-08-23 18:09:44 -0700714 goto error;
715 }
Russ Coxff3a73b2009-07-30 16:53:08 -0700716 // no defaultlit for left
717 // the outer context gives the type
718 n->type = l->type;
719 goto ret;
720
721 case OCOM:
722 case OMINUS:
723 case ONOT:
724 case OPLUS:
725 ok |= Erv;
Russ Cox866b2722009-08-11 17:05:22 -0700726 l = typecheck(&n->left, Erv | (top & Eiota));
Russ Coxff3a73b2009-07-30 16:53:08 -0700727 if((t = l->type) == T)
728 goto error;
729 if(!okfor[n->op][t->etype]) {
Luuk van Dijk50110c92011-10-31 18:09:40 +0100730 yyerror("invalid operation: %O %T", n->op, t);
Russ Coxff3a73b2009-07-30 16:53:08 -0700731 goto error;
732 }
733 n->type = t;
734 goto ret;
735
736 /*
737 * exprs
738 */
739 case OADDR:
Russ Cox54b40372009-08-05 00:42:44 -0700740 ok |= Erv;
Russ Coxa75e3472009-10-15 16:03:01 -0700741 typecheck(&n->left, Erv | Eaddr);
Russ Cox9dc22b62009-08-03 11:58:52 -0700742 if(n->left->type == T)
743 goto error;
Russ Cox7dc9d8c2011-12-02 14:13:12 -0500744 checklvalue(n->left, "take the address of");
Russ Cox1a3ee672014-02-15 20:01:15 -0500745 r = outervalue(n->left);
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +0300746 for(l = n->left; l != r; l = l->left) {
Russ Coxeb3aba242011-10-13 15:46:39 -0400747 l->addrtaken = 1;
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +0300748 if(l->closure)
749 l->closure->addrtaken = 1;
750 }
Russ Cox334056a2014-01-14 10:43:13 -0500751 if(l->orig != l && l->op == ONAME)
752 fatal("found non-orig name node %N", l);
Russ Coxeb3aba242011-10-13 15:46:39 -0400753 l->addrtaken = 1;
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +0300754 if(l->closure)
755 l->closure->addrtaken = 1;
Russ Coxa2b8e382009-07-31 09:29:28 -0700756 defaultlit(&n->left, T);
757 l = n->left;
Russ Coxff3a73b2009-07-30 16:53:08 -0700758 if((t = l->type) == T)
759 goto error;
760 n->type = ptrto(t);
761 goto ret;
762
Russ Cox9dc22b62009-08-03 11:58:52 -0700763 case OCOMPLIT:
Russ Cox54b40372009-08-05 00:42:44 -0700764 ok |= Erv;
Russ Cox9dc22b62009-08-03 11:58:52 -0700765 typecheckcomplit(&n);
766 if(n->type == T)
Russ Coxff3a73b2009-07-30 16:53:08 -0700767 goto error;
Russ Coxff3a73b2009-07-30 16:53:08 -0700768 goto ret;
769
Russ Cox26097312009-08-05 02:33:30 -0700770 case OXDOT:
771 n = adddot(n);
772 n->op = ODOT;
Russ Cox7ae1fe42012-02-10 22:46:56 -0500773 if(n->left == N)
774 goto error;
Russ Cox26097312009-08-05 02:33:30 -0700775 // fall through
Russ Coxff3a73b2009-07-30 16:53:08 -0700776 case ODOT:
Russ Coxc6f4d682010-01-07 23:20:00 -0800777 typecheck(&n->left, Erv|Etype);
778 defaultlit(&n->left, T);
Luuk van Dijk40b2fe02011-12-05 14:40:19 -0500779 if((t = n->left->type) == T)
Russ Coxff3a73b2009-07-30 16:53:08 -0700780 goto error;
781 if(n->right->op != ONAME) {
782 yyerror("rhs of . must be a name"); // impossible
783 goto error;
784 }
Russ Coxd3c758d2013-03-20 17:11:09 -0400785 r = n->right;
Luuk van Dijk40b2fe02011-12-05 14:40:19 -0500786
787 if(n->left->op == OTYPE) {
Russ Cox00ffd592010-09-28 13:43:50 -0400788 if(!looktypedot(n, t, 0)) {
789 if(looktypedot(n, t, 1))
Luuk van Dijk50110c92011-10-31 18:09:40 +0100790 yyerror("%N undefined (cannot refer to unexported method %S)", n, n->right->sym);
Russ Cox00ffd592010-09-28 13:43:50 -0400791 else
Luuk van Dijk50110c92011-10-31 18:09:40 +0100792 yyerror("%N undefined (type %T has no method %S)", n, t, n->right->sym);
Russ Cox00ffd592010-09-28 13:43:50 -0400793 goto error;
794 }
795 if(n->type->etype != TFUNC || n->type->thistuple != 1) {
Luuk van Dijk40b2fe02011-12-05 14:40:19 -0500796 yyerror("type %T has no method %hS", n->left->type, n->right->sym);
Russ Cox00ffd592010-09-28 13:43:50 -0400797 n->type = T;
798 goto error;
799 }
800 n->op = ONAME;
Luuk van Dijk40b2fe02011-12-05 14:40:19 -0500801 n->sym = n->right->sym;
802 n->type = methodfunc(n->type, n->left->type);
Russ Cox00ffd592010-09-28 13:43:50 -0400803 n->xoffset = 0;
804 n->class = PFUNC;
805 ok = Erv;
806 goto ret;
807 }
Russ Coxbee2d5b2010-09-30 14:59:41 -0400808 if(isptr[t->etype] && t->type->etype != TINTER) {
Russ Coxff3a73b2009-07-30 16:53:08 -0700809 t = t->type;
810 if(t == T)
811 goto error;
812 n->op = ODOTPTR;
Russ Coxb6487162009-08-07 12:50:26 -0700813 checkwidth(t);
Russ Coxff3a73b2009-07-30 16:53:08 -0700814 }
Daniel Morsingb65acae2013-03-04 17:01:42 +0100815 if(isblank(n->right)) {
816 yyerror("cannot refer to blank field or method");
817 goto error;
818 }
Russ Cox5d754bf2009-12-15 16:22:04 -0800819 if(!lookdot(n, t, 0)) {
820 if(lookdot(n, t, 1))
Luuk van Dijk50110c92011-10-31 18:09:40 +0100821 yyerror("%N undefined (cannot refer to unexported field or method %S)", n, n->right->sym);
Russ Cox5d754bf2009-12-15 16:22:04 -0800822 else
Luuk van Dijk40b2fe02011-12-05 14:40:19 -0500823 yyerror("%N undefined (type %T has no field or method %S)", n, n->left->type, n->right->sym);
Russ Coxff3a73b2009-07-30 16:53:08 -0700824 goto error;
825 }
826 switch(n->op) {
827 case ODOTINTER:
828 case ODOTMETH:
Russ Coxd3c758d2013-03-20 17:11:09 -0400829 if(top&Ecall)
830 ok |= Ecall;
831 else {
832 typecheckpartialcall(n, r);
833 ok |= Erv;
834 }
Russ Coxff3a73b2009-07-30 16:53:08 -0700835 break;
836 default:
837 ok |= Erv;
Russ Coxff3a73b2009-07-30 16:53:08 -0700838 break;
839 }
840 goto ret;
841
842 case ODOTTYPE:
Russ Cox54b40372009-08-05 00:42:44 -0700843 ok |= Erv;
Russ Coxff3a73b2009-07-30 16:53:08 -0700844 typecheck(&n->left, Erv);
845 defaultlit(&n->left, T);
846 l = n->left;
847 if((t = l->type) == T)
848 goto error;
849 if(!isinter(t)) {
Luuk van Dijk50110c92011-10-31 18:09:40 +0100850 yyerror("invalid type assertion: %N (non-interface type %T on left)", n, t);
Russ Coxff3a73b2009-07-30 16:53:08 -0700851 goto error;
852 }
853 if(n->right != N) {
854 typecheck(&n->right, Etype);
855 n->type = n->right->type;
856 n->right = N;
857 if(n->type == T)
858 goto error;
859 }
Russ Coxa2a7d472010-06-09 11:00:55 -0700860 if(n->type != T && n->type->etype != TINTER)
Russ Coxa212d172010-06-20 11:45:53 -0700861 if(!implements(n->type, t, &missing, &have, &ptr)) {
Daniel Morsing1c2021c2012-09-01 13:52:55 -0400862 if(have && have->sym == missing->sym)
863 yyerror("impossible type assertion:\n\t%T does not implement %T (wrong type for %S method)\n"
864 "\t\thave %S%hhT\n\t\twant %S%hhT", n->type, t, missing->sym,
865 have->sym, have->type, missing->sym, missing->type);
866 else if(ptr)
Russ Cox22547852013-07-15 20:39:07 -0400867 yyerror("impossible type assertion:\n\t%T does not implement %T (%S method has pointer receiver)",
Daniel Morsing1c2021c2012-09-01 13:52:55 -0400868 n->type, t, missing->sym);
869 else if(have)
870 yyerror("impossible type assertion:\n\t%T does not implement %T (missing %S method)\n"
871 "\t\thave %S%hhT\n\t\twant %S%hhT", n->type, t, missing->sym,
872 have->sym, have->type, missing->sym, missing->type);
Russ Coxa2a7d472010-06-09 11:00:55 -0700873 else
Daniel Morsing1c2021c2012-09-01 13:52:55 -0400874 yyerror("impossible type assertion:\n\t%T does not implement %T (missing %S method)",
875 n->type, t, missing->sym);
Russ Coxa2a7d472010-06-09 11:00:55 -0700876 goto error;
877 }
Russ Coxff3a73b2009-07-30 16:53:08 -0700878 goto ret;
879
880 case OINDEX:
Russ Cox54b40372009-08-05 00:42:44 -0700881 ok |= Erv;
Russ Coxff3a73b2009-07-30 16:53:08 -0700882 typecheck(&n->left, Erv);
883 defaultlit(&n->left, T);
884 implicitstar(&n->left);
885 l = n->left;
886 typecheck(&n->right, Erv);
887 r = n->right;
888 if((t = l->type) == T || r->type == T)
889 goto error;
890 switch(t->etype) {
891 default:
Shenghou Ma656a4022014-02-13 21:01:33 -0500892 yyerror("invalid operation: %N (type %T does not support indexing)", n, t);
Russ Coxff3a73b2009-07-30 16:53:08 -0700893 goto error;
894
Russ Coxd82dcad2013-02-03 02:01:05 -0500895
896 case TSTRING:
Russ Coxff3a73b2009-07-30 16:53:08 -0700897 case TARRAY:
Rémy Oudompheng88b98ff2013-03-22 00:38:23 +0100898 indexlit(&n->right);
Russ Coxd82dcad2013-02-03 02:01:05 -0500899 if(t->etype == TSTRING)
900 n->type = types[TUINT8];
901 else
902 n->type = t->type;
903 why = "string";
904 if(t->etype == TARRAY) {
905 if(isfixedarray(t))
906 why = "array";
907 else
908 why = "slice";
909 }
Daniel Morsing85d60a72012-11-01 18:45:19 +0100910 if(n->right->type != T && !isint[n->right->type->etype]) {
Russ Coxd82dcad2013-02-03 02:01:05 -0500911 yyerror("non-integer %s index %N", why, n->right);
Daniel Morsing85d60a72012-11-01 18:45:19 +0100912 break;
913 }
Rémy Oudompheng88b98ff2013-03-22 00:38:23 +0100914 if(isconst(n->right, CTINT)) {
Russ Cox870f4e12014-09-25 13:24:43 -0400915 x = mpgetfix(n->right->val.u.xval);
916 if(x < 0)
Daniel Morsing85d60a72012-11-01 18:45:19 +0100917 yyerror("invalid %s index %N (index must be non-negative)", why, n->right);
Russ Cox870f4e12014-09-25 13:24:43 -0400918 else if(isfixedarray(t) && t->bound > 0 && x >= t->bound)
Daniel Morsing85d60a72012-11-01 18:45:19 +0100919 yyerror("invalid array index %N (out of bounds for %d-element array)", n->right, t->bound);
Russ Cox870f4e12014-09-25 13:24:43 -0400920 else if(isconst(n->left, CTSTR) && x >= n->left->val.u.sval->len)
Russ Coxd82dcad2013-02-03 02:01:05 -0500921 yyerror("invalid string index %N (out of bounds for %d-byte string)", n->right, n->left->val.u.sval->len);
922 else if(mpcmpfixfix(n->right->val.u.xval, maxintval[TINT]) > 0)
Ian Lance Taylore3977f02012-11-07 17:34:06 -0800923 yyerror("invalid %s index %N (index too large)", why, n->right);
Daniel Morsing85d60a72012-11-01 18:45:19 +0100924 }
Russ Coxff3a73b2009-07-30 16:53:08 -0700925 break;
926
927 case TMAP:
Russ Coxa2b8e382009-07-31 09:29:28 -0700928 n->etype = 0;
Russ Coxff3a73b2009-07-30 16:53:08 -0700929 defaultlit(&n->right, t->down);
Russ Cox565b5dc2010-06-08 18:50:02 -0700930 if(n->right->type != T)
931 n->right = assignconv(n->right, t->down, "map index");
Russ Coxff3a73b2009-07-30 16:53:08 -0700932 n->type = t->type;
Russ Cox9dc22b62009-08-03 11:58:52 -0700933 n->op = OINDEXMAP;
Russ Coxff3a73b2009-07-30 16:53:08 -0700934 break;
Russ Coxff3a73b2009-07-30 16:53:08 -0700935 }
936 goto ret;
937
938 case ORECV:
Russ Cox54b40372009-08-05 00:42:44 -0700939 ok |= Etop | Erv;
Russ Coxff3a73b2009-07-30 16:53:08 -0700940 typecheck(&n->left, Erv);
941 defaultlit(&n->left, T);
942 l = n->left;
943 if((t = l->type) == T)
944 goto error;
945 if(t->etype != TCHAN) {
Luuk van Dijk50110c92011-10-31 18:09:40 +0100946 yyerror("invalid operation: %N (receive from non-chan type %T)", n, t);
Russ Coxff3a73b2009-07-30 16:53:08 -0700947 goto error;
948 }
949 if(!(t->chan & Crecv)) {
Luuk van Dijk50110c92011-10-31 18:09:40 +0100950 yyerror("invalid operation: %N (receive from send-only type %T)", n, t);
Russ Coxff3a73b2009-07-30 16:53:08 -0700951 goto error;
952 }
953 n->type = t->type;
Russ Coxff3a73b2009-07-30 16:53:08 -0700954 goto ret;
955
956 case OSEND:
Russ Coxe1ac1572013-09-06 15:47:52 -0400957 ok |= Etop;
Russ Coxff3a73b2009-07-30 16:53:08 -0700958 l = typecheck(&n->left, Erv);
959 typecheck(&n->right, Erv);
960 defaultlit(&n->left, T);
961 l = n->left;
962 if((t = l->type) == T)
963 goto error;
Russ Cox42c26b72010-10-07 03:33:42 -0400964 if(t->etype != TCHAN) {
Luuk van Dijk50110c92011-10-31 18:09:40 +0100965 yyerror("invalid operation: %N (send to non-chan type %T)", n, t);
Russ Cox42c26b72010-10-07 03:33:42 -0400966 goto error;
967 }
Russ Coxff3a73b2009-07-30 16:53:08 -0700968 if(!(t->chan & Csend)) {
Luuk van Dijk50110c92011-10-31 18:09:40 +0100969 yyerror("invalid operation: %N (send to receive-only type %T)", n, t);
Russ Coxff3a73b2009-07-30 16:53:08 -0700970 goto error;
971 }
972 defaultlit(&n->right, t->type);
973 r = n->right;
Lucio De Reb3cc4892011-08-29 09:35:04 -0400974 if(r->type == T)
Russ Coxff3a73b2009-07-30 16:53:08 -0700975 goto error;
Russ Coxb700cb42014-04-01 13:31:38 -0400976 n->right = assignconv(r, l->type->type, "send");
Russ Coxff3a73b2009-07-30 16:53:08 -0700977 // TODO: more aggressive
Russ Coxa2b8e382009-07-31 09:29:28 -0700978 n->etype = 0;
Russ Coxa95ee612009-09-21 15:45:55 -0700979 n->type = T;
Russ Coxff3a73b2009-07-30 16:53:08 -0700980 goto ret;
981
982 case OSLICE:
983 ok |= Erv;
984 typecheck(&n->left, top);
985 typecheck(&n->right->left, Erv);
986 typecheck(&n->right->right, Erv);
987 defaultlit(&n->left, T);
Rémy Oudompheng88b98ff2013-03-22 00:38:23 +0100988 indexlit(&n->right->left);
989 indexlit(&n->right->right);
Ian Lance Taylor72bf3bc2012-11-06 11:35:58 -0800990 l = n->left;
991 if(isfixedarray(l->type)) {
Russ Cox7d15eda2011-12-02 12:30:56 -0500992 if(!islvalue(n->left)) {
993 yyerror("invalid operation %N (slice of unaddressable value)", n);
994 goto error;
995 }
Russ Cox10eb76b2010-04-29 15:52:27 -0700996 n->left = nod(OADDR, n->left, N);
Luuk van Dijk29a5ae62011-11-02 15:36:33 +0100997 n->left->implicit = 1;
Russ Cox7d15eda2011-12-02 12:30:56 -0500998 typecheck(&n->left, Erv);
Ian Lance Taylor72bf3bc2012-11-06 11:35:58 -0800999 l = n->left;
1000 }
1001 if((t = l->type) == T)
1002 goto error;
1003 tp = nil;
1004 if(istype(t, TSTRING)) {
1005 n->type = t;
1006 n->op = OSLICESTR;
1007 } else if(isptr[t->etype] && isfixedarray(t->type)) {
1008 tp = t->type;
1009 n->type = typ(TARRAY);
1010 n->type->type = tp->type;
1011 n->type->bound = -1;
1012 dowidth(n->type);
1013 n->op = OSLICEARR;
1014 } else if(isslice(t)) {
1015 n->type = t;
1016 } else {
1017 yyerror("cannot slice %N (type %T)", l, t);
1018 goto error;
Russ Cox10eb76b2010-04-29 15:52:27 -07001019 }
Russ Cox870f4e12014-09-25 13:24:43 -04001020 if((lo = n->right->left) != N && checksliceindex(l, lo, tp) < 0)
Russ Coxb4e92ce2013-07-01 20:32:36 -04001021 goto error;
Russ Cox870f4e12014-09-25 13:24:43 -04001022 if((hi = n->right->right) != N && checksliceindex(l, hi, tp) < 0)
Russ Coxb4e92ce2013-07-01 20:32:36 -04001023 goto error;
1024 if(checksliceconst(lo, hi) < 0)
1025 goto error;
1026 goto ret;
1027
1028 case OSLICE3:
1029 ok |= Erv;
1030 typecheck(&n->left, top);
1031 typecheck(&n->right->left, Erv);
1032 typecheck(&n->right->right->left, Erv);
1033 typecheck(&n->right->right->right, Erv);
1034 defaultlit(&n->left, T);
1035 indexlit(&n->right->left);
1036 indexlit(&n->right->right->left);
1037 indexlit(&n->right->right->right);
1038 l = n->left;
1039 if(isfixedarray(l->type)) {
1040 if(!islvalue(n->left)) {
1041 yyerror("invalid operation %N (slice of unaddressable value)", n);
Scott Lawrencefce222a2010-09-08 22:20:29 -04001042 goto error;
Russ Cox82ee4812010-09-10 11:53:27 -04001043 }
Russ Coxb4e92ce2013-07-01 20:32:36 -04001044 n->left = nod(OADDR, n->left, N);
1045 n->left->implicit = 1;
1046 typecheck(&n->left, Erv);
1047 l = n->left;
Russ Coxff3a73b2009-07-30 16:53:08 -07001048 }
Russ Coxb4e92ce2013-07-01 20:32:36 -04001049 if((t = l->type) == T)
1050 goto error;
1051 tp = nil;
1052 if(istype(t, TSTRING)) {
1053 yyerror("invalid operation %N (3-index slice of string)", n);
Ian Lance Taylor08918ba2012-12-05 15:46:45 -08001054 goto error;
1055 }
Russ Coxb4e92ce2013-07-01 20:32:36 -04001056 if(isptr[t->etype] && isfixedarray(t->type)) {
1057 tp = t->type;
1058 n->type = typ(TARRAY);
1059 n->type->type = tp->type;
1060 n->type->bound = -1;
1061 dowidth(n->type);
1062 n->op = OSLICE3ARR;
1063 } else if(isslice(t)) {
1064 n->type = t;
1065 } else {
1066 yyerror("cannot slice %N (type %T)", l, t);
1067 goto error;
1068 }
Russ Cox870f4e12014-09-25 13:24:43 -04001069 if((lo = n->right->left) != N && checksliceindex(l, lo, tp) < 0)
Russ Coxb4e92ce2013-07-01 20:32:36 -04001070 goto error;
Russ Cox870f4e12014-09-25 13:24:43 -04001071 if((mid = n->right->right->left) != N && checksliceindex(l, mid, tp) < 0)
Russ Coxb4e92ce2013-07-01 20:32:36 -04001072 goto error;
Russ Cox870f4e12014-09-25 13:24:43 -04001073 if((hi = n->right->right->right) != N && checksliceindex(l, hi, tp) < 0)
Russ Coxb4e92ce2013-07-01 20:32:36 -04001074 goto error;
1075 if(checksliceconst(lo, hi) < 0 || checksliceconst(lo, mid) < 0 || checksliceconst(mid, hi) < 0)
1076 goto error;
Ian Lance Taylor72bf3bc2012-11-06 11:35:58 -08001077 goto ret;
Russ Coxaa6e81dd2009-09-09 16:59:41 -07001078
Russ Coxff3a73b2009-07-30 16:53:08 -07001079 /*
1080 * call and call like
1081 */
1082 case OCALL:
1083 l = n->left;
Russ Coxcdb446f2010-07-15 16:13:47 -07001084 if(l->op == ONAME && (r = unsafenmagic(n)) != N) {
Russ Cox75dd8fd2010-09-24 11:55:30 -04001085 if(n->isddd)
Luuk van Dijk50110c92011-10-31 18:09:40 +01001086 yyerror("invalid use of ... with builtin %N", l);
Russ Cox76da2782010-06-12 11:17:24 -07001087 n = r;
1088 goto reswitch;
1089 }
Luuk van Dijk2c4edb02011-06-01 17:02:43 +02001090 typecheck(&n->left, Erv | Etype | Ecall |(top&Eproc));
Jan Ziak14837472014-03-14 16:42:42 +01001091 n->diag |= n->left->diag;
Russ Cox76da2782010-06-12 11:17:24 -07001092 l = n->left;
Russ Coxff3a73b2009-07-30 16:53:08 -07001093 if(l->op == ONAME && l->etype != 0) {
Russ Coxd8b5d032010-10-27 17:56:32 -07001094 if(n->isddd && l->etype != OAPPEND)
Luuk van Dijk50110c92011-10-31 18:09:40 +01001095 yyerror("invalid use of ... with builtin %N", l);
Russ Coxff3a73b2009-07-30 16:53:08 -07001096 // builtin: OLEN, OCAP, etc.
1097 n->op = l->etype;
1098 n->left = n->right;
1099 n->right = N;
1100 goto reswitch;
1101 }
Russ Cox9dc22b62009-08-03 11:58:52 -07001102 defaultlit(&n->left, T);
1103 l = n->left;
Russ Coxa75e3472009-10-15 16:03:01 -07001104 if(l->op == OTYPE) {
Russ Coxf607c472013-02-01 21:21:27 -05001105 if(n->isddd || l->type->bound == -100) {
1106 if(!l->type->broke)
1107 yyerror("invalid use of ... in type conversion", l);
1108 n->diag = 1;
1109 }
Russ Coxa75e3472009-10-15 16:03:01 -07001110 // pick off before type-checking arguments
1111 ok |= Erv;
1112 // turn CALL(type, arg) into CONV(arg) w/ type
1113 n->left = N;
Russ Coxa75e3472009-10-15 16:03:01 -07001114 n->op = OCONV;
1115 n->type = l->type;
Russ Coxa212d172010-06-20 11:45:53 -07001116 if(onearg(n, "conversion to %T", l->type) < 0)
1117 goto error;
Russ Coxa75e3472009-10-15 16:03:01 -07001118 goto doconv;
1119 }
1120
Rémy Oudompheng656b1922012-07-13 08:05:41 +02001121 if(count(n->list) == 1 && !n->isddd)
Russ Cox54b40372009-08-05 00:42:44 -07001122 typecheck(&n->list->n, Erv | Efnstruct);
1123 else
1124 typechecklist(n->list, Erv);
Russ Coxff3a73b2009-07-30 16:53:08 -07001125 if((t = l->type) == T)
Russ Coxff3a73b2009-07-30 16:53:08 -07001126 goto error;
Russ Coxb6487162009-08-07 12:50:26 -07001127 checkwidth(t);
Russ Cox9dc22b62009-08-03 11:58:52 -07001128
1129 switch(l->op) {
Russ Cox9dc22b62009-08-03 11:58:52 -07001130 case ODOTINTER:
1131 n->op = OCALLINTER;
1132 break;
1133
1134 case ODOTMETH:
1135 n->op = OCALLMETH;
Anthony Martin0b209b32011-05-24 19:48:19 -04001136 // typecheckaste was used here but there wasn't enough
1137 // information further down the call chain to know if we
1138 // were testing a method receiver for unexported fields.
1139 // It isn't necessary, so just do a sanity check.
1140 tp = getthisx(t)->type->type;
1141 if(l->left == N || !eqtype(l->left->type, tp))
1142 fatal("method receiver");
Russ Cox9dc22b62009-08-03 11:58:52 -07001143 break;
1144
1145 default:
1146 n->op = OCALLFUNC;
1147 if(t->etype != TFUNC) {
Luuk van Dijk50110c92011-10-31 18:09:40 +01001148 yyerror("cannot call non-function %N (type %T)", l, t);
Russ Cox9dc22b62009-08-03 11:58:52 -07001149 goto error;
1150 }
1151 break;
Russ Coxff3a73b2009-07-30 16:53:08 -07001152 }
Jan Ziaka599b482014-04-11 15:57:30 +02001153 if(snprint(descbuf, sizeof descbuf, "argument to %N", n->left) < sizeof descbuf)
1154 desc = descbuf;
1155 else
1156 desc = "function argument";
1157 typecheckaste(OCALL, n->left, n->isddd, getinargx(t), n->list, desc);
Russ Cox54b40372009-08-05 00:42:44 -07001158 ok |= Etop;
1159 if(t->outtuple == 0)
Russ Coxff3a73b2009-07-30 16:53:08 -07001160 goto ret;
Russ Cox54b40372009-08-05 00:42:44 -07001161 ok |= Erv;
Russ Coxff3a73b2009-07-30 16:53:08 -07001162 if(t->outtuple == 1) {
Russ Coxff3a73b2009-07-30 16:53:08 -07001163 t = getoutargx(l->type)->type;
Russ Cox680ee6a2009-10-08 23:03:34 -07001164 if(t == T)
1165 goto error;
Russ Coxff3a73b2009-07-30 16:53:08 -07001166 if(t->etype == TFIELD)
1167 t = t->type;
1168 n->type = t;
1169 goto ret;
1170 }
1171 // multiple return
Russ Cox54b40372009-08-05 00:42:44 -07001172 if(!(top & (Efnstruct | Etop))) {
Luuk van Dijk50110c92011-10-31 18:09:40 +01001173 yyerror("multiple-value %N() in single-value context", l);
Russ Cox54b40372009-08-05 00:42:44 -07001174 goto ret;
1175 }
Russ Coxff3a73b2009-07-30 16:53:08 -07001176 n->type = getoutargx(l->type);
1177 goto ret;
1178
1179 case OCAP:
1180 case OLEN:
Ken Thompson426099f2010-03-05 20:16:04 -08001181 case OREAL:
1182 case OIMAG:
Russ Cox54b40372009-08-05 00:42:44 -07001183 ok |= Erv;
Luuk van Dijk50110c92011-10-31 18:09:40 +01001184 if(onearg(n, "%O", n->op) < 0)
Russ Coxff3a73b2009-07-30 16:53:08 -07001185 goto error;
1186 typecheck(&n->left, Erv);
1187 defaultlit(&n->left, T);
1188 implicitstar(&n->left);
1189 l = n->left;
Ken Thompson426099f2010-03-05 20:16:04 -08001190 t = l->type;
1191 if(t == T)
Russ Coxff3a73b2009-07-30 16:53:08 -07001192 goto error;
1193 switch(n->op) {
1194 case OCAP:
1195 if(!okforcap[t->etype])
1196 goto badcall1;
1197 break;
1198 case OLEN:
1199 if(!okforlen[t->etype])
1200 goto badcall1;
1201 break;
Ken Thompson426099f2010-03-05 20:16:04 -08001202 case OREAL:
1203 case OIMAG:
1204 if(!iscomplex[t->etype])
1205 goto badcall1;
Anthony Martin94df1a02011-01-05 13:12:30 -05001206 if(isconst(l, CTCPLX)){
Russ Cox79a16a32013-02-01 21:02:15 -05001207 r = n;
Anthony Martin94df1a02011-01-05 13:12:30 -05001208 if(n->op == OREAL)
1209 n = nodfltconst(&l->val.u.cval->real);
1210 else
1211 n = nodfltconst(&l->val.u.cval->imag);
Russ Cox79a16a32013-02-01 21:02:15 -05001212 n->orig = r;
Anthony Martin94df1a02011-01-05 13:12:30 -05001213 }
Ken Thompson426099f2010-03-05 20:16:04 -08001214 n->type = types[cplxsubtype(t->etype)];
1215 goto ret;
Russ Coxff3a73b2009-07-30 16:53:08 -07001216 }
1217 // might be constant
1218 switch(t->etype) {
1219 case TSTRING:
Russ Cox8133cb32011-04-28 13:14:35 -04001220 if(isconst(l, CTSTR)) {
1221 r = nod(OXXX, N, N);
1222 nodconst(r, types[TINT], l->val.u.sval->len);
1223 r->orig = n;
1224 n = r;
1225 }
Russ Coxff3a73b2009-07-30 16:53:08 -07001226 break;
1227 case TARRAY:
Russ Coxd4fb5682012-03-07 22:43:28 -05001228 if(t->bound < 0) // slice
1229 break;
1230 if(callrecv(l)) // has call or receive
1231 break;
1232 r = nod(OXXX, N, N);
1233 nodconst(r, types[TINT], t->bound);
1234 r->orig = n;
1235 n = r;
Russ Coxff3a73b2009-07-30 16:53:08 -07001236 break;
1237 }
1238 n->type = types[TINT];
1239 goto ret;
1240
Russ Cox08499442011-01-19 23:08:11 -05001241 case OCOMPLEX:
Ken Thompson426099f2010-03-05 20:16:04 -08001242 ok |= Erv;
Chris Manghane671cc6e2014-03-05 14:16:21 -05001243 if(count(n->list) == 1) {
1244 typechecklist(n->list, Efnstruct);
Shenghou Macb1897a2014-12-28 19:18:54 -05001245 if(n->list->n->op != OCALLFUNC && n->list->n->op != OCALLMETH) {
1246 yyerror("invalid operation: complex expects two arguments");
1247 goto error;
1248 }
Chris Manghane671cc6e2014-03-05 14:16:21 -05001249 t = n->list->n->left->type;
1250 if(t->outtuple != 2) {
1251 yyerror("invalid operation: complex expects two arguments, %N returns %d results", n->list->n, t->outtuple);
1252 goto error;
1253 }
1254 t = n->list->n->type->type;
1255 l = t->nname;
1256 r = t->down->nname;
1257 } else {
1258 if(twoarg(n) < 0)
1259 goto error;
1260 l = typecheck(&n->left, Erv | (top & Eiota));
1261 r = typecheck(&n->right, Erv | (top & Eiota));
1262 if(l->type == T || r->type == T)
1263 goto error;
1264 defaultlit2(&l, &r, 0);
1265 if(l->type == T || r->type == T)
1266 goto error;
1267 n->left = l;
1268 n->right = r;
1269 }
Rémy Oudompheng401e0fe2013-03-11 22:55:14 +01001270 if(!eqtype(l->type, r->type)) {
Rémy Oudompheng401e0fe2013-03-11 22:55:14 +01001271 yyerror("invalid operation: %N (mismatched types %T and %T)", n, l->type, r->type);
Ken Thompson426099f2010-03-05 20:16:04 -08001272 goto error;
1273 }
1274 switch(l->type->etype) {
1275 default:
Rémy Oudompheng861aa462013-03-16 00:37:28 +01001276 yyerror("invalid operation: %N (arguments have type %T, expected floating-point)", n, l->type, r->type);
1277 goto error;
Russ Cox4ac011a2010-03-08 15:44:18 -08001278 case TIDEAL:
1279 t = types[TIDEAL];
1280 break;
Ken Thompson426099f2010-03-05 20:16:04 -08001281 case TFLOAT32:
Russ Cox4ac011a2010-03-08 15:44:18 -08001282 t = types[TCOMPLEX64];
Ken Thompson426099f2010-03-05 20:16:04 -08001283 break;
1284 case TFLOAT64:
Russ Cox4ac011a2010-03-08 15:44:18 -08001285 t = types[TCOMPLEX128];
Ken Thompson426099f2010-03-05 20:16:04 -08001286 break;
1287 }
Russ Cox4ac011a2010-03-08 15:44:18 -08001288 if(l->op == OLITERAL && r->op == OLITERAL) {
1289 // make it a complex literal
Russ Cox79a16a32013-02-01 21:02:15 -05001290 r = nodcplxlit(l->val, r->val);
1291 r->orig = n;
1292 n = r;
Russ Cox4ac011a2010-03-08 15:44:18 -08001293 }
1294 n->type = t;
Ken Thompson426099f2010-03-05 20:16:04 -08001295 goto ret;
1296
Russ Coxff3a73b2009-07-30 16:53:08 -07001297 case OCLOSE:
Luuk van Dijk50110c92011-10-31 18:09:40 +01001298 if(onearg(n, "%O", n->op) < 0)
Russ Coxff3a73b2009-07-30 16:53:08 -07001299 goto error;
1300 typecheck(&n->left, Erv);
1301 defaultlit(&n->left, T);
1302 l = n->left;
1303 if((t = l->type) == T)
1304 goto error;
1305 if(t->etype != TCHAN) {
Luuk van Dijk50110c92011-10-31 18:09:40 +01001306 yyerror("invalid operation: %N (non-chan type %T)", n, t);
Russ Coxff3a73b2009-07-30 16:53:08 -07001307 goto error;
1308 }
Russ Coxf58ed4e2011-10-13 16:58:04 -04001309 if(!(t->chan & Csend)) {
Luuk van Dijk556258e2012-01-10 11:09:04 +01001310 yyerror("invalid operation: %N (cannot close receive-only channel)", n);
Russ Coxf58ed4e2011-10-13 16:58:04 -04001311 goto error;
1312 }
Russ Cox8bf34e32011-03-11 14:47:26 -05001313 ok |= Etop;
Russ Coxff3a73b2009-07-30 16:53:08 -07001314 goto ret;
1315
Russ Cox1d687c72011-10-18 09:41:32 -04001316 case ODELETE:
1317 args = n->list;
1318 if(args == nil) {
1319 yyerror("missing arguments to delete");
1320 goto error;
1321 }
1322 if(args->next == nil) {
1323 yyerror("missing second (key) argument to delete");
1324 goto error;
1325 }
1326 if(args->next->next != nil) {
1327 yyerror("too many arguments to delete");
1328 goto error;
1329 }
1330 ok |= Etop;
1331 typechecklist(args, Erv);
1332 l = args->n;
1333 r = args->next->n;
1334 if(l->type != T && l->type->etype != TMAP) {
1335 yyerror("first argument to delete must be map; have %lT", l->type);
1336 goto error;
1337 }
1338 args->next->n = assignconv(r, l->type->down, "delete");
1339 goto ret;
1340
Russ Coxd8b5d032010-10-27 17:56:32 -07001341 case OAPPEND:
1342 ok |= Erv;
1343 args = n->list;
1344 if(args == nil) {
1345 yyerror("missing arguments to append");
1346 goto error;
1347 }
Chris Manghane671cc6e2014-03-05 14:16:21 -05001348
1349 if(count(args) == 1 && !n->isddd)
1350 typecheck(&args->n, Erv | Efnstruct);
1351 else
1352 typechecklist(args, Erv);
1353
Russ Coxd8b5d032010-10-27 17:56:32 -07001354 if((t = args->n->type) == T)
1355 goto error;
Chris Manghane671cc6e2014-03-05 14:16:21 -05001356
1357 // Unpack multiple-return result before type-checking.
Chris Manghanef5b88132015-01-20 14:35:33 -08001358 if(istype(t, TSTRUCT) && t->funarg) {
Chris Manghane671cc6e2014-03-05 14:16:21 -05001359 t = t->type;
1360 if(istype(t, TFIELD))
1361 t = t->type;
1362 }
1363
Russ Coxd8b5d032010-10-27 17:56:32 -07001364 n->type = t;
1365 if(!isslice(t)) {
Russ Coxfcc1f2a2012-05-15 12:51:58 -04001366 if(isconst(args->n, CTNIL)) {
1367 yyerror("first argument to append must be typed slice; have untyped nil", t);
1368 goto error;
1369 }
Russ Coxd8b5d032010-10-27 17:56:32 -07001370 yyerror("first argument to append must be slice; have %lT", t);
1371 goto error;
1372 }
Luuk van Dijk151b2f12011-11-09 11:17:06 +01001373
Russ Coxd8b5d032010-10-27 17:56:32 -07001374 if(n->isddd) {
1375 if(args->next == nil) {
1376 yyerror("cannot use ... on first argument to append");
1377 goto error;
1378 }
1379 if(args->next->next != nil) {
1380 yyerror("too many arguments to append");
1381 goto error;
1382 }
Russ Cox862179b2011-10-18 14:55:50 -04001383 if(istype(t->type, TUINT8) && istype(args->next->n->type, TSTRING)) {
Luuk van Dijk77fac212011-10-12 15:59:23 +02001384 defaultlit(&args->next->n, types[TSTRING]);
1385 goto ret;
1386 }
Russ Coxd8b5d032010-10-27 17:56:32 -07001387 args->next->n = assignconv(args->next->n, t->orig, "append");
1388 goto ret;
1389 }
1390 for(args=args->next; args != nil; args=args->next) {
1391 if(args->n->type == T)
1392 continue;
1393 args->n = assignconv(args->n, t->type, "append");
1394 }
1395 goto ret;
1396
Ken Thompsonc4606d02009-11-17 20:41:44 -08001397 case OCOPY:
Ken Thompson01c2de02009-11-17 22:00:59 -08001398 ok |= Etop|Erv;
Ken Thompsonc4606d02009-11-17 20:41:44 -08001399 args = n->list;
1400 if(args == nil || args->next == nil) {
1401 yyerror("missing arguments to copy");
1402 goto error;
1403 }
1404 if(args->next->next != nil) {
1405 yyerror("too many arguments to copy");
1406 goto error;
1407 }
Ken Thompsonc4606d02009-11-17 20:41:44 -08001408 n->left = args->n;
1409 n->right = args->next->n;
Luuk van Dijk847b61b2011-08-24 19:07:08 +02001410 n->list = nil;
Ken Thompsonc4606d02009-11-17 20:41:44 -08001411 n->type = types[TINT];
Ken Thompson01c2de02009-11-17 22:00:59 -08001412 typecheck(&n->left, Erv);
1413 typecheck(&n->right, Erv);
Russ Cox9be56ad2009-11-18 14:26:28 -08001414 if(n->left->type == T || n->right->type == T)
1415 goto error;
Russ Cox07fc1452010-01-18 16:00:13 -08001416 defaultlit(&n->left, T);
1417 defaultlit(&n->right, T);
Russ Cox56b983c2014-03-03 19:55:40 -05001418 if(n->left->type == T || n->right->type == T)
1419 goto error;
Luuk van Dijk77fac212011-10-12 15:59:23 +02001420
Russ Cox82c6f5e2010-10-26 08:36:07 -07001421 // copy([]byte, string)
Quan Yong Zhai256df102011-04-21 12:09:29 -04001422 if(isslice(n->left->type) && n->right->type->etype == TSTRING) {
Russ Cox862179b2011-10-18 14:55:50 -04001423 if(eqtype(n->left->type->type, bytetype))
Luuk van Dijk2c4edb02011-06-01 17:02:43 +02001424 goto ret;
1425 yyerror("arguments to copy have different element types: %lT and string", n->left->type);
Quan Yong Zhai256df102011-04-21 12:09:29 -04001426 goto error;
1427 }
Luuk van Dijk77fac212011-10-12 15:59:23 +02001428
Ken Thompson01c2de02009-11-17 22:00:59 -08001429 if(!isslice(n->left->type) || !isslice(n->right->type)) {
Russ Cox07fc1452010-01-18 16:00:13 -08001430 if(!isslice(n->left->type) && !isslice(n->right->type))
Russ Cox565b5dc2010-06-08 18:50:02 -07001431 yyerror("arguments to copy must be slices; have %lT, %lT", n->left->type, n->right->type);
Russ Cox07fc1452010-01-18 16:00:13 -08001432 else if(!isslice(n->left->type))
Russ Cox565b5dc2010-06-08 18:50:02 -07001433 yyerror("first argument to copy should be slice; have %lT", n->left->type);
Russ Cox07fc1452010-01-18 16:00:13 -08001434 else
Russ Cox82c6f5e2010-10-26 08:36:07 -07001435 yyerror("second argument to copy should be slice or string; have %lT", n->right->type);
Ken Thompson01c2de02009-11-17 22:00:59 -08001436 goto error;
1437 }
Russ Cox565b5dc2010-06-08 18:50:02 -07001438 if(!eqtype(n->left->type->type, n->right->type->type)) {
1439 yyerror("arguments to copy have different element types: %lT and %lT", n->left->type, n->right->type);
Ken Thompson01c2de02009-11-17 22:00:59 -08001440 goto error;
1441 }
Ken Thompsonc4606d02009-11-17 20:41:44 -08001442 goto ret;
1443
Russ Coxff3a73b2009-07-30 16:53:08 -07001444 case OCONV:
1445 doconv:
Russ Cox54b40372009-08-05 00:42:44 -07001446 ok |= Erv;
Rémy Oudomphengb0bb6f82013-03-04 16:42:03 +01001447 saveorignode(n);
Russ Cox76da2782010-06-12 11:17:24 -07001448 typecheck(&n->left, Erv | (top & (Eindir | Eiota)));
Russ Cox60ff8cc2009-10-20 08:27:14 -07001449 convlit1(&n->left, n->type, 1);
Russ Cox9dc22b62009-08-03 11:58:52 -07001450 if((t = n->left->type) == T || n->type == T)
Russ Coxff3a73b2009-07-30 16:53:08 -07001451 goto error;
Russ Cox565b5dc2010-06-08 18:50:02 -07001452 if((n->op = convertop(t, n->type, &why)) == 0) {
Russ Coxf607c472013-02-01 21:21:27 -05001453 if(!n->diag && !n->type->broke) {
1454 yyerror("cannot convert %lN to type %T%s", n->left, n->type, why);
1455 n->diag = 1;
1456 }
Lucio De Reb3cc4892011-08-29 09:35:04 -04001457 n->op = OCONV;
Russ Cox565b5dc2010-06-08 18:50:02 -07001458 }
Russ Cox39101612010-02-25 15:11:07 -08001459 switch(n->op) {
Russ Cox565b5dc2010-06-08 18:50:02 -07001460 case OCONVNOP:
Chris Manghane5cc29ab2014-12-09 07:16:38 -08001461 if(n->left->op == OLITERAL && n->type != types[TBOOL]) {
Russ Cox79a16a32013-02-01 21:02:15 -05001462 r = nod(OXXX, N, N);
1463 n->op = OCONV;
1464 n->orig = r;
1465 *r = *n;
Russ Cox565b5dc2010-06-08 18:50:02 -07001466 n->op = OLITERAL;
1467 n->val = n->left->val;
1468 }
1469 break;
Russ Cox39101612010-02-25 15:11:07 -08001470 case OSTRARRAYBYTE:
Russ Coxd227d682014-01-06 20:43:44 -05001471 // do not use stringtoarraylit.
1472 // generated code and compiler memory footprint is better without it.
1473 break;
Russ Cox39101612010-02-25 15:11:07 -08001474 case OSTRARRAYRUNE:
1475 if(n->left->op == OLITERAL)
1476 stringtoarraylit(&n);
1477 break;
1478 }
Russ Coxff3a73b2009-07-30 16:53:08 -07001479 goto ret;
1480
1481 case OMAKE:
Russ Cox54b40372009-08-05 00:42:44 -07001482 ok |= Erv;
Russ Coxff3a73b2009-07-30 16:53:08 -07001483 args = n->list;
1484 if(args == nil) {
1485 yyerror("missing argument to make");
1486 goto error;
1487 }
Russ Coxee9bfb02012-01-25 17:53:50 -05001488 n->list = nil;
Russ Coxff3a73b2009-07-30 16:53:08 -07001489 l = args->n;
1490 args = args->next;
1491 typecheck(&l, Etype);
1492 if((t = l->type) == T)
1493 goto error;
1494
1495 switch(t->etype) {
1496 default:
1497 badmake:
1498 yyerror("cannot make type %T", t);
1499 goto error;
1500
1501 case TARRAY:
1502 if(!isslice(t))
1503 goto badmake;
1504 if(args == nil) {
1505 yyerror("missing len argument to make(%T)", t);
1506 goto error;
1507 }
1508 l = args->n;
1509 args = args->next;
1510 typecheck(&l, Erv);
Russ Coxff3a73b2009-07-30 16:53:08 -07001511 r = N;
1512 if(args != nil) {
1513 r = args->n;
1514 args = args->next;
1515 typecheck(&r, Erv);
Russ Coxff3a73b2009-07-30 16:53:08 -07001516 }
1517 if(l->type == T || (r && r->type == T))
1518 goto error;
Russ Coxf02067a2013-02-03 14:28:44 -05001519 et = checkmake(t, "len", l) < 0;
1520 et |= r && checkmake(t, "cap", r) < 0;
1521 if(et)
Russ Coxff3a73b2009-07-30 16:53:08 -07001522 goto error;
Russ Coxf02067a2013-02-03 14:28:44 -05001523 if(isconst(l, CTINT) && r && isconst(r, CTINT) && mpcmpfixfix(l->val.u.xval, r->val.u.xval) > 0) {
1524 yyerror("len larger than cap in make(%T)", t);
Russ Coxff3a73b2009-07-30 16:53:08 -07001525 goto error;
1526 }
1527 n->left = l;
1528 n->right = r;
Russ Cox9dc22b62009-08-03 11:58:52 -07001529 n->op = OMAKESLICE;
Russ Coxff3a73b2009-07-30 16:53:08 -07001530 break;
1531
1532 case TMAP:
1533 if(args != nil) {
1534 l = args->n;
1535 args = args->next;
1536 typecheck(&l, Erv);
Russ Cox6361f522010-05-01 13:15:42 -07001537 defaultlit(&l, types[TINT]);
Russ Coxff3a73b2009-07-30 16:53:08 -07001538 if(l->type == T)
1539 goto error;
Russ Coxf02067a2013-02-03 14:28:44 -05001540 if(checkmake(t, "size", l) < 0)
Russ Coxff3a73b2009-07-30 16:53:08 -07001541 goto error;
Russ Coxff3a73b2009-07-30 16:53:08 -07001542 n->left = l;
Russ Cox9dc22b62009-08-03 11:58:52 -07001543 } else
1544 n->left = nodintconst(0);
1545 n->op = OMAKEMAP;
Russ Coxff3a73b2009-07-30 16:53:08 -07001546 break;
1547
1548 case TCHAN:
1549 l = N;
1550 if(args != nil) {
1551 l = args->n;
1552 args = args->next;
1553 typecheck(&l, Erv);
Russ Cox6361f522010-05-01 13:15:42 -07001554 defaultlit(&l, types[TINT]);
Russ Coxff3a73b2009-07-30 16:53:08 -07001555 if(l->type == T)
1556 goto error;
Russ Coxf02067a2013-02-03 14:28:44 -05001557 if(checkmake(t, "buffer", l) < 0)
Russ Coxff3a73b2009-07-30 16:53:08 -07001558 goto error;
Russ Coxff3a73b2009-07-30 16:53:08 -07001559 n->left = l;
Russ Cox9dc22b62009-08-03 11:58:52 -07001560 } else
1561 n->left = nodintconst(0);
1562 n->op = OMAKECHAN;
Russ Coxff3a73b2009-07-30 16:53:08 -07001563 break;
1564 }
1565 if(args != nil) {
1566 yyerror("too many arguments to make(%T)", t);
Russ Cox9dc22b62009-08-03 11:58:52 -07001567 n->op = OMAKE;
Russ Coxff3a73b2009-07-30 16:53:08 -07001568 goto error;
1569 }
1570 n->type = t;
1571 goto ret;
1572
1573 case ONEW:
Russ Cox54b40372009-08-05 00:42:44 -07001574 ok |= Erv;
Russ Coxff3a73b2009-07-30 16:53:08 -07001575 args = n->list;
1576 if(args == nil) {
1577 yyerror("missing argument to new");
1578 goto error;
1579 }
1580 l = args->n;
1581 typecheck(&l, Etype);
1582 if((t = l->type) == T)
1583 goto error;
1584 if(args->next != nil) {
1585 yyerror("too many arguments to new(%T)", t);
1586 goto error;
1587 }
1588 n->left = l;
1589 n->type = ptrto(t);
1590 goto ret;
1591
Russ Coxff3a73b2009-07-30 16:53:08 -07001592 case OPRINT:
1593 case OPRINTN:
Russ Cox54b40372009-08-05 00:42:44 -07001594 ok |= Etop;
Russ Coxdc9a3b22010-12-13 16:22:19 -05001595 typechecklist(n->list, Erv | Eindir); // Eindir: address does not escape
Russ Coxe29d3df2012-02-22 00:29:37 -05001596 for(args=n->list; args; args=args->next) {
1597 // Special case for print: int constant is int64, not int.
1598 if(isconst(args->n, CTINT))
1599 defaultlit(&args->n, types[TINT64]);
1600 else
1601 defaultlit(&args->n, T);
1602 }
Russ Coxff3a73b2009-07-30 16:53:08 -07001603 goto ret;
1604
Russ Cox01eaf782010-03-30 10:53:16 -07001605 case OPANIC:
1606 ok |= Etop;
Russ Coxa212d172010-06-20 11:45:53 -07001607 if(onearg(n, "panic") < 0)
Russ Cox01eaf782010-03-30 10:53:16 -07001608 goto error;
1609 typecheck(&n->left, Erv);
Russ Cox585eae32010-08-03 01:07:40 -07001610 defaultlit(&n->left, types[TINTER]);
Russ Cox01eaf782010-03-30 10:53:16 -07001611 if(n->left->type == T)
1612 goto error;
1613 goto ret;
1614
1615 case ORECOVER:
1616 ok |= Erv|Etop;
1617 if(n->list != nil) {
1618 yyerror("too many arguments to recover");
1619 goto error;
1620 }
1621 n->type = types[TINTER];
1622 goto ret;
1623
Russ Coxb6487162009-08-07 12:50:26 -07001624 case OCLOSURE:
1625 ok |= Erv;
Luuk van Dijk2c4edb02011-06-01 17:02:43 +02001626 typecheckclosure(n, top);
Russ Coxb6487162009-08-07 12:50:26 -07001627 if(n->type == T)
1628 goto error;
1629 goto ret;
Russ Coxf91cc3b2012-02-11 00:19:24 -05001630
1631 case OITAB:
1632 ok |= Erv;
1633 typecheck(&n->left, Erv);
1634 if((t = n->left->type) == T)
1635 goto error;
1636 if(t->etype != TINTER)
1637 fatal("OITAB of %T", t);
1638 n->type = ptrto(types[TUINTPTR]);
1639 goto ret;
Rémy Oudomphengff416a32013-09-12 00:15:28 +02001640
1641 case OSPTR:
1642 ok |= Erv;
1643 typecheck(&n->left, Erv);
1644 if((t = n->left->type) == T)
1645 goto error;
1646 if(!isslice(t) && t->etype != TSTRING)
1647 fatal("OSPTR of %T", t);
1648 if(t->etype == TSTRING)
1649 n->type = ptrto(types[TUINT8]);
1650 else
1651 n->type = ptrto(t->type);
1652 goto ret;
1653
Russ Cox9f647282013-02-22 14:25:50 -05001654 case OCLOSUREVAR:
1655 ok |= Erv;
1656 goto ret;
1657
1658 case OCFUNC:
1659 ok |= Erv;
1660 typecheck(&n->left, Erv);
1661 n->type = types[TUINTPTR];
1662 goto ret;
1663
1664 case OCONVNOP:
1665 ok |= Erv;
1666 typecheck(&n->left, Erv);
1667 goto ret;
Russ Coxb6487162009-08-07 12:50:26 -07001668
Russ Coxff3a73b2009-07-30 16:53:08 -07001669 /*
1670 * statements
1671 */
1672 case OAS:
Russ Cox54b40372009-08-05 00:42:44 -07001673 ok |= Etop;
1674 typecheckas(n);
Dmitry Vyukova7bb3932015-01-26 17:19:00 +03001675 // Code that creates temps does not bother to set defn, so do it here.
1676 if(n->left->op == ONAME && strncmp(n->left->sym->name, "autotmp_", 8) == 0)
1677 n->left->defn = n;
Russ Coxff3a73b2009-07-30 16:53:08 -07001678 goto ret;
1679
1680 case OAS2:
Russ Cox54b40372009-08-05 00:42:44 -07001681 ok |= Etop;
Russ Coxd8c19c82009-08-04 10:26:29 -07001682 typecheckas2(n);
Russ Coxff3a73b2009-07-30 16:53:08 -07001683 goto ret;
1684
1685 case OBREAK:
1686 case OCONTINUE:
1687 case ODCL:
1688 case OEMPTY:
1689 case OGOTO:
Russ Coxff3a73b2009-07-30 16:53:08 -07001690 case OXFALL:
Russ Coxb700cb42014-04-01 13:31:38 -04001691 case OVARKILL:
Russ Cox54b40372009-08-05 00:42:44 -07001692 ok |= Etop;
Russ Coxff3a73b2009-07-30 16:53:08 -07001693 goto ret;
1694
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +03001695 case OLABEL:
1696 ok |= Etop;
1697 decldepth++;
1698 goto ret;
1699
Russ Coxff3a73b2009-07-30 16:53:08 -07001700 case ODEFER:
Russ Cox54b40372009-08-05 00:42:44 -07001701 ok |= Etop;
Russ Cox79a16a32013-02-01 21:02:15 -05001702 typecheck(&n->left, Etop|Erv);
1703 if(!n->left->diag)
1704 checkdefergo(n);
Russ Coxff3a73b2009-07-30 16:53:08 -07001705 goto ret;
1706
Luuk van Dijk2c4edb02011-06-01 17:02:43 +02001707 case OPROC:
1708 ok |= Etop;
Russ Cox79a16a32013-02-01 21:02:15 -05001709 typecheck(&n->left, Etop|Eproc|Erv);
1710 checkdefergo(n);
Luuk van Dijk2c4edb02011-06-01 17:02:43 +02001711 goto ret;
1712
Russ Coxff3a73b2009-07-30 16:53:08 -07001713 case OFOR:
Russ Cox54b40372009-08-05 00:42:44 -07001714 ok |= Etop;
Russ Coxff3a73b2009-07-30 16:53:08 -07001715 typechecklist(n->ninit, Etop);
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +03001716 decldepth++;
Russ Coxd8c19c82009-08-04 10:26:29 -07001717 typecheck(&n->ntest, Erv);
1718 if(n->ntest != N && (t = n->ntest->type) != T && t->etype != TBOOL)
Luuk van Dijk50110c92011-10-31 18:09:40 +01001719 yyerror("non-bool %lN used as for condition", n->ntest);
Russ Coxff3a73b2009-07-30 16:53:08 -07001720 typecheck(&n->nincr, Etop);
1721 typechecklist(n->nbody, Etop);
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +03001722 decldepth--;
Russ Coxff3a73b2009-07-30 16:53:08 -07001723 goto ret;
1724
1725 case OIF:
Russ Cox54b40372009-08-05 00:42:44 -07001726 ok |= Etop;
Russ Coxff3a73b2009-07-30 16:53:08 -07001727 typechecklist(n->ninit, Etop);
Russ Coxd8c19c82009-08-04 10:26:29 -07001728 typecheck(&n->ntest, Erv);
1729 if(n->ntest != N && (t = n->ntest->type) != T && t->etype != TBOOL)
Luuk van Dijk50110c92011-10-31 18:09:40 +01001730 yyerror("non-bool %lN used as if condition", n->ntest);
Russ Coxff3a73b2009-07-30 16:53:08 -07001731 typechecklist(n->nbody, Etop);
1732 typechecklist(n->nelse, Etop);
1733 goto ret;
1734
1735 case ORETURN:
Russ Cox54b40372009-08-05 00:42:44 -07001736 ok |= Etop;
Rémy Oudompheng1d3ca922012-02-16 23:42:19 +01001737 if(count(n->list) == 1)
1738 typechecklist(n->list, Erv | Efnstruct);
1739 else
1740 typechecklist(n->list, Erv);
Russ Coxf20c2e12010-07-26 17:34:17 -07001741 if(curfn == N) {
1742 yyerror("return outside function");
1743 goto error;
1744 }
Russ Cox9dc22b62009-08-03 11:58:52 -07001745 if(curfn->type->outnamed && n->list == nil)
1746 goto ret;
Russ Cox50387922011-01-30 16:07:57 -05001747 typecheckaste(ORETURN, nil, 0, getoutargx(curfn->type), n->list, "return argument");
Russ Coxff3a73b2009-07-30 16:53:08 -07001748 goto ret;
Russ Cox1f51d272013-06-11 09:41:49 -04001749
1750 case ORETJMP:
1751 ok |= Etop;
1752 goto ret;
Russ Coxff3a73b2009-07-30 16:53:08 -07001753
1754 case OSELECT:
Russ Cox54b40372009-08-05 00:42:44 -07001755 ok |= Etop;
Russ Coxf7a867e2009-08-04 12:57:48 -07001756 typecheckselect(n);
Russ Coxff3a73b2009-07-30 16:53:08 -07001757 goto ret;
1758
1759 case OSWITCH:
Russ Cox54b40372009-08-05 00:42:44 -07001760 ok |= Etop;
Russ Coxd8c19c82009-08-04 10:26:29 -07001761 typecheckswitch(n);
Russ Coxff3a73b2009-07-30 16:53:08 -07001762 goto ret;
1763
Russ Cox26097312009-08-05 02:33:30 -07001764 case ORANGE:
1765 ok |= Etop;
1766 typecheckrange(n);
1767 goto ret;
1768
Russ Coxff3a73b2009-07-30 16:53:08 -07001769 case OTYPESW:
Russ Cox83bdb802009-09-09 01:21:20 -07001770 yyerror("use of .(type) outside type switch");
1771 goto error;
Russ Coxff3a73b2009-07-30 16:53:08 -07001772
1773 case OXCASE:
Russ Cox54b40372009-08-05 00:42:44 -07001774 ok |= Etop;
Russ Coxff3a73b2009-07-30 16:53:08 -07001775 typechecklist(n->list, Erv);
1776 typechecklist(n->nbody, Etop);
1777 goto ret;
Russ Coxb6487162009-08-07 12:50:26 -07001778
1779 case ODCLFUNC:
1780 ok |= Etop;
1781 typecheckfunc(n);
1782 goto ret;
1783
1784 case ODCLCONST:
1785 ok |= Etop;
1786 typecheck(&n->left, Erv);
1787 goto ret;
1788
1789 case ODCLTYPE:
1790 ok |= Etop;
1791 typecheck(&n->left, Etype);
Russ Cox05a1eb12009-12-03 01:12:02 -08001792 if(!incannedimport)
1793 checkwidth(n->left->type);
Russ Coxb6487162009-08-07 12:50:26 -07001794 goto ret;
Russ Coxff3a73b2009-07-30 16:53:08 -07001795 }
1796
1797ret:
Russ Coxb6487162009-08-07 12:50:26 -07001798 t = n->type;
1799 if(t && !t->funarg && n->op != OTYPE) {
1800 switch(t->etype) {
1801 case TFUNC: // might have TANY; wait until its called
1802 case TANY:
1803 case TFORW:
Russ Coxb6487162009-08-07 12:50:26 -07001804 case TIDEAL:
1805 case TNIL:
Russ Cox5438be42009-09-08 23:16:19 -07001806 case TBLANK:
Russ Coxb6487162009-08-07 12:50:26 -07001807 break;
1808 default:
1809 checkwidth(t);
1810 }
1811 }
Russ Coxd20ad1c2010-06-11 15:28:43 -07001812
Russ Coxc29f4e02012-09-21 21:12:41 -04001813 if(safemode && !incannedimport && !importpkg && !compiling_wrappers && t && t->etype == TUNSAFEPTR)
Russ Coxa2a7d472010-06-09 11:00:55 -07001814 yyerror("cannot use unsafe.Pointer");
Russ Coxb6487162009-08-07 12:50:26 -07001815
Russ Coxff3a73b2009-07-30 16:53:08 -07001816 evconst(n);
1817 if(n->op == OTYPE && !(top & Etype)) {
1818 yyerror("type %T is not an expression", n->type);
1819 goto error;
1820 }
Russ Cox9dc22b62009-08-03 11:58:52 -07001821 if((top & (Erv|Etype)) == Etype && n->op != OTYPE) {
Luuk van Dijk50110c92011-10-31 18:09:40 +01001822 yyerror("%N is not a type", n);
Russ Coxff3a73b2009-07-30 16:53:08 -07001823 goto error;
1824 }
Russ Coxb6487162009-08-07 12:50:26 -07001825 // TODO(rsc): simplify
1826 if((top & (Ecall|Erv|Etype)) && !(top & Etop) && !(ok & (Erv|Etype|Ecall))) {
Luuk van Dijk50110c92011-10-31 18:09:40 +01001827 yyerror("%N used as value", n);
Russ Cox54b40372009-08-05 00:42:44 -07001828 goto error;
1829 }
Russ Coxb6487162009-08-07 12:50:26 -07001830 if((top & Etop) && !(top & (Ecall|Erv|Etype)) && !(ok & Etop)) {
Russ Cox8133cb32011-04-28 13:14:35 -04001831 if(n->diag == 0) {
Russ Cox79a16a32013-02-01 21:02:15 -05001832 yyerror("%N evaluated but not used", n);
Russ Cox8133cb32011-04-28 13:14:35 -04001833 n->diag = 1;
1834 }
Russ Coxff3a73b2009-07-30 16:53:08 -07001835 goto error;
1836 }
1837
1838 /* TODO
1839 if(n->type == T)
1840 fatal("typecheck nil type");
1841 */
1842 goto out;
1843
1844badcall1:
Luuk van Dijk50110c92011-10-31 18:09:40 +01001845 yyerror("invalid argument %lN for %O", n->left, n->op);
Russ Coxff3a73b2009-07-30 16:53:08 -07001846 goto error;
1847
1848error:
1849 n->type = T;
1850
1851out:
Russ Coxff3a73b2009-07-30 16:53:08 -07001852 *np = n;
Russ Coxff3a73b2009-07-30 16:53:08 -07001853}
1854
Russ Coxb4e92ce2013-07-01 20:32:36 -04001855static int
Russ Cox870f4e12014-09-25 13:24:43 -04001856checksliceindex(Node *l, Node *r, Type *tp)
Russ Coxb4e92ce2013-07-01 20:32:36 -04001857{
1858 Type *t;
1859
1860 if((t = r->type) == T)
1861 return -1;
1862 if(!isint[t->etype]) {
1863 yyerror("invalid slice index %N (type %T)", r, t);
1864 return -1;
1865 }
1866 if(r->op == OLITERAL) {
1867 if(mpgetfix(r->val.u.xval) < 0) {
1868 yyerror("invalid slice index %N (index must be non-negative)", r);
1869 return -1;
1870 } else if(tp != nil && tp->bound > 0 && mpgetfix(r->val.u.xval) > tp->bound) {
1871 yyerror("invalid slice index %N (out of bounds for %d-element array)", r, tp->bound);
1872 return -1;
Russ Cox870f4e12014-09-25 13:24:43 -04001873 } else if(isconst(l, CTSTR) && mpgetfix(r->val.u.xval) > l->val.u.sval->len) {
1874 yyerror("invalid slice index %N (out of bounds for %d-byte string)", r, l->val.u.sval->len);
1875 return -1;
Russ Coxb4e92ce2013-07-01 20:32:36 -04001876 } else if(mpcmpfixfix(r->val.u.xval, maxintval[TINT]) > 0) {
1877 yyerror("invalid slice index %N (index too large)", r);
1878 return -1;
1879 }
1880 }
1881 return 0;
1882}
1883
1884static int
1885checksliceconst(Node *lo, Node *hi)
1886{
1887 if(lo != N && hi != N && lo->op == OLITERAL && hi->op == OLITERAL
1888 && mpcmpfixfix(lo->val.u.xval, hi->val.u.xval) > 0) {
1889 yyerror("invalid slice index: %N > %N", lo, hi);
1890 return -1;
1891 }
1892 return 0;
1893}
1894
Russ Coxff3a73b2009-07-30 16:53:08 -07001895static void
Russ Cox79a16a32013-02-01 21:02:15 -05001896checkdefergo(Node *n)
1897{
1898 char *what;
1899
1900 what = "defer";
1901 if(n->op == OPROC)
1902 what = "go";
1903
1904 switch(n->left->op) {
1905 case OCALLINTER:
1906 case OCALLMETH:
1907 case OCALLFUNC:
1908 case OCLOSE:
1909 case OCOPY:
1910 case ODELETE:
1911 case OPANIC:
1912 case OPRINT:
1913 case OPRINTN:
1914 case ORECOVER:
1915 // ok
1916 break;
1917 case OAPPEND:
1918 case OCAP:
1919 case OCOMPLEX:
1920 case OIMAG:
1921 case OLEN:
1922 case OMAKE:
1923 case OMAKESLICE:
1924 case OMAKECHAN:
1925 case OMAKEMAP:
1926 case ONEW:
1927 case OREAL:
1928 case OLITERAL: // conversion or unsafe.Alignof, Offsetof, Sizeof
1929 if(n->left->orig != N && n->left->orig->op == OCONV)
1930 goto conv;
1931 yyerror("%s discards result of %N", what, n->left);
1932 break;
1933 default:
1934 conv:
Daniel Morsing6f5af9c2013-05-21 18:35:47 +02001935 // type is broken or missing, most likely a method call on a broken type
1936 // we will warn about the broken type elsewhere. no need to emit a potentially confusing error
1937 if(n->left->type == T || n->left->type->broke)
1938 break;
1939
Russ Cox79a16a32013-02-01 21:02:15 -05001940 if(!n->diag) {
1941 // The syntax made sure it was a call, so this must be
1942 // a conversion.
1943 n->diag = 1;
1944 yyerror("%s requires function call, not conversion", what);
1945 }
1946 break;
1947 }
1948}
1949
1950static void
Russ Coxff3a73b2009-07-30 16:53:08 -07001951implicitstar(Node **nn)
1952{
1953 Type *t;
1954 Node *n;
1955
Russ Cox82ee4812010-09-10 11:53:27 -04001956 // insert implicit * if needed for fixed array
Russ Coxff3a73b2009-07-30 16:53:08 -07001957 n = *nn;
1958 t = n->type;
1959 if(t == T || !isptr[t->etype])
1960 return;
1961 t = t->type;
1962 if(t == T)
1963 return;
1964 if(!isfixedarray(t))
1965 return;
1966 n = nod(OIND, n, N);
Russ Cox7ae1fe42012-02-10 22:46:56 -05001967 n->implicit = 1;
Russ Coxff3a73b2009-07-30 16:53:08 -07001968 typecheck(&n, Erv);
1969 *nn = n;
1970}
1971
1972static int
Russ Coxa212d172010-06-20 11:45:53 -07001973onearg(Node *n, char *f, ...)
Russ Coxff3a73b2009-07-30 16:53:08 -07001974{
Russ Coxa212d172010-06-20 11:45:53 -07001975 va_list arg;
1976 char *p;
1977
Russ Coxff3a73b2009-07-30 16:53:08 -07001978 if(n->left != N)
1979 return 0;
1980 if(n->list == nil) {
Russ Coxa212d172010-06-20 11:45:53 -07001981 va_start(arg, f);
1982 p = vsmprint(f, arg);
1983 va_end(arg);
Luuk van Dijk50110c92011-10-31 18:09:40 +01001984 yyerror("missing argument to %s: %N", p, n);
Russ Coxff3a73b2009-07-30 16:53:08 -07001985 return -1;
1986 }
Russ Coxff3a73b2009-07-30 16:53:08 -07001987 if(n->list->next != nil) {
Russ Coxa212d172010-06-20 11:45:53 -07001988 va_start(arg, f);
1989 p = vsmprint(f, arg);
1990 va_end(arg);
Luuk van Dijk50110c92011-10-31 18:09:40 +01001991 yyerror("too many arguments to %s: %N", p, n);
Russ Coxa212d172010-06-20 11:45:53 -07001992 n->left = n->list->n;
Russ Coxff3a73b2009-07-30 16:53:08 -07001993 n->list = nil;
1994 return -1;
1995 }
Russ Coxa212d172010-06-20 11:45:53 -07001996 n->left = n->list->n;
Russ Coxff3a73b2009-07-30 16:53:08 -07001997 n->list = nil;
1998 return 0;
1999}
2000
Ken Thompson426099f2010-03-05 20:16:04 -08002001static int
2002twoarg(Node *n)
2003{
2004 if(n->left != N)
2005 return 0;
2006 if(n->list == nil) {
Luuk van Dijk50110c92011-10-31 18:09:40 +01002007 yyerror("missing argument to %O - %N", n->op, n);
Ken Thompson426099f2010-03-05 20:16:04 -08002008 return -1;
2009 }
2010 n->left = n->list->n;
2011 if(n->list->next == nil) {
Luuk van Dijk50110c92011-10-31 18:09:40 +01002012 yyerror("missing argument to %O - %N", n->op, n);
Ken Thompson426099f2010-03-05 20:16:04 -08002013 n->list = nil;
2014 return -1;
2015 }
2016 if(n->list->next->next != nil) {
Luuk van Dijk50110c92011-10-31 18:09:40 +01002017 yyerror("too many arguments to %O - %N", n->op, n);
Ken Thompson426099f2010-03-05 20:16:04 -08002018 n->list = nil;
2019 return -1;
2020 }
2021 n->right = n->list->next->n;
2022 n->list = nil;
2023 return 0;
2024}
2025
Russ Coxff3a73b2009-07-30 16:53:08 -07002026static Type*
Russ Cox7ae1fe42012-02-10 22:46:56 -05002027lookdot1(Node *errnode, Sym *s, Type *t, Type *f, int dostrcmp)
Russ Coxff3a73b2009-07-30 16:53:08 -07002028{
2029 Type *r;
2030
2031 r = T;
2032 for(; f!=T; f=f->down) {
Russ Cox5d754bf2009-12-15 16:22:04 -08002033 if(dostrcmp && strcmp(f->sym->name, s->name) == 0)
2034 return f;
Russ Coxff3a73b2009-07-30 16:53:08 -07002035 if(f->sym != s)
2036 continue;
2037 if(r != T) {
Russ Cox7ae1fe42012-02-10 22:46:56 -05002038 if(errnode)
2039 yyerror("ambiguous selector %N", errnode);
2040 else if(isptr[t->etype])
2041 yyerror("ambiguous selector (%T).%S", t, s);
2042 else
2043 yyerror("ambiguous selector %T.%S", t, s);
Russ Coxff3a73b2009-07-30 16:53:08 -07002044 break;
2045 }
2046 r = f;
2047 }
2048 return r;
2049}
2050
2051static int
Russ Cox00ffd592010-09-28 13:43:50 -04002052looktypedot(Node *n, Type *t, int dostrcmp)
2053{
Rémy Oudomphengced80042012-12-22 19:13:45 +01002054 Type *f1, *f2;
Russ Cox00ffd592010-09-28 13:43:50 -04002055 Sym *s;
2056
2057 s = n->right->sym;
2058
2059 if(t->etype == TINTER) {
Russ Cox7ae1fe42012-02-10 22:46:56 -05002060 f1 = lookdot1(n, s, t, t->type, dostrcmp);
Russ Cox00ffd592010-09-28 13:43:50 -04002061 if(f1 == T)
2062 return 0;
2063
Russ Cox00ffd592010-09-28 13:43:50 -04002064 n->right = methodname(n->right, t);
2065 n->xoffset = f1->width;
2066 n->type = f1->type;
2067 n->op = ODOTINTER;
2068 return 1;
2069 }
2070
Rémy Oudomphengced80042012-12-22 19:13:45 +01002071 // Find the base type: methtype will fail if t
2072 // is not of the form T or *T.
2073 f2 = methtype(t, 0);
Russ Cox00ffd592010-09-28 13:43:50 -04002074 if(f2 == T)
2075 return 0;
2076
Russ Cox42679742012-03-07 02:27:15 -05002077 expandmeth(f2);
Russ Cox7ae1fe42012-02-10 22:46:56 -05002078 f2 = lookdot1(n, s, f2, f2->xmethod, dostrcmp);
Russ Coxa3c68222010-10-03 11:50:44 -04002079 if(f2 == T)
2080 return 0;
Russ Cox00ffd592010-09-28 13:43:50 -04002081
2082 // disallow T.m if m requires *T receiver
2083 if(isptr[getthisx(f2->type)->type->type->etype]
2084 && !isptr[t->etype]
2085 && f2->embedded != 2
2086 && !isifacemethod(f2->type)) {
Luuk van Dijk50110c92011-10-31 18:09:40 +01002087 yyerror("invalid method expression %N (needs pointer receiver: (*%T).%hS)", n, t, f2->sym);
Russ Cox00ffd592010-09-28 13:43:50 -04002088 return 0;
2089 }
2090
2091 n->right = methodname(n->right, t);
2092 n->xoffset = f2->width;
2093 n->type = f2->type;
2094 n->op = ODOTMETH;
2095 return 1;
2096}
2097
Luuk van Dijk7df9ff52011-11-02 17:18:53 +01002098static Type*
2099derefall(Type* t)
2100{
2101 while(t && t->etype == tptr)
2102 t = t->type;
2103 return t;
2104}
2105
Russ Cox00ffd592010-09-28 13:43:50 -04002106static int
Russ Cox5d754bf2009-12-15 16:22:04 -08002107lookdot(Node *n, Type *t, int dostrcmp)
Russ Coxff3a73b2009-07-30 16:53:08 -07002108{
2109 Type *f1, *f2, *tt, *rcvr;
2110 Sym *s;
2111
2112 s = n->right->sym;
2113
Russ Coxb6487162009-08-07 12:50:26 -07002114 dowidth(t);
Russ Coxff3a73b2009-07-30 16:53:08 -07002115 f1 = T;
2116 if(t->etype == TSTRUCT || t->etype == TINTER)
Russ Cox7ae1fe42012-02-10 22:46:56 -05002117 f1 = lookdot1(n, s, t, t->type, dostrcmp);
Russ Coxff3a73b2009-07-30 16:53:08 -07002118
Russ Cox00ffd592010-09-28 13:43:50 -04002119 f2 = T;
2120 if(n->left->type == t || n->left->type->sym == S) {
Russ Cox42679742012-03-07 02:27:15 -05002121 f2 = methtype(t, 0);
Russ Cox00ffd592010-09-28 13:43:50 -04002122 if(f2 != T) {
2123 // Use f2->method, not f2->xmethod: adddot has
2124 // already inserted all the necessary embedded dots.
Russ Cox7ae1fe42012-02-10 22:46:56 -05002125 f2 = lookdot1(n, s, f2, f2->method, dostrcmp);
Russ Cox00ffd592010-09-28 13:43:50 -04002126 }
2127 }
Russ Coxff3a73b2009-07-30 16:53:08 -07002128
2129 if(f1 != T) {
2130 if(f2 != T)
Russ Coxbf0c1902012-01-23 15:10:53 -05002131 yyerror("%S is both field and method",
Russ Coxff3a73b2009-07-30 16:53:08 -07002132 n->right->sym);
Russ Cox4589c342010-02-18 18:31:13 -08002133 if(f1->width == BADWIDTH)
2134 fatal("lookdot badwidth %T %p", f1, f1);
Russ Coxff3a73b2009-07-30 16:53:08 -07002135 n->xoffset = f1->width;
2136 n->type = f1->type;
Russ Cox3d400622012-11-02 00:17:21 -04002137 n->paramfld = f1;
Russ Coxff3a73b2009-07-30 16:53:08 -07002138 if(t->etype == TINTER) {
2139 if(isptr[n->left->type->etype]) {
2140 n->left = nod(OIND, n->left, N); // implicitstar
Russ Cox7ae1fe42012-02-10 22:46:56 -05002141 n->left->implicit = 1;
Russ Cox9dc22b62009-08-03 11:58:52 -07002142 typecheck(&n->left, Erv);
Russ Coxff3a73b2009-07-30 16:53:08 -07002143 }
2144 n->op = ODOTINTER;
2145 }
2146 return 1;
2147 }
2148
2149 if(f2 != T) {
2150 tt = n->left->type;
Russ Coxb6487162009-08-07 12:50:26 -07002151 dowidth(tt);
Russ Coxff3a73b2009-07-30 16:53:08 -07002152 rcvr = getthisx(f2->type)->type->type;
Russ Cox00ffd592010-09-28 13:43:50 -04002153 if(!eqtype(rcvr, tt)) {
Russ Coxff3a73b2009-07-30 16:53:08 -07002154 if(rcvr->etype == tptr && eqtype(rcvr->type, tt)) {
Russ Cox9dc22b62009-08-03 11:58:52 -07002155 checklvalue(n->left, "call pointer method on");
Russ Coxff3a73b2009-07-30 16:53:08 -07002156 n->left = nod(OADDR, n->left, N);
Russ Cox2a701982010-10-07 04:42:44 -04002157 n->left->implicit = 1;
Russ Cox0d668252009-12-18 17:24:58 -08002158 typecheck(&n->left, Etype|Erv);
Russ Cox93fcb922014-10-20 22:04:12 -04002159 } else if(tt->etype == tptr && rcvr->etype != tptr && eqtype(tt->type, rcvr)) {
Russ Coxff3a73b2009-07-30 16:53:08 -07002160 n->left = nod(OIND, n->left, N);
Russ Cox2a701982010-10-07 04:42:44 -04002161 n->left->implicit = 1;
Russ Cox0d668252009-12-18 17:24:58 -08002162 typecheck(&n->left, Etype|Erv);
Russ Cox93fcb922014-10-20 22:04:12 -04002163 } else if(tt->etype == tptr && tt->type->etype == tptr && eqtype(derefall(tt), derefall(rcvr))) {
Luuk van Dijk7df9ff52011-11-02 17:18:53 +01002164 yyerror("calling method %N with receiver %lN requires explicit dereference", n->right, n->left);
2165 while(tt->etype == tptr) {
Russ Cox93fcb922014-10-20 22:04:12 -04002166 // Stop one level early for method with pointer receiver.
2167 if(rcvr->etype == tptr && tt->type->etype != tptr)
2168 break;
Luuk van Dijk7df9ff52011-11-02 17:18:53 +01002169 n->left = nod(OIND, n->left, N);
2170 n->left->implicit = 1;
2171 typecheck(&n->left, Etype|Erv);
2172 tt = tt->type;
2173 }
Russ Coxff3a73b2009-07-30 16:53:08 -07002174 } else {
Russ Coxff3a73b2009-07-30 16:53:08 -07002175 fatal("method mismatch: %T for %T", rcvr, tt);
2176 }
2177 }
2178 n->right = methodname(n->right, n->left->type);
2179 n->xoffset = f2->width;
2180 n->type = f2->type;
Russ Coxfc128402011-12-09 08:03:51 -05002181// print("lookdot found [%p] %T\n", f2->type, f2->type);
Russ Coxff3a73b2009-07-30 16:53:08 -07002182 n->op = ODOTMETH;
2183 return 1;
2184 }
2185
2186 return 0;
2187}
2188
Russ Coxff3a73b2009-07-30 16:53:08 -07002189static int
Russ Cox9dc22b62009-08-03 11:58:52 -07002190nokeys(NodeList *l)
Russ Coxff3a73b2009-07-30 16:53:08 -07002191{
Russ Cox9dc22b62009-08-03 11:58:52 -07002192 for(; l; l=l->next)
2193 if(l->n->op == OKEY)
2194 return 0;
2195 return 1;
2196}
Russ Coxff3a73b2009-07-30 16:53:08 -07002197
Jan Ziak1d2b71c2014-04-16 22:42:09 -04002198static int
2199hasddd(Type *t)
2200{
2201 Type *tl;
2202
2203 for(tl=t->type; tl; tl=tl->down) {
2204 if(tl->isddd)
2205 return 1;
2206 }
2207 return 0;
2208}
2209
2210static int
2211downcount(Type *t)
2212{
2213 Type *tl;
2214 int n;
2215
2216 n = 0;
2217 for(tl=t->type; tl; tl=tl->down) {
2218 n++;
2219 }
2220 return n;
2221}
2222
Russ Coxa95ee612009-09-21 15:45:55 -07002223/*
Russ Cox9dc22b62009-08-03 11:58:52 -07002224 * typecheck assignment: type list = expression list
2225 */
2226static void
Russ Cox50387922011-01-30 16:07:57 -05002227typecheckaste(int op, Node *call, int isddd, Type *tstruct, NodeList *nl, char *desc)
Russ Cox9dc22b62009-08-03 11:58:52 -07002228{
Russ Coxd8c19c82009-08-04 10:26:29 -07002229 Type *t, *tl, *tn;
Russ Cox9dc22b62009-08-03 11:58:52 -07002230 Node *n;
Russ Coxd8c19c82009-08-04 10:26:29 -07002231 int lno;
Russ Cox565b5dc2010-06-08 18:50:02 -07002232 char *why;
Jan Ziak1d2b71c2014-04-16 22:42:09 -04002233 int n1, n2;
Russ Cox9dc22b62009-08-03 11:58:52 -07002234
Russ Coxd8c19c82009-08-04 10:26:29 -07002235 lno = lineno;
2236
Russ Cox680ee6a2009-10-08 23:03:34 -07002237 if(tstruct->broke)
2238 goto out;
2239
Jan Ziak14837472014-03-14 16:42:42 +01002240 n = N;
Russ Coxd8c19c82009-08-04 10:26:29 -07002241 if(nl != nil && nl->next == nil && (n = nl->n)->type != T)
2242 if(n->type->etype == TSTRUCT && n->type->funarg) {
Jan Ziak1d2b71c2014-04-16 22:42:09 -04002243 if(!hasddd(tstruct)) {
2244 n1 = downcount(tstruct);
2245 n2 = downcount(n->type);
2246 if(n2 > n1)
2247 goto toomany;
2248 if(n2 < n1)
2249 goto notenough;
2250 }
2251
Russ Coxd8c19c82009-08-04 10:26:29 -07002252 tn = n->type->type;
2253 for(tl=tstruct->type; tl; tl=tl->down) {
Russ Cox68796b02010-02-01 00:25:59 -08002254 if(tl->isddd) {
Russ Coxa3c68222010-10-03 11:50:44 -04002255 for(; tn; tn=tn->down) {
Russ Cox50387922011-01-30 16:07:57 -05002256 if(assignop(tn->type, tl->type->type, &why) == 0) {
2257 if(call != N)
Daniel Morsing7e270cf2013-07-16 11:43:11 +02002258 yyerror("cannot use %T as type %T in argument to %N%s", tn->type, tl->type->type, call, why);
Russ Cox50387922011-01-30 16:07:57 -05002259 else
Daniel Morsing7e270cf2013-07-16 11:43:11 +02002260 yyerror("cannot use %T as type %T in %s%s", tn->type, tl->type->type, desc, why);
Russ Cox50387922011-01-30 16:07:57 -05002261 }
Russ Coxa3c68222010-10-03 11:50:44 -04002262 }
Russ Cox68796b02010-02-01 00:25:59 -08002263 goto out;
2264 }
Russ Cox75dd8fd2010-09-24 11:55:30 -04002265 if(tn == T)
2266 goto notenough;
Russ Cox50387922011-01-30 16:07:57 -05002267 if(assignop(tn->type, tl->type, &why) == 0) {
2268 if(call != N)
Luuk van Dijk50110c92011-10-31 18:09:40 +01002269 yyerror("cannot use %T as type %T in argument to %N%s", tn->type, tl->type, call, why);
Russ Cox50387922011-01-30 16:07:57 -05002270 else
2271 yyerror("cannot use %T as type %T in %s%s", tn->type, tl->type, desc, why);
2272 }
Russ Coxd8c19c82009-08-04 10:26:29 -07002273 tn = tn->down;
2274 }
2275 if(tn != T)
Russ Cox75dd8fd2010-09-24 11:55:30 -04002276 goto toomany;
Russ Coxd8c19c82009-08-04 10:26:29 -07002277 goto out;
Russ Cox9dc22b62009-08-03 11:58:52 -07002278 }
2279
Jan Ziak1d2b71c2014-04-16 22:42:09 -04002280 n1 = downcount(tstruct);
2281 n2 = count(nl);
2282 if(!hasddd(tstruct)) {
2283 if(n2 > n1)
2284 goto toomany;
2285 if(n2 < n1)
2286 goto notenough;
2287 }
2288 else {
2289 if(!isddd) {
2290 if(n2 < n1-1)
2291 goto notenough;
2292 } else {
2293 if(n2 > n1)
2294 goto toomany;
2295 if(n2 < n1)
2296 goto notenough;
2297 }
2298 }
2299
Russ Cox9dc22b62009-08-03 11:58:52 -07002300 for(tl=tstruct->type; tl; tl=tl->down) {
2301 t = tl->type;
Russ Cox68796b02010-02-01 00:25:59 -08002302 if(tl->isddd) {
Russ Cox75dd8fd2010-09-24 11:55:30 -04002303 if(isddd) {
2304 if(nl == nil)
2305 goto notenough;
2306 if(nl->next != nil)
2307 goto toomany;
Russ Coxa3c68222010-10-03 11:50:44 -04002308 n = nl->n;
2309 setlineno(n);
2310 if(n->type != T)
2311 nl->n = assignconv(n, t, desc);
Russ Cox68796b02010-02-01 00:25:59 -08002312 goto out;
Russ Cox75dd8fd2010-09-24 11:55:30 -04002313 }
Russ Coxd8c19c82009-08-04 10:26:29 -07002314 for(; nl; nl=nl->next) {
Russ Coxa3c68222010-10-03 11:50:44 -04002315 n = nl->n;
Russ Coxd8c19c82009-08-04 10:26:29 -07002316 setlineno(nl->n);
Russ Coxa3c68222010-10-03 11:50:44 -04002317 if(n->type != T)
2318 nl->n = assignconv(n, t->type, desc);
Russ Coxd8c19c82009-08-04 10:26:29 -07002319 }
2320 goto out;
Russ Cox9dc22b62009-08-03 11:58:52 -07002321 }
Russ Cox75dd8fd2010-09-24 11:55:30 -04002322 if(nl == nil)
2323 goto notenough;
Russ Cox9dc22b62009-08-03 11:58:52 -07002324 n = nl->n;
Russ Cox75dd8fd2010-09-24 11:55:30 -04002325 setlineno(n);
Russ Cox9dc22b62009-08-03 11:58:52 -07002326 if(n->type != T)
Russ Cox565b5dc2010-06-08 18:50:02 -07002327 nl->n = assignconv(n, t, desc);
Russ Cox9dc22b62009-08-03 11:58:52 -07002328 nl = nl->next;
2329 }
Russ Cox75dd8fd2010-09-24 11:55:30 -04002330 if(nl != nil)
2331 goto toomany;
Russ Cox50387922011-01-30 16:07:57 -05002332 if(isddd) {
2333 if(call != N)
Luuk van Dijk50110c92011-10-31 18:09:40 +01002334 yyerror("invalid use of ... in call to %N", call);
Russ Cox50387922011-01-30 16:07:57 -05002335 else
Luuk van Dijk50110c92011-10-31 18:09:40 +01002336 yyerror("invalid use of ... in %O", op);
Russ Cox50387922011-01-30 16:07:57 -05002337 }
Russ Coxd8c19c82009-08-04 10:26:29 -07002338
2339out:
2340 lineno = lno;
Russ Cox75dd8fd2010-09-24 11:55:30 -04002341 return;
2342
2343notenough:
Jan Ziak14837472014-03-14 16:42:42 +01002344 if(n == N || !n->diag) {
2345 if(call != N)
2346 yyerror("not enough arguments in call to %N", call);
2347 else
2348 yyerror("not enough arguments to %O", op);
2349 if(n != N)
2350 n->diag = 1;
2351 }
Russ Cox75dd8fd2010-09-24 11:55:30 -04002352 goto out;
2353
2354toomany:
Russ Cox50387922011-01-30 16:07:57 -05002355 if(call != N)
Luuk van Dijk50110c92011-10-31 18:09:40 +01002356 yyerror("too many arguments in call to %N", call);
Russ Cox50387922011-01-30 16:07:57 -05002357 else
Luuk van Dijk50110c92011-10-31 18:09:40 +01002358 yyerror("too many arguments to %O", op);
Russ Cox75dd8fd2010-09-24 11:55:30 -04002359 goto out;
Russ Cox9dc22b62009-08-03 11:58:52 -07002360}
2361
2362/*
Russ Cox9dc22b62009-08-03 11:58:52 -07002363 * type check composite
2364 */
2365
2366static void
Russ Cox8d44ede2015-01-22 12:10:59 -05002367fielddup(Node *n, Node **hash, ulong nhash)
Russ Cox9dc22b62009-08-03 11:58:52 -07002368{
2369 uint h;
2370 char *s;
2371 Node *a;
2372
2373 if(n->op != ONAME)
2374 fatal("fielddup: not ONAME");
2375 s = n->sym->name;
2376 h = stringhash(s)%nhash;
2377 for(a=hash[h]; a!=N; a=a->ntest) {
2378 if(strcmp(a->sym->name, s) == 0) {
2379 yyerror("duplicate field name in struct literal: %s", s);
2380 return;
2381 }
2382 }
2383 n->ntest = hash[h];
2384 hash[h] = n;
2385}
2386
2387static void
Russ Cox8d44ede2015-01-22 12:10:59 -05002388keydup(Node *n, Node **hash, ulong nhash)
Russ Cox9dc22b62009-08-03 11:58:52 -07002389{
2390 uint h;
2391 ulong b;
2392 double d;
2393 int i;
Jan Ziak3072df52014-04-04 16:46:23 +02002394 Node *a, *orign;
Russ Cox9dc22b62009-08-03 11:58:52 -07002395 Node cmp;
2396 char *s;
2397
Jan Ziak3072df52014-04-04 16:46:23 +02002398 orign = n;
2399 if(n->op == OCONVIFACE)
2400 n = n->left;
Russ Cox9dc22b62009-08-03 11:58:52 -07002401 evconst(n);
2402 if(n->op != OLITERAL)
2403 return; // we dont check variables
2404
2405 switch(n->val.ctype) {
2406 default: // unknown, bool, nil
2407 b = 23;
2408 break;
2409 case CTINT:
Russ Coxbe0ffbf2011-12-08 22:07:43 -05002410 case CTRUNE:
Russ Cox9dc22b62009-08-03 11:58:52 -07002411 b = mpgetfix(n->val.u.xval);
2412 break;
2413 case CTFLT:
2414 d = mpgetflt(n->val.u.fval);
2415 s = (char*)&d;
2416 b = 0;
2417 for(i=sizeof(d); i>0; i--)
2418 b = b*PRIME1 + *s++;
2419 break;
2420 case CTSTR:
2421 b = 0;
2422 s = n->val.u.sval->s;
2423 for(i=n->val.u.sval->len; i>0; i--)
2424 b = b*PRIME1 + *s++;
2425 break;
2426 }
2427
2428 h = b%nhash;
2429 memset(&cmp, 0, sizeof(cmp));
2430 for(a=hash[h]; a!=N; a=a->ntest) {
2431 cmp.op = OEQ;
2432 cmp.left = n;
Russ Coxec38c6f2014-05-15 15:34:37 -04002433 b = 0;
Jan Ziak3072df52014-04-04 16:46:23 +02002434 if(a->op == OCONVIFACE && orign->op == OCONVIFACE) {
Russ Coxec38c6f2014-05-15 15:34:37 -04002435 if(eqtype(a->left->type, n->type)) {
Jan Ziak3072df52014-04-04 16:46:23 +02002436 cmp.right = a->left;
2437 evconst(&cmp);
2438 b = cmp.val.u.bval;
2439 }
Russ Coxec38c6f2014-05-15 15:34:37 -04002440 } else if(eqtype(a->type, n->type)) {
Jan Ziak3072df52014-04-04 16:46:23 +02002441 cmp.right = a;
2442 evconst(&cmp);
2443 b = cmp.val.u.bval;
2444 }
Russ Cox9dc22b62009-08-03 11:58:52 -07002445 if(b) {
Russ Cox5ab9d2b2012-03-05 13:47:36 -05002446 yyerror("duplicate key %N in map literal", n);
Russ Cox9dc22b62009-08-03 11:58:52 -07002447 return;
2448 }
2449 }
Jan Ziak3072df52014-04-04 16:46:23 +02002450 orign->ntest = hash[h];
2451 hash[h] = orign;
Russ Cox9dc22b62009-08-03 11:58:52 -07002452}
2453
2454static void
Russ Cox8d44ede2015-01-22 12:10:59 -05002455indexdup(Node *n, Node **hash, ulong nhash)
Russ Cox9dc22b62009-08-03 11:58:52 -07002456{
2457 uint h;
2458 Node *a;
2459 ulong b, c;
2460
2461 if(n->op != OLITERAL)
2462 fatal("indexdup: not OLITERAL");
2463
2464 b = mpgetfix(n->val.u.xval);
2465 h = b%nhash;
2466 for(a=hash[h]; a!=N; a=a->ntest) {
2467 c = mpgetfix(a->val.u.xval);
2468 if(b == c) {
2469 yyerror("duplicate index in array literal: %ld", b);
2470 return;
2471 }
2472 }
2473 n->ntest = hash[h];
2474 hash[h] = n;
2475}
2476
Ken Thompsonb3dd22f2010-11-18 13:07:34 -08002477static int
Ken Thompson8cb8ba12010-11-20 15:58:28 -08002478prime(ulong h, ulong sr)
Ken Thompsonb3dd22f2010-11-18 13:07:34 -08002479{
Ken Thompson8cb8ba12010-11-20 15:58:28 -08002480 ulong n;
Ken Thompsonb3dd22f2010-11-18 13:07:34 -08002481
Ken Thompson8cb8ba12010-11-20 15:58:28 -08002482 for(n=3; n<=sr; n+=2)
Ken Thompsonb3dd22f2010-11-18 13:07:34 -08002483 if(h%n == 0)
2484 return 0;
2485 return 1;
2486}
2487
2488static ulong
2489inithash(Node *n, Node ***hash, Node **autohash, ulong nautohash)
2490{
Ken Thompson8cb8ba12010-11-20 15:58:28 -08002491 ulong h, sr;
Ken Thompsonb3dd22f2010-11-18 13:07:34 -08002492 NodeList *ll;
Ken Thompson8cb8ba12010-11-20 15:58:28 -08002493 int i;
Ken Thompsonb3dd22f2010-11-18 13:07:34 -08002494
Ken Thompson8cb8ba12010-11-20 15:58:28 -08002495 // count the number of entries
Ken Thompsonb3dd22f2010-11-18 13:07:34 -08002496 h = 0;
2497 for(ll=n->list; ll; ll=ll->next)
2498 h++;
Ken Thompson8cb8ba12010-11-20 15:58:28 -08002499
2500 // if the auto hash table is
2501 // large enough use it.
Ken Thompsonb3dd22f2010-11-18 13:07:34 -08002502 if(h <= nautohash) {
2503 *hash = autohash;
2504 memset(*hash, 0, nautohash * sizeof(**hash));
2505 return nautohash;
2506 }
Ken Thompson8cb8ba12010-11-20 15:58:28 -08002507
2508 // make hash size odd and 12% larger than entries
2509 h += h/8;
2510 h |= 1;
2511
2512 // calculate sqrt of h
2513 sr = h/2;
2514 for(i=0; i<5; i++)
2515 sr = (sr + h/sr)/2;
2516
2517 // check for primeality
2518 while(!prime(h, sr))
2519 h += 2;
2520
2521 // build and return a throw-away hash table
Ken Thompsonb3dd22f2010-11-18 13:07:34 -08002522 *hash = mal(h * sizeof(**hash));
2523 memset(*hash, 0, h * sizeof(**hash));
2524 return h;
2525}
2526
Russ Cox7dc9d8c2011-12-02 14:13:12 -05002527static int
2528iscomptype(Type *t)
2529{
2530 switch(t->etype) {
2531 case TARRAY:
2532 case TSTRUCT:
2533 case TMAP:
2534 return 1;
2535 case TPTR32:
2536 case TPTR64:
2537 switch(t->type->etype) {
2538 case TARRAY:
2539 case TSTRUCT:
2540 case TMAP:
2541 return 1;
2542 }
2543 break;
2544 }
2545 return 0;
2546}
2547
2548static void
2549pushtype(Node *n, Type *t)
2550{
2551 if(n == N || n->op != OCOMPLIT || !iscomptype(t))
2552 return;
2553
2554 if(n->right == N) {
2555 n->right = typenod(t);
Russ Cox5c524042012-02-09 00:26:08 -05002556 n->implicit = 1; // don't print
2557 n->right->implicit = 1; // * is okay
Russ Cox7dc9d8c2011-12-02 14:13:12 -05002558 }
2559 else if(debug['s']) {
2560 typecheck(&n->right, Etype);
2561 if(n->right->type != T && eqtype(n->right->type, t))
Shenghou Ma76b2f062014-12-30 19:48:26 -05002562 print("%L: redundant type: %T\n", n->lineno, t);
Russ Cox7dc9d8c2011-12-02 14:13:12 -05002563 }
2564}
2565
Russ Cox9dc22b62009-08-03 11:58:52 -07002566static void
2567typecheckcomplit(Node **np)
2568{
Rob Pike4dcb13b2013-04-29 22:44:40 -07002569 int bad, i, nerr;
Russ Cox8d44ede2015-01-22 12:10:59 -05002570 int64 length;
Rémy Oudomphengb0bb6f82013-03-04 16:42:03 +01002571 Node *l, *n, *norig, *r, **hash;
Russ Cox9dc22b62009-08-03 11:58:52 -07002572 NodeList *ll;
Russ Cox7dc9d8c2011-12-02 14:13:12 -05002573 Type *t, *f;
Daniel Morsing87c35d82012-10-07 16:47:53 +02002574 Sym *s, *s1;
Russ Cox75dd8fd2010-09-24 11:55:30 -04002575 int32 lno;
Ken Thompsonb3dd22f2010-11-18 13:07:34 -08002576 ulong nhash;
2577 Node *autohash[101];
Russ Cox9dc22b62009-08-03 11:58:52 -07002578
2579 n = *np;
Russ Cox75dd8fd2010-09-24 11:55:30 -04002580 lno = lineno;
Russ Cox9dc22b62009-08-03 11:58:52 -07002581
Russ Cox8ffc4ec2010-10-21 23:17:20 -04002582 if(n->right == N) {
2583 if(n->list != nil)
2584 setlineno(n->list->n);
2585 yyerror("missing type in composite literal");
2586 goto error;
2587 }
Rémy Oudomphengb0bb6f82013-03-04 16:42:03 +01002588
2589 // Save original node (including n->right)
2590 norig = nod(n->op, N, N);
2591 *norig = *n;
2592
Russ Cox75dd8fd2010-09-24 11:55:30 -04002593 setlineno(n->right);
Russ Coxbf899be2011-07-26 00:52:02 -04002594 l = typecheck(&n->right /* sic */, Etype|Ecomplit);
Russ Cox9dc22b62009-08-03 11:58:52 -07002595 if((t = l->type) == T)
2596 goto error;
2597 nerr = nerrors;
Russ Cox7dc9d8c2011-12-02 14:13:12 -05002598 n->type = t;
Rémy Oudomphengb0bb6f82013-03-04 16:42:03 +01002599
Russ Cox7dc9d8c2011-12-02 14:13:12 -05002600 if(isptr[t->etype]) {
Luuk van Dijk419c53a2012-02-06 12:19:59 +01002601 // For better or worse, we don't allow pointers as the composite literal type,
Russ Cox5c524042012-02-09 00:26:08 -05002602 // except when using the &T syntax, which sets implicit on the OIND.
2603 if(!n->right->implicit) {
Russ Cox7dc9d8c2011-12-02 14:13:12 -05002604 yyerror("invalid pointer type %T for composite literal (use &%T instead)", t, t->type);
2605 goto error;
Russ Cox8ffc4ec2010-10-21 23:17:20 -04002606 }
Russ Cox7dc9d8c2011-12-02 14:13:12 -05002607 // Also, the underlying type must be a struct, map, slice, or array.
2608 if(!iscomptype(t)) {
2609 yyerror("invalid pointer type %T for composite literal", t);
2610 goto error;
2611 }
Rémy Oudompheng9e66ee42013-02-26 00:43:31 +01002612 t = t->type;
Russ Cox8ffc4ec2010-10-21 23:17:20 -04002613 }
2614
Russ Cox9dc22b62009-08-03 11:58:52 -07002615 switch(t->etype) {
2616 default:
2617 yyerror("invalid type for composite literal: %T", t);
2618 n->type = T;
2619 break;
2620
2621 case TARRAY:
Ken Thompsonb3dd22f2010-11-18 13:07:34 -08002622 nhash = inithash(n, &hash, autohash, nelem(autohash));
2623
Russ Cox8d44ede2015-01-22 12:10:59 -05002624 length = 0;
Russ Cox9dc22b62009-08-03 11:58:52 -07002625 i = 0;
2626 for(ll=n->list; ll; ll=ll->next) {
2627 l = ll->n;
Russ Cox75dd8fd2010-09-24 11:55:30 -04002628 setlineno(l);
Russ Cox8ffc4ec2010-10-21 23:17:20 -04002629 if(l->op != OKEY) {
2630 l = nod(OKEY, nodintconst(i), l);
2631 l->left->type = types[TINT];
2632 l->left->typecheck = 1;
2633 ll->n = l;
2634 }
2635
2636 typecheck(&l->left, Erv);
2637 evconst(l->left);
2638 i = nonnegconst(l->left);
Jan Ziak2ca99502014-03-29 15:45:40 +01002639 if(i < 0 && !l->left->diag) {
Russ Cox8ffc4ec2010-10-21 23:17:20 -04002640 yyerror("array index must be non-negative integer constant");
Jan Ziak2ca99502014-03-29 15:45:40 +01002641 l->left->diag = 1;
Russ Cox8ffc4ec2010-10-21 23:17:20 -04002642 i = -(1<<30); // stay negative for a while
Russ Cox9dc22b62009-08-03 11:58:52 -07002643 }
2644 if(i >= 0)
Ken Thompsonb3dd22f2010-11-18 13:07:34 -08002645 indexdup(l->left, hash, nhash);
Russ Cox9dc22b62009-08-03 11:58:52 -07002646 i++;
Russ Cox8d44ede2015-01-22 12:10:59 -05002647 if(i > length) {
2648 length = i;
2649 if(t->bound >= 0 && length > t->bound) {
Russ Cox9dc22b62009-08-03 11:58:52 -07002650 setlineno(l);
Russ Cox8d44ede2015-01-22 12:10:59 -05002651 yyerror("array index %lld out of bounds [0:%lld]", length-1, t->bound);
Russ Cox9dc22b62009-08-03 11:58:52 -07002652 t->bound = -1; // no more errors
2653 }
2654 }
Russ Cox8ffc4ec2010-10-21 23:17:20 -04002655
Russ Cox7dc9d8c2011-12-02 14:13:12 -05002656 r = l->right;
2657 pushtype(r, t->type);
2658 typecheck(&r, Erv);
2659 defaultlit(&r, t->type);
2660 l->right = assignconv(r, t->type, "array element");
Russ Cox9dc22b62009-08-03 11:58:52 -07002661 }
2662 if(t->bound == -100)
Russ Cox8d44ede2015-01-22 12:10:59 -05002663 t->bound = length;
Russ Cox9dc22b62009-08-03 11:58:52 -07002664 if(t->bound < 0)
Russ Cox8d44ede2015-01-22 12:10:59 -05002665 n->right = nodintconst(length);
Russ Cox9dc22b62009-08-03 11:58:52 -07002666 n->op = OARRAYLIT;
2667 break;
2668
2669 case TMAP:
Ken Thompsonb3dd22f2010-11-18 13:07:34 -08002670 nhash = inithash(n, &hash, autohash, nelem(autohash));
2671
Russ Cox9dc22b62009-08-03 11:58:52 -07002672 for(ll=n->list; ll; ll=ll->next) {
2673 l = ll->n;
Russ Cox75dd8fd2010-09-24 11:55:30 -04002674 setlineno(l);
Russ Cox9dc22b62009-08-03 11:58:52 -07002675 if(l->op != OKEY) {
2676 typecheck(&ll->n, Erv);
2677 yyerror("missing key in map literal");
2678 continue;
2679 }
Russ Cox8ffc4ec2010-10-21 23:17:20 -04002680
Russ Cox9dc22b62009-08-03 11:58:52 -07002681 typecheck(&l->left, Erv);
Russ Cox9dc22b62009-08-03 11:58:52 -07002682 defaultlit(&l->left, t->down);
Russ Cox565b5dc2010-06-08 18:50:02 -07002683 l->left = assignconv(l->left, t->down, "map key");
Jeff R. Allen46e7cb52012-01-20 13:34:38 -05002684 if (l->left->op != OCONV)
2685 keydup(l->left, hash, nhash);
Russ Cox8ffc4ec2010-10-21 23:17:20 -04002686
Russ Cox7dc9d8c2011-12-02 14:13:12 -05002687 r = l->right;
2688 pushtype(r, t->type);
2689 typecheck(&r, Erv);
2690 defaultlit(&r, t->type);
2691 l->right = assignconv(r, t->type, "map value");
Russ Cox9dc22b62009-08-03 11:58:52 -07002692 }
2693 n->op = OMAPLIT;
2694 break;
2695
2696 case TSTRUCT:
2697 bad = 0;
2698 if(n->list != nil && nokeys(n->list)) {
2699 // simple list of variables
2700 f = t->type;
2701 for(ll=n->list; ll; ll=ll->next) {
Russ Cox75dd8fd2010-09-24 11:55:30 -04002702 setlineno(ll->n);
Russ Cox9dc22b62009-08-03 11:58:52 -07002703 typecheck(&ll->n, Erv);
2704 if(f == nil) {
2705 if(!bad++)
2706 yyerror("too many values in struct initializer");
2707 continue;
2708 }
Russ Coxa3382312009-11-15 12:57:09 -08002709 s = f->sym;
Russ Cox758f2bc2010-01-22 17:06:20 -08002710 if(s != nil && !exportname(s->name) && s->pkg != localpkg)
Russ Cox9475caf2010-04-11 14:52:06 -07002711 yyerror("implicit assignment of unexported field '%s' in %T literal", s->name, t);
Russ Cox7dc9d8c2011-12-02 14:13:12 -05002712 // No pushtype allowed here. Must name fields for that.
Russ Cox565b5dc2010-06-08 18:50:02 -07002713 ll->n = assignconv(ll->n, f->type, "field value");
Russ Cox9dc22b62009-08-03 11:58:52 -07002714 ll->n = nod(OKEY, newname(f->sym), ll->n);
Russ Cox335da672011-08-31 07:37:14 -04002715 ll->n->left->type = f;
Russ Cox9dc22b62009-08-03 11:58:52 -07002716 ll->n->left->typecheck = 1;
2717 f = f->down;
2718 }
Russ Coxef3e6812009-08-24 09:23:04 -07002719 if(f != nil)
2720 yyerror("too few values in struct initializer");
Russ Cox9dc22b62009-08-03 11:58:52 -07002721 } else {
Ken Thompsonb3dd22f2010-11-18 13:07:34 -08002722 nhash = inithash(n, &hash, autohash, nelem(autohash));
2723
Russ Cox9dc22b62009-08-03 11:58:52 -07002724 // keyed list
2725 for(ll=n->list; ll; ll=ll->next) {
2726 l = ll->n;
Russ Cox75dd8fd2010-09-24 11:55:30 -04002727 setlineno(l);
Russ Cox9dc22b62009-08-03 11:58:52 -07002728 if(l->op != OKEY) {
2729 if(!bad++)
2730 yyerror("mixture of field:value and value initializers");
2731 typecheck(&ll->n, Erv);
2732 continue;
2733 }
Russ Coxa3382312009-11-15 12:57:09 -08002734 s = l->left->sym;
2735 if(s == S) {
Luuk van Dijk50110c92011-10-31 18:09:40 +01002736 yyerror("invalid field name %N in struct initializer", l->left);
Russ Cox9dc22b62009-08-03 11:58:52 -07002737 typecheck(&l->right, Erv);
2738 continue;
2739 }
Luuk van Dijk40b2fe02011-12-05 14:40:19 -05002740
Russ Cox7b240e82010-07-26 14:21:39 -07002741 // Sym might have resolved to name in other top-level
2742 // package, because of import dot. Redirect to correct sym
2743 // before we do the lookup.
Daniel Morsing87c35d82012-10-07 16:47:53 +02002744 if(s->pkg != localpkg && exportname(s->name)) {
2745 s1 = lookup(s->name);
2746 if(s1->origpkg == s->pkg)
2747 s = s1;
2748 }
Russ Cox7ae1fe42012-02-10 22:46:56 -05002749 f = lookdot1(nil, s, t, t->type, 0);
Russ Coxa3382312009-11-15 12:57:09 -08002750 if(f == nil) {
Luuk van Dijk40b2fe02011-12-05 14:40:19 -05002751 yyerror("unknown %T field '%S' in struct literal", t, s);
Russ Cox9dc22b62009-08-03 11:58:52 -07002752 continue;
Russ Coxa3382312009-11-15 12:57:09 -08002753 }
Russ Cox335da672011-08-31 07:37:14 -04002754 l->left = newname(s);
2755 l->left->typecheck = 1;
2756 l->left->type = f;
Russ Coxa3382312009-11-15 12:57:09 -08002757 s = f->sym;
Ken Thompsonb3dd22f2010-11-18 13:07:34 -08002758 fielddup(newname(s), hash, nhash);
Russ Cox7dc9d8c2011-12-02 14:13:12 -05002759 r = l->right;
Russ Cox5cb1c822011-12-05 14:22:41 -05002760 // No pushtype allowed here. Tried and rejected.
Russ Cox7dc9d8c2011-12-02 14:13:12 -05002761 typecheck(&r, Erv);
2762 l->right = assignconv(r, f->type, "field value");
Russ Cox9dc22b62009-08-03 11:58:52 -07002763 }
2764 }
2765 n->op = OSTRUCTLIT;
2766 break;
2767 }
2768 if(nerr != nerrors)
2769 goto error;
Russ Cox7dc9d8c2011-12-02 14:13:12 -05002770
Rémy Oudomphengb0bb6f82013-03-04 16:42:03 +01002771 n->orig = norig;
Russ Cox7dc9d8c2011-12-02 14:13:12 -05002772 if(isptr[n->type->etype]) {
2773 n = nod(OPTRLIT, n, N);
2774 n->typecheck = 1;
2775 n->type = n->left->type;
2776 n->left->type = t;
Russ Cox5e985052011-12-07 15:48:55 -05002777 n->left->typecheck = 1;
Russ Cox7dc9d8c2011-12-02 14:13:12 -05002778 }
Russ Cox9dc22b62009-08-03 11:58:52 -07002779
Rémy Oudomphengb0bb6f82013-03-04 16:42:03 +01002780 n->orig = norig;
Russ Cox9dc22b62009-08-03 11:58:52 -07002781 *np = n;
Russ Cox75dd8fd2010-09-24 11:55:30 -04002782 lineno = lno;
Russ Cox9dc22b62009-08-03 11:58:52 -07002783 return;
2784
2785error:
2786 n->type = T;
2787 *np = n;
Russ Cox75dd8fd2010-09-24 11:55:30 -04002788 lineno = lno;
Russ Cox9dc22b62009-08-03 11:58:52 -07002789}
2790
2791/*
Russ Coxd8c19c82009-08-04 10:26:29 -07002792 * lvalue etc
2793 */
Russ Cox0bd41e22010-02-01 22:18:51 -08002794int
Russ Cox9dc22b62009-08-03 11:58:52 -07002795islvalue(Node *n)
2796{
2797 switch(n->op) {
2798 case OINDEX:
Russ Cox5e253642010-05-24 14:22:54 -07002799 if(isfixedarray(n->left->type))
2800 return islvalue(n->left);
Russ Coxe48c0fb2010-10-26 21:11:17 -07002801 if(n->left->type != T && n->left->type->etype == TSTRING)
2802 return 0;
Russ Cox5e253642010-05-24 14:22:54 -07002803 // fall through
Russ Cox9dc22b62009-08-03 11:58:52 -07002804 case OIND:
2805 case ODOTPTR:
Russ Coxd3c758d2013-03-20 17:11:09 -04002806 case OCLOSUREVAR:
Russ Coxe5ef6572014-12-29 11:47:04 -05002807 case OPARAM:
Russ Cox9dc22b62009-08-03 11:58:52 -07002808 return 1;
2809 case ODOT:
2810 return islvalue(n->left);
2811 case ONAME:
2812 if(n->class == PFUNC)
2813 return 0;
2814 return 1;
2815 }
2816 return 0;
2817}
2818
2819static void
2820checklvalue(Node *n, char *verb)
2821{
2822 if(!islvalue(n))
Luuk van Dijk50110c92011-10-31 18:09:40 +01002823 yyerror("cannot %s %N", verb, n);
Russ Cox9dc22b62009-08-03 11:58:52 -07002824}
2825
Dmitry Vyukovb581ca52015-01-26 11:26:55 +03002826void
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +03002827checkassign(Node *stmt, Node *n)
Russ Cox9dc22b62009-08-03 11:58:52 -07002828{
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +03002829 Node *r, *l;
2830
Dmitry Vyukoveaa87202015-01-29 18:33:19 +03002831 // Variables declared in ORANGE are assigned on every iteration.
2832 if(n->defn != stmt || stmt->op == ORANGE) {
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +03002833 r = outervalue(n);
2834 for(l = n; l != r; l = l->left) {
2835 l->assigned = 1;
2836 if(l->closure)
2837 l->closure->assigned = 1;
2838 }
2839 l->assigned = 1;
2840 if(l->closure)
2841 l->closure->assigned = 1;
2842 }
2843
Russ Cox9dc22b62009-08-03 11:58:52 -07002844 if(islvalue(n))
2845 return;
2846 if(n->op == OINDEXMAP) {
2847 n->etype = 1;
2848 return;
2849 }
Daniel Morsingf2e94b52014-01-03 21:03:20 +01002850
2851 // have already complained about n being undefined
2852 if(n->op == ONONAME)
2853 return;
2854
Luuk van Dijk50110c92011-10-31 18:09:40 +01002855 yyerror("cannot assign to %N", n);
Russ Cox9dc22b62009-08-03 11:58:52 -07002856}
2857
2858static void
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +03002859checkassignlist(Node *stmt, NodeList *l)
Russ Cox9dc22b62009-08-03 11:58:52 -07002860{
2861 for(; l; l=l->next)
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +03002862 checkassign(stmt, l->n);
Russ Coxff3a73b2009-07-30 16:53:08 -07002863}
Russ Coxd8c19c82009-08-04 10:26:29 -07002864
Russ Cox1552e622014-10-16 12:43:17 -04002865// Check whether l and r are the same side effect-free expression,
2866// so that it is safe to reuse one instead of computing both.
Josh Bleecher Snyderf03c9202015-01-07 17:44:49 -08002867int
Russ Cox1552e622014-10-16 12:43:17 -04002868samesafeexpr(Node *l, Node *r)
2869{
2870 if(l->op != r->op || !eqtype(l->type, r->type))
2871 return 0;
2872
2873 switch(l->op) {
2874 case ONAME:
2875 case OCLOSUREVAR:
2876 return l == r;
2877
2878 case ODOT:
2879 case ODOTPTR:
2880 return l->right != nil && r->right != nil && l->right->sym == r->right->sym && samesafeexpr(l->left, r->left);
2881
2882 case OIND:
2883 return samesafeexpr(l->left, r->left);
2884
2885 case OINDEX:
2886 return samesafeexpr(l->left, r->left) && samesafeexpr(l->right, r->right);
2887 }
2888
2889 return 0;
2890}
2891
Russ Coxd8c19c82009-08-04 10:26:29 -07002892/*
Russ Cox54b40372009-08-05 00:42:44 -07002893 * type check assignment.
2894 * if this assignment is the definition of a var on the left side,
2895 * fill in the var's type.
Russ Coxd8c19c82009-08-04 10:26:29 -07002896 */
Russ Cox54b40372009-08-05 00:42:44 -07002897
2898static void
2899typecheckas(Node *n)
2900{
2901 // delicate little dance.
2902 // the definition of n may refer to this assignment
2903 // as its definition, in which case it will call typecheckas.
2904 // in that case, do not call typecheck back, or it will cycle.
2905 // if the variable has a type (ntype) then typechecking
2906 // will not look at defn, so it is okay (and desirable,
2907 // so that the conversion below happens).
Russ Cox76da2782010-06-12 11:17:24 -07002908 n->left = resolve(n->left);
Russ Cox54b40372009-08-05 00:42:44 -07002909 if(n->left->defn != n || n->left->ntype)
Russ Cox5438be42009-09-08 23:16:19 -07002910 typecheck(&n->left, Erv | Easgn);
Russ Cox54b40372009-08-05 00:42:44 -07002911
Russ Cox54b40372009-08-05 00:42:44 -07002912 typecheck(&n->right, Erv);
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +03002913 checkassign(n, n->left);
Russ Cox9da66662009-12-03 22:09:58 -08002914 if(n->right && n->right->type != T) {
2915 if(n->left->type != T)
Russ Cox565b5dc2010-06-08 18:50:02 -07002916 n->right = assignconv(n->right, n->left->type, "assignment");
Russ Cox9da66662009-12-03 22:09:58 -08002917 }
Russ Cox54b40372009-08-05 00:42:44 -07002918 if(n->left->defn == n && n->left->ntype == N) {
2919 defaultlit(&n->right, T);
2920 n->left->type = n->right->type;
2921 }
2922
2923 // second half of dance.
2924 // now that right is done, typecheck the left
2925 // just to get it over with. see dance above.
2926 n->typecheck = 1;
2927 if(n->left->typecheck == 0)
Russ Cox5438be42009-09-08 23:16:19 -07002928 typecheck(&n->left, Erv | Easgn);
Russ Cox1552e622014-10-16 12:43:17 -04002929
2930 // Recognize slices being updated in place, for better code generation later.
2931 // Don't rewrite if using race detector, to avoid needing to teach race detector
2932 // about this optimization.
2933 if(n->left && n->left->op != OINDEXMAP && n->right && !flag_race) {
2934 switch(n->right->op) {
2935 case OSLICE:
2936 case OSLICE3:
2937 case OSLICESTR:
2938 // For x = x[0:y], x can be updated in place, without touching pointer.
Russ Coxb035e972014-10-30 10:16:03 -04002939 // TODO(rsc): Reenable once it is actually updated in place without touching the pointer.
2940 if(0 && samesafeexpr(n->left, n->right->left) && (n->right->right->left == N || iszero(n->right->right->left)))
Russ Cox1552e622014-10-16 12:43:17 -04002941 n->right->reslice = 1;
2942 break;
2943
2944 case OAPPEND:
2945 // For x = append(x, ...), x can be updated in place when there is capacity,
2946 // without touching the pointer; otherwise the emitted code to growslice
2947 // can take care of updating the pointer, and only in that case.
Russ Coxb035e972014-10-30 10:16:03 -04002948 // TODO(rsc): Reenable once the emitted code does update the pointer.
2949 if(0 && n->right->list != nil && samesafeexpr(n->left, n->right->list->n))
Russ Cox1552e622014-10-16 12:43:17 -04002950 n->right->reslice = 1;
2951 break;
2952 }
2953 }
Russ Cox54b40372009-08-05 00:42:44 -07002954}
2955
Russ Coxd8c19c82009-08-04 10:26:29 -07002956static void
Russ Cox565b5dc2010-06-08 18:50:02 -07002957checkassignto(Type *src, Node *dst)
2958{
2959 char *why;
2960
2961 if(assignop(src, dst->type, &why) == 0) {
Luuk van Dijk50110c92011-10-31 18:09:40 +01002962 yyerror("cannot assign %T to %lN in multiple assignment%s", src, dst, why);
Russ Cox565b5dc2010-06-08 18:50:02 -07002963 return;
2964 }
Russ Cox565b5dc2010-06-08 18:50:02 -07002965}
2966
2967static void
Russ Coxd8c19c82009-08-04 10:26:29 -07002968typecheckas2(Node *n)
2969{
Russ Cox565b5dc2010-06-08 18:50:02 -07002970 int cl, cr;
Russ Coxd8c19c82009-08-04 10:26:29 -07002971 NodeList *ll, *lr;
Russ Cox5fc37712011-11-11 16:48:25 -05002972 Node *l, *r;
Russ Coxd8c19c82009-08-04 10:26:29 -07002973 Iter s;
2974 Type *t;
2975
Russ Cox54b40372009-08-05 00:42:44 -07002976 for(ll=n->list; ll; ll=ll->next) {
2977 // delicate little dance.
Russ Cox76da2782010-06-12 11:17:24 -07002978 ll->n = resolve(ll->n);
Russ Cox54b40372009-08-05 00:42:44 -07002979 if(ll->n->defn != n || ll->n->ntype)
Russ Cox5438be42009-09-08 23:16:19 -07002980 typecheck(&ll->n, Erv | Easgn);
Russ Cox54b40372009-08-05 00:42:44 -07002981 }
Russ Coxd8c19c82009-08-04 10:26:29 -07002982 cl = count(n->list);
2983 cr = count(n->rlist);
Russ Cox54b40372009-08-05 00:42:44 -07002984 if(cl > 1 && cr == 1)
2985 typecheck(&n->rlist->n, Erv | Efnstruct);
2986 else
2987 typechecklist(n->rlist, Erv);
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +03002988 checkassignlist(n, n->list);
Russ Coxd8c19c82009-08-04 10:26:29 -07002989
2990 if(cl == cr) {
2991 // easy
Russ Cox54b40372009-08-05 00:42:44 -07002992 for(ll=n->list, lr=n->rlist; ll; ll=ll->next, lr=lr->next) {
Russ Coxd8c19c82009-08-04 10:26:29 -07002993 if(ll->n->type != T && lr->n->type != T)
Russ Cox565b5dc2010-06-08 18:50:02 -07002994 lr->n = assignconv(lr->n, ll->n->type, "assignment");
Russ Cox54b40372009-08-05 00:42:44 -07002995 if(ll->n->defn == n && ll->n->ntype == N) {
2996 defaultlit(&lr->n, T);
2997 ll->n->type = lr->n->type;
2998 }
2999 }
3000 goto out;
Russ Coxd8c19c82009-08-04 10:26:29 -07003001 }
3002
3003
3004 l = n->list->n;
3005 r = n->rlist->n;
3006
Russ Coxd8c19c82009-08-04 10:26:29 -07003007 // x,y,z = f()
3008 if(cr == 1) {
3009 if(r->type == T)
Russ Cox54b40372009-08-05 00:42:44 -07003010 goto out;
Russ Coxd8c19c82009-08-04 10:26:29 -07003011 switch(r->op) {
3012 case OCALLMETH:
3013 case OCALLINTER:
3014 case OCALLFUNC:
3015 if(r->type->etype != TSTRUCT || r->type->funarg == 0)
3016 break;
3017 cr = structcount(r->type);
3018 if(cr != cl)
3019 goto mismatch;
3020 n->op = OAS2FUNC;
3021 t = structfirst(&s, &r->type);
3022 for(ll=n->list; ll; ll=ll->next) {
Dominik Honnef062ae452014-01-21 22:44:54 -05003023 if(t->type != T && ll->n->type != T)
Russ Cox565b5dc2010-06-08 18:50:02 -07003024 checkassignto(t->type, ll->n);
Russ Cox54b40372009-08-05 00:42:44 -07003025 if(ll->n->defn == n && ll->n->ntype == N)
3026 ll->n->type = t->type;
Russ Coxd8c19c82009-08-04 10:26:29 -07003027 t = structnext(&s);
3028 }
Russ Cox54b40372009-08-05 00:42:44 -07003029 goto out;
Russ Coxd8c19c82009-08-04 10:26:29 -07003030 }
3031 }
3032
3033 // x, ok = y
3034 if(cl == 2 && cr == 1) {
3035 if(r->type == T)
Russ Cox54b40372009-08-05 00:42:44 -07003036 goto out;
Russ Coxd8c19c82009-08-04 10:26:29 -07003037 switch(r->op) {
3038 case OINDEXMAP:
3039 n->op = OAS2MAPR;
3040 goto common;
3041 case ORECV:
Russ Cox8bf34e32011-03-11 14:47:26 -05003042 n->op = OAS2RECV;
Russ Cox8bf34e32011-03-11 14:47:26 -05003043 goto common;
Russ Coxd8c19c82009-08-04 10:26:29 -07003044 case ODOTTYPE:
3045 n->op = OAS2DOTTYPE;
Russ Cox565b5dc2010-06-08 18:50:02 -07003046 r->op = ODOTTYPE2;
Russ Coxd8c19c82009-08-04 10:26:29 -07003047 common:
Russ Cox565b5dc2010-06-08 18:50:02 -07003048 if(l->type != T)
3049 checkassignto(r->type, l);
Russ Cox54b40372009-08-05 00:42:44 -07003050 if(l->defn == n)
3051 l->type = r->type;
Russ Coxd8c19c82009-08-04 10:26:29 -07003052 l = n->list->next->n;
Chris Manghane897f7a32014-08-11 16:11:55 -07003053 if(l->type != T && l->type->etype != TBOOL)
Russ Cox565b5dc2010-06-08 18:50:02 -07003054 checkassignto(types[TBOOL], l);
Russ Cox54b40372009-08-05 00:42:44 -07003055 if(l->defn == n && l->ntype == N)
3056 l->type = types[TBOOL];
3057 goto out;
Russ Coxd8c19c82009-08-04 10:26:29 -07003058 }
3059 }
3060
3061mismatch:
3062 yyerror("assignment count mismatch: %d = %d", cl, cr);
Russ Cox54b40372009-08-05 00:42:44 -07003063
3064out:
3065 // second half of dance
3066 n->typecheck = 1;
3067 for(ll=n->list; ll; ll=ll->next)
3068 if(ll->n->typecheck == 0)
Russ Cox1c9e4b32009-09-15 14:11:43 -07003069 typecheck(&ll->n, Erv | Easgn);
Russ Coxd8c19c82009-08-04 10:26:29 -07003070}
Russ Coxb6487162009-08-07 12:50:26 -07003071
3072/*
3073 * type check function definition
3074 */
3075static void
3076typecheckfunc(Node *n)
3077{
3078 Type *t, *rcvr;
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +03003079 NodeList *l;
Russ Coxb6487162009-08-07 12:50:26 -07003080
Russ Cox5438be42009-09-08 23:16:19 -07003081 typecheck(&n->nname, Erv | Easgn);
Russ Coxb6487162009-08-07 12:50:26 -07003082 if((t = n->nname->type) == T)
3083 return;
3084 n->type = t;
Russ Coxfc128402011-12-09 08:03:51 -05003085 t->nname = n->nname;
Russ Coxb6487162009-08-07 12:50:26 -07003086 rcvr = getthisx(t)->type;
Russ Coxaa6e81dd2009-09-09 16:59:41 -07003087 if(rcvr != nil && n->shortname != N && !isblank(n->shortname))
Russ Cox3d400622012-11-02 00:17:21 -04003088 addmethod(n->shortname->sym, t, 1, n->nname->nointerface);
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +03003089
3090 for(l=n->dcl; l; l=l->next)
3091 if(l->n->op == ONAME && (l->n->class == PPARAM || l->n->class == PPARAMOUT))
3092 l->n->decldepth = 1;
Russ Coxb6487162009-08-07 12:50:26 -07003093}
Russ Cox39101612010-02-25 15:11:07 -08003094
3095static void
3096stringtoarraylit(Node **np)
3097{
3098 int32 i;
3099 NodeList *l;
3100 Strlit *s;
3101 char *p, *ep;
3102 Rune r;
3103 Node *nn, *n;
3104
3105 n = *np;
3106 if(n->left->op != OLITERAL || n->left->val.ctype != CTSTR)
3107 fatal("stringtoarraylit %N", n);
3108
3109 s = n->left->val.u.sval;
3110 l = nil;
3111 p = s->s;
3112 ep = s->s + s->len;
3113 i = 0;
3114 if(n->type->type->etype == TUINT8) {
3115 // raw []byte
3116 while(p < ep)
3117 l = list(l, nod(OKEY, nodintconst(i++), nodintconst((uchar)*p++)));
3118 } else {
Russ Cox6ed3fa62011-10-25 22:19:39 -07003119 // utf-8 []rune
Russ Cox39101612010-02-25 15:11:07 -08003120 while(p < ep) {
3121 p += chartorune(&r, p);
3122 l = list(l, nod(OKEY, nodintconst(i++), nodintconst(r)));
3123 }
3124 }
3125 nn = nod(OCOMPLIT, N, typenod(n->type));
3126 nn->list = l;
3127 typecheck(&nn, Erv);
3128 *np = nn;
3129}
Lorenzo Stoakesb6f06322011-04-28 00:13:49 -04003130
Luuk van Dijkab8ed7f2011-06-03 17:44:02 +02003131
3132static int ntypecheckdeftype;
3133static NodeList *methodqueue;
3134
3135static void
3136domethod(Node *n)
3137{
3138 Node *nt;
Russ Cox8e515482011-11-28 16:40:39 -05003139 Type *t;
Luuk van Dijkab8ed7f2011-06-03 17:44:02 +02003140
3141 nt = n->type->nname;
3142 typecheck(&nt, Etype);
3143 if(nt->type == T) {
3144 // type check failed; leave empty func
3145 n->type->etype = TFUNC;
3146 n->type->nod = N;
3147 return;
3148 }
Russ Cox8e515482011-11-28 16:40:39 -05003149
3150 // If we have
3151 // type I interface {
3152 // M(_ int)
3153 // }
3154 // then even though I.M looks like it doesn't care about the
3155 // value of its argument, a specific implementation of I may
3156 // care. The _ would suppress the assignment to that argument
3157 // while generating a call, so remove it.
3158 for(t=getinargx(nt->type)->type; t; t=t->down) {
3159 if(t->sym != nil && strcmp(t->sym->name, "_") == 0)
3160 t->sym = nil;
3161 }
3162
Luuk van Dijkab8ed7f2011-06-03 17:44:02 +02003163 *n->type = *nt->type;
3164 n->type->nod = N;
3165 checkwidth(n->type);
3166}
3167
Russ Cox6363fc52012-06-07 03:06:40 -04003168static NodeList *mapqueue;
Luuk van Dijkab8ed7f2011-06-03 17:44:02 +02003169
3170void
3171copytype(Node *n, Type *t)
3172{
Russ Cox6363fc52012-06-07 03:06:40 -04003173 int maplineno, embedlineno, lno;
3174 NodeList *l;
3175
3176 if(t->etype == TFORW) {
3177 // This type isn't computed yet; when it is, update n.
3178 t->copyto = list(t->copyto, n);
3179 return;
3180 }
3181
3182 maplineno = n->type->maplineno;
3183 embedlineno = n->type->embedlineno;
3184
3185 l = n->type->copyto;
Luuk van Dijkab8ed7f2011-06-03 17:44:02 +02003186 *n->type = *t;
3187
3188 t = n->type;
3189 t->sym = n->sym;
3190 t->local = n->local;
3191 t->vargen = n->vargen;
3192 t->siggen = 0;
3193 t->method = nil;
Maxim Pimenovffa6b382011-11-28 11:52:16 -05003194 t->xmethod = nil;
Luuk van Dijkab8ed7f2011-06-03 17:44:02 +02003195 t->nod = N;
3196 t->printed = 0;
3197 t->deferwidth = 0;
Russ Cox6363fc52012-06-07 03:06:40 -04003198 t->copyto = nil;
3199
3200 // Update nodes waiting on this type.
3201 for(; l; l=l->next)
3202 copytype(l->n, t);
3203
3204 // Double-check use of type as embedded type.
3205 lno = lineno;
3206 if(embedlineno) {
3207 lineno = embedlineno;
3208 if(isptr[t->etype])
3209 yyerror("embedded type cannot be a pointer");
3210 }
3211 lineno = lno;
3212
3213 // Queue check for map until all the types are done settling.
3214 if(maplineno) {
3215 t->maplineno = maplineno;
3216 mapqueue = list(mapqueue, n);
3217 }
Luuk van Dijkab8ed7f2011-06-03 17:44:02 +02003218}
3219
3220static void
3221typecheckdeftype(Node *n)
3222{
Russ Cox6363fc52012-06-07 03:06:40 -04003223 int lno;
Luuk van Dijkab8ed7f2011-06-03 17:44:02 +02003224 Type *t;
3225 NodeList *l;
3226
3227 ntypecheckdeftype++;
3228 lno = lineno;
3229 setlineno(n);
3230 n->type->sym = n->sym;
3231 n->typecheck = 1;
3232 typecheck(&n->ntype, Etype);
3233 if((t = n->ntype->type) == T) {
3234 n->diag = 1;
Daniel Morsing85ce3c72012-08-31 13:02:29 -04003235 n->type = T;
Luuk van Dijkab8ed7f2011-06-03 17:44:02 +02003236 goto ret;
3237 }
3238 if(n->type == T) {
3239 n->diag = 1;
3240 goto ret;
3241 }
3242
Luuk van Dijkab8ed7f2011-06-03 17:44:02 +02003243 // copy new type and clear fields
3244 // that don't come along.
3245 // anything zeroed here must be zeroed in
3246 // typedcl2 too.
3247 copytype(n, t);
3248
Luuk van Dijkab8ed7f2011-06-03 17:44:02 +02003249ret:
3250 lineno = lno;
3251
3252 // if there are no type definitions going on, it's safe to
3253 // try to resolve the method types for the interfaces
3254 // we just read.
3255 if(ntypecheckdeftype == 1) {
3256 while((l = methodqueue) != nil) {
3257 methodqueue = nil;
3258 for(; l; l=l->next)
3259 domethod(l->n);
3260 }
Russ Cox6363fc52012-06-07 03:06:40 -04003261 for(l=mapqueue; l; l=l->next) {
3262 lineno = l->n->type->maplineno;
3263 maptype(l->n->type, types[TBOOL]);
3264 }
3265 lineno = lno;
Luuk van Dijkab8ed7f2011-06-03 17:44:02 +02003266 }
3267 ntypecheckdeftype--;
3268}
3269
3270void
3271queuemethod(Node *n)
3272{
3273 if(ntypecheckdeftype == 0) {
3274 domethod(n);
3275 return;
3276 }
3277 methodqueue = list(methodqueue, n);
3278}
3279
3280Node*
3281typecheckdef(Node *n)
3282{
Russ Cox933d7122013-09-09 13:03:59 -04003283 int lno, nerrors0;
Luuk van Dijkab8ed7f2011-06-03 17:44:02 +02003284 Node *e;
3285 Type *t;
3286 NodeList *l;
3287
3288 lno = lineno;
3289 setlineno(n);
3290
3291 if(n->op == ONONAME) {
3292 if(!n->diag) {
3293 n->diag = 1;
3294 if(n->lineno != 0)
3295 lineno = n->lineno;
3296 yyerror("undefined: %S", n->sym);
3297 }
3298 return n;
3299 }
3300
3301 if(n->walkdef == 1)
3302 return n;
3303
3304 l = mal(sizeof *l);
3305 l->n = n;
3306 l->next = typecheckdefstack;
3307 typecheckdefstack = l;
3308
3309 if(n->walkdef == 2) {
3310 flusherrors();
3311 print("typecheckdef loop:");
3312 for(l=typecheckdefstack; l; l=l->next)
3313 print(" %S", l->n->sym);
3314 print("\n");
3315 fatal("typecheckdef loop");
3316 }
3317 n->walkdef = 2;
3318
3319 if(n->type != T || n->sym == S) // builtin or no name
3320 goto ret;
3321
3322 switch(n->op) {
3323 default:
3324 fatal("typecheckdef %O", n->op);
3325
Russ Cox7f4c5ea2011-06-17 15:25:05 -04003326 case OGOTO:
3327 case OLABEL:
3328 // not really syms
3329 break;
3330
Luuk van Dijkab8ed7f2011-06-03 17:44:02 +02003331 case OLITERAL:
3332 if(n->ntype != N) {
3333 typecheck(&n->ntype, Etype);
3334 n->type = n->ntype->type;
3335 n->ntype = N;
3336 if(n->type == T) {
3337 n->diag = 1;
3338 goto ret;
3339 }
3340 }
3341 e = n->defn;
3342 n->defn = N;
3343 if(e == N) {
3344 lineno = n->lineno;
3345 dump("typecheckdef nil defn", n);
3346 yyerror("xxx");
3347 }
3348 typecheck(&e, Erv | Eiota);
Luuk van Dijkab8ed7f2011-06-03 17:44:02 +02003349 if(isconst(e, CTNIL)) {
3350 yyerror("const initializer cannot be nil");
3351 goto ret;
3352 }
Russ Cox89313062013-02-01 23:10:02 -05003353 if(e->type != T && e->op != OLITERAL || !isgoconst(e)) {
Jan Ziak833dae62014-03-24 20:36:42 +01003354 if(!e->diag) {
3355 yyerror("const initializer %N is not a constant", e);
3356 e->diag = 1;
3357 }
Russ Cox89313062013-02-01 23:10:02 -05003358 goto ret;
3359 }
Luuk van Dijkab8ed7f2011-06-03 17:44:02 +02003360 t = n->type;
3361 if(t != T) {
3362 if(!okforconst[t->etype]) {
3363 yyerror("invalid constant type %T", t);
3364 goto ret;
3365 }
3366 if(!isideal(e->type) && !eqtype(t, e->type)) {
Luuk van Dijk50110c92011-10-31 18:09:40 +01003367 yyerror("cannot use %lN as type %T in const initializer", e, t);
Luuk van Dijkab8ed7f2011-06-03 17:44:02 +02003368 goto ret;
3369 }
3370 convlit(&e, t);
3371 }
3372 n->val = e->val;
3373 n->type = e->type;
3374 break;
3375
3376 case ONAME:
3377 if(n->ntype != N) {
3378 typecheck(&n->ntype, Etype);
3379 n->type = n->ntype->type;
Luuk van Dijk847b61b2011-08-24 19:07:08 +02003380
Luuk van Dijkab8ed7f2011-06-03 17:44:02 +02003381 if(n->type == T) {
3382 n->diag = 1;
3383 goto ret;
3384 }
3385 }
3386 if(n->type != T)
3387 break;
3388 if(n->defn == N) {
3389 if(n->etype != 0) // like OPRINTN
3390 break;
Russ Cox7f4c5ea2011-06-17 15:25:05 -04003391 if(nsavederrors+nerrors > 0) {
Luuk van Dijkab8ed7f2011-06-03 17:44:02 +02003392 // Can have undefined variables in x := foo
3393 // that make x have an n->ndefn == nil.
3394 // If there are other errors anyway, don't
3395 // bother adding to the noise.
3396 break;
3397 }
3398 fatal("var without type, init: %S", n->sym);
3399 }
3400 if(n->defn->op == ONAME) {
3401 typecheck(&n->defn, Erv);
3402 n->type = n->defn->type;
3403 break;
3404 }
3405 typecheck(&n->defn, Etop); // fills in n->type
3406 break;
3407
3408 case OTYPE:
3409 if(curfn)
3410 defercheckwidth();
3411 n->walkdef = 1;
3412 n->type = typ(TFORW);
3413 n->type->sym = n->sym;
Russ Cox933d7122013-09-09 13:03:59 -04003414 nerrors0 = nerrors;
Luuk van Dijkab8ed7f2011-06-03 17:44:02 +02003415 typecheckdeftype(n);
David du Colombierd0591d52014-02-07 17:05:16 +01003416 if(n->type->etype == TFORW && nerrors > nerrors0) {
Russ Cox933d7122013-09-09 13:03:59 -04003417 // Something went wrong during type-checking,
3418 // but it was reported. Silence future errors.
3419 n->type->broke = 1;
3420 }
Luuk van Dijkab8ed7f2011-06-03 17:44:02 +02003421 if(curfn)
3422 resumecheckwidth();
3423 break;
3424
3425 case OPACK:
3426 // nothing to see here
3427 break;
3428 }
3429
3430ret:
Russ Coxe29d3df2012-02-22 00:29:37 -05003431 if(n->op != OLITERAL && n->type != T && isideal(n->type))
3432 fatal("got %T for %N", n->type, n);
Luuk van Dijkab8ed7f2011-06-03 17:44:02 +02003433 if(typecheckdefstack->n != n)
3434 fatal("typecheckdefstack mismatch");
3435 l = typecheckdefstack;
3436 typecheckdefstack = l->next;
3437
3438 lineno = lno;
3439 n->walkdef = 1;
3440 return n;
3441}
Russ Coxf02067a2013-02-03 14:28:44 -05003442
3443static int
3444checkmake(Type *t, char *arg, Node *n)
3445{
3446 if(n->op == OLITERAL) {
Shenghou Mae33e47e2014-02-23 16:31:48 -05003447 switch(n->val.ctype) {
3448 case CTINT:
3449 case CTRUNE:
3450 case CTFLT:
3451 case CTCPLX:
3452 n->val = toint(n->val);
3453 if(mpcmpfixc(n->val.u.xval, 0) < 0) {
3454 yyerror("negative %s argument in make(%T)", arg, t);
3455 return -1;
3456 }
3457 if(mpcmpfixfix(n->val.u.xval, maxintval[TINT]) > 0) {
3458 yyerror("%s argument too large in make(%T)", arg, t);
3459 return -1;
3460 }
3461
3462 // Delay defaultlit until after we've checked range, to avoid
3463 // a redundant "constant NNN overflows int" error.
3464 defaultlit(&n, types[TINT]);
3465 return 0;
3466 default:
3467 break;
Russ Coxf02067a2013-02-03 14:28:44 -05003468 }
Russ Coxf02067a2013-02-03 14:28:44 -05003469 }
Russ Coxf02067a2013-02-03 14:28:44 -05003470
Shenghou Mae33e47e2014-02-23 16:31:48 -05003471 if(!isint[n->type->etype] && n->type->etype != TIDEAL) {
Russ Coxf02067a2013-02-03 14:28:44 -05003472 yyerror("non-integer %s argument in make(%T) - %T", arg, t, n->type);
3473 return -1;
3474 }
Shenghou Mae33e47e2014-02-23 16:31:48 -05003475
3476 // Defaultlit still necessary for non-constant: n might be 1<<k.
3477 defaultlit(&n, types[TINT]);
3478
Russ Coxf02067a2013-02-03 14:28:44 -05003479 return 0;
3480}
Russ Coxecab4082013-03-04 17:02:04 -05003481
3482static void markbreaklist(NodeList*, Node*);
3483
3484static void
3485markbreak(Node *n, Node *implicit)
3486{
3487 Label *lab;
3488
3489 if(n == N)
3490 return;
3491
3492 switch(n->op) {
3493 case OBREAK:
3494 if(n->left == N) {
3495 if(implicit)
3496 implicit->hasbreak = 1;
3497 } else {
3498 lab = n->left->sym->label;
3499 if(lab != L)
3500 lab->def->hasbreak = 1;
3501 }
3502 break;
3503
3504 case OFOR:
3505 case OSWITCH:
3506 case OTYPESW:
3507 case OSELECT:
3508 case ORANGE:
3509 implicit = n;
3510 // fall through
3511
3512 default:
3513 markbreak(n->left, implicit);
3514 markbreak(n->right, implicit);
3515 markbreak(n->ntest, implicit);
3516 markbreak(n->nincr, implicit);
3517 markbreaklist(n->ninit, implicit);
3518 markbreaklist(n->nbody, implicit);
3519 markbreaklist(n->nelse, implicit);
3520 markbreaklist(n->list, implicit);
3521 markbreaklist(n->rlist, implicit);
3522 break;
3523 }
3524}
3525
3526static void
3527markbreaklist(NodeList *l, Node *implicit)
3528{
3529 Node *n;
3530 Label *lab;
3531
3532 for(; l; l=l->next) {
3533 n = l->n;
3534 if(n->op == OLABEL && l->next && n->defn == l->next->n) {
3535 switch(n->defn->op) {
3536 case OFOR:
3537 case OSWITCH:
3538 case OTYPESW:
3539 case OSELECT:
3540 case ORANGE:
3541 lab = mal(sizeof *lab);
3542 lab->def = n->defn;
3543 n->left->sym->label = lab;
3544 markbreak(n->defn, n->defn);
3545 n->left->sym->label = L;
3546 l = l->next;
3547 continue;
3548 }
3549 }
3550 markbreak(n, implicit);
3551 }
3552}
3553
3554static int
3555isterminating(NodeList *l, int top)
3556{
3557 int def;
3558 Node *n;
3559
3560 if(l == nil)
3561 return 0;
3562 if(top) {
3563 while(l->next && l->n->op != OLABEL)
3564 l = l->next;
3565 markbreaklist(l, nil);
3566 }
3567 while(l->next)
3568 l = l->next;
3569 n = l->n;
3570
3571 if(n == N)
3572 return 0;
3573
3574 switch(n->op) {
3575 // NOTE: OLABEL is treated as a separate statement,
3576 // not a separate prefix, so skipping to the last statement
3577 // in the block handles the labeled statement case by
3578 // skipping over the label. No case OLABEL here.
3579
3580 case OBLOCK:
3581 return isterminating(n->list, 0);
3582
3583 case OGOTO:
3584 case ORETURN:
Russ Cox1f51d272013-06-11 09:41:49 -04003585 case ORETJMP:
Russ Coxecab4082013-03-04 17:02:04 -05003586 case OPANIC:
3587 case OXFALL:
3588 return 1;
3589
3590 case OFOR:
3591 if(n->ntest != N)
3592 return 0;
3593 if(n->hasbreak)
3594 return 0;
3595 return 1;
3596
3597 case OIF:
3598 return isterminating(n->nbody, 0) && isterminating(n->nelse, 0);
3599
3600 case OSWITCH:
3601 case OTYPESW:
3602 case OSELECT:
3603 if(n->hasbreak)
3604 return 0;
3605 def = 0;
3606 for(l=n->list; l; l=l->next) {
3607 if(!isterminating(l->n->nbody, 0))
3608 return 0;
3609 if(l->n->list == nil) // default
3610 def = 1;
3611 }
3612 if(n->op != OSELECT && !def)
3613 return 0;
3614 return 1;
3615 }
3616
3617 return 0;
3618}
3619
3620void
3621checkreturn(Node *fn)
3622{
3623 if(fn->type->outtuple && fn->nbody != nil)
3624 if(!isterminating(fn->nbody, 1))
3625 yyerrorl(fn->endlineno, "missing return at end of function");
3626}