diff options
Diffstat (limited to 'src/cmd/gc/subr.c')
| -rw-r--r-- | src/cmd/gc/subr.c | 41 | 
1 files changed, 33 insertions, 8 deletions
| diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c index 142e5ba41..2098794a7 100644 --- a/src/cmd/gc/subr.c +++ b/src/cmd/gc/subr.c @@ -135,6 +135,7 @@ yyerror(char *fmt, ...)  	int i;  	static int lastsyntax;  	va_list arg; +	char buf[512], *p;  	if(strncmp(fmt, "syntax error", 12) == 0) {  		nsyntaxerrors++; @@ -147,6 +148,16 @@ yyerror(char *fmt, ...)  			return;  		lastsyntax = lexlineno; +		if(strstr(fmt, "{ or {")) { +			// The grammar has { and LBRACE but both show up as {. +			// Rewrite syntax error referring to "{ or {" to say just "{". +			strecpy(buf, buf+sizeof buf, fmt); +			p = strstr(buf, "{ or {"); +			if(p) +				memmove(p+1, p+6, strlen(p+6)+1); +			fmt = buf; +		} +		  		// look for parse state-specific errors in list (see go.errors).  		for(i=0; i<nelem(yymsg); i++) {  			if(yymsg[i].yystate == yystate && yymsg[i].yychar == yychar) { @@ -834,7 +845,6 @@ goopnames[] =  	[OCALL]	= "function call",  	[OCAP]		= "cap",  	[OCASE]		= "case", -	[OCLOSED]	= "closed",  	[OCLOSE]	= "close",  	[OCOMPLEX]	= "complex",  	[OCOM]		= "^", @@ -1144,7 +1154,7 @@ Tpretty(Fmt *fp, Type *t)  	&& t->sym != S  	&& !(fp->flags&FmtLong)) {  		s = t->sym; -		if(t == types[t->etype]) +		if(t == types[t->etype] && t->etype != TUNSAFEPTR)  			return fmtprint(fp, "%s", s->name);  		if(exporting) {  			if(fp->flags & FmtShort) @@ -1304,6 +1314,11 @@ Tpretty(Fmt *fp, Type *t)  		if(t->sym)  			return fmtprint(fp, "undefined %S", t->sym);  		return fmtprint(fp, "undefined"); +	 +	case TUNSAFEPTR: +		if(exporting) +			return fmtprint(fp, "\"unsafe\".Pointer"); +		return fmtprint(fp, "unsafe.Pointer");  	}  	// Don't know how to handle - fall back to detailed prints. @@ -1346,6 +1361,9 @@ Tconv(Fmt *fp)  		}  	} +	if(sharp || exporting) +		fatal("missing %E case during export", t->etype); +  	et = t->etype;  	fmtprint(fp, "%E ", et);  	if(t->sym != S) @@ -1663,6 +1681,9 @@ isselect(Node *n)  	s = pkglookup("selectrecv", runtimepkg);  	if(s == n->sym)  		return 1; +	s = pkglookup("selectrecv2", runtimepkg); +	if(s == n->sym) +		return 1;  	s = pkglookup("selectdefault", runtimepkg);  	if(s == n->sym)  		return 1; @@ -1864,7 +1885,7 @@ assignop(Type *src, Type *dst, char **why)  	if(why != nil)  		*why = ""; -	if(safemode && (isptrto(src, TANY) || isptrto(dst, TANY))) { +	if(safemode && src != T && src->etype == TUNSAFEPTR) {  		yyerror("cannot use unsafe.Pointer");  		errorexit();  	} @@ -1879,8 +1900,9 @@ assignop(Type *src, Type *dst, char **why)  		return OCONVNOP;  	// 2. src and dst have identical underlying types -	// and either src or dst is not a named type. -	if(eqtype(src->orig, dst->orig) && (src->sym == S || dst->sym == S)) +	// and either src or dst is not a named type or +	// both are interface types. +	if(eqtype(src->orig, dst->orig) && (src->sym == S || dst->sym == S || src->etype == TINTER))  		return OCONVNOP;  	// 3. dst is an interface type and src implements dst. @@ -2028,11 +2050,11 @@ convertop(Type *src, Type *dst, char **why)  	}  	// 8. src is a pointer or uintptr and dst is unsafe.Pointer. -	if((isptr[src->etype] || src->etype == TUINTPTR) && isptrto(dst, TANY)) +	if((isptr[src->etype] || src->etype == TUINTPTR) && dst->etype == TUNSAFEPTR)  		return OCONVNOP;  	// 9. src is unsafe.Pointer and dst is a pointer or uintptr. -	if(isptrto(src, TANY) && (isptr[dst->etype] || dst->etype == TUINTPTR)) +	if(src->etype == TUNSAFEPTR && (isptr[dst->etype] || dst->etype == TUINTPTR))  		return OCONVNOP;  	return 0; @@ -2043,13 +2065,16 @@ Node*  assignconv(Node *n, Type *t, char *context)  {  	int op; -	Node *r; +	Node *r, *old;  	char *why;  	if(n == N || n->type == T)  		return n; +	old = n; +	old->diag++;  // silence errors about n; we'll issue one below  	defaultlit(&n, t); +	old->diag--;  	if(t->etype == TBLANK)  		return n; | 
