1
0
mirror of https://github.com/golang/go synced 2024-11-21 20:54:45 -07:00

gc: various bugs

Fixes #1016.
Fixes #1152.
Fixes #1153.

R=ken2
CC=golang-dev
https://golang.org/cl/2344042
This commit is contained in:
Russ Cox 2010-10-03 11:50:44 -04:00
parent f481afae53
commit a3c682267f
6 changed files with 59 additions and 12 deletions

View File

@ -403,7 +403,6 @@ enum
ORETURN, ORETURN,
OSELECT, OSELECT,
OSWITCH, OSWITCH,
OTYPECASE,
OTYPESW, // l = r.(type) OTYPESW, // l = r.(type)
// types // types

View File

@ -673,11 +673,13 @@ select_stmt:
LSELECT LSELECT
{ {
markdcl(); markdcl();
typesw = nod(OXXX, typesw, N);
} }
switch_body switch_body
{ {
$$ = nod(OSELECT, N, N); $$ = nod(OSELECT, N, N);
$$->list = $3; $$->list = $3;
typesw = typesw->left;
popdcl(); popdcl();
} }

View File

@ -106,6 +106,11 @@ exprfmt(Fmt *f, Node *n, int prec)
case OOROR: case OOROR:
nprec = 1; nprec = 1;
break; break;
case OTYPE:
if(n->sym != S)
nprec = 7;
break;
} }
if(prec > nprec) if(prec > nprec)

View File

@ -1186,11 +1186,6 @@ reswitch:
typecheckrange(n); typecheckrange(n);
goto ret; goto ret;
case OTYPECASE:
ok |= Etop | Erv;
typecheck(&n->left, Erv);
goto ret;
case OTYPESW: case OTYPESW:
yyerror("use of .(type) outside type switch"); yyerror("use of .(type) outside type switch");
goto error; goto error;
@ -1415,6 +1410,8 @@ looktypedot(Node *n, Type *t, int dostrcmp)
expandmeth(f2->sym, f2); expandmeth(f2->sym, f2);
f2 = lookdot1(s, f2, f2->xmethod, dostrcmp); f2 = lookdot1(s, f2, f2->xmethod, dostrcmp);
if(f2 == T)
return 0;
// disallow T.m if m requires *T receiver // disallow T.m if m requires *T receiver
if(isptr[getthisx(f2->type)->type->type->etype] if(isptr[getthisx(f2->type)->type->type->etype]
@ -1531,13 +1528,16 @@ typecheckaste(int op, int isddd, Type *tstruct, NodeList *nl, char *desc)
tn = n->type->type; tn = n->type->type;
for(tl=tstruct->type; tl; tl=tl->down) { for(tl=tstruct->type; tl; tl=tl->down) {
if(tl->isddd) { if(tl->isddd) {
for(; tn; tn=tn->down) for(; tn; tn=tn->down) {
exportassignok(tn->type, desc);
if(assignop(tn->type, tl->type->type, &why) == 0) if(assignop(tn->type, tl->type->type, &why) == 0)
yyerror("cannot use %T as type %T in %s%s", tn->type, tl->type->type, desc, why); yyerror("cannot use %T as type %T in %s%s", tn->type, tl->type->type, desc, why);
}
goto out; goto out;
} }
if(tn == T) if(tn == T)
goto notenough; goto notenough;
exportassignok(tn->type, desc);
if(assignop(tn->type, tl->type, &why) == 0) if(assignop(tn->type, tl->type, &why) == 0)
yyerror("cannot use %T as type %T in %s%s", tn->type, tl->type, desc, why); yyerror("cannot use %T as type %T in %s%s", tn->type, tl->type, desc, why);
tn = tn->down; tn = tn->down;
@ -1560,15 +1560,17 @@ typecheckaste(int op, int isddd, Type *tstruct, NodeList *nl, char *desc)
goto notenough; goto notenough;
if(nl->next != nil) if(nl->next != nil)
goto toomany; goto toomany;
if(assignop(nl->n->type, t, &why) == 0) n = nl->n;
yyerror("ddd cannot use %+N as type %T in %s%s", nl->n, t, desc, why); setlineno(n);
if(n->type != T)
nl->n = assignconv(n, t, desc);
goto out; goto out;
} }
for(; nl; nl=nl->next) { for(; nl; nl=nl->next) {
n = nl->n;
setlineno(nl->n); setlineno(nl->n);
defaultlit(&nl->n, t->type); if(n->type != T)
if(assignop(nl->n->type, t->type, &why) == 0) nl->n = assignconv(n, t->type, desc);
yyerror("cannot use %+N as type %T in %s%s", nl->n, t->type, desc, why);
} }
goto out; goto out;
} }

19
test/fixedbugs/bug309.go Normal file
View File

@ -0,0 +1,19 @@
// $G $D/$F.go
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// issue 1016
package main
func foo(t interface{}, c chan int) {
switch v := t.(type) {
case int:
select {
case <-c:
// bug was: internal compiler error: var without type, init: v
}
}
}

20
test/fixedbugs/bug310.go Normal file
View File

@ -0,0 +1,20 @@
// errchk $G $D/$F.go
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package p
import (
"bytes"
"fmt"
)
type t int
func main() {
_ = t.bar // ERROR "no method"
var b bytes.Buffer
fmt.Print(b) // ERROR "implicit assignment"
}