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,
OSELECT,
OSWITCH,
OTYPECASE,
OTYPESW, // l = r.(type)
// types

View file

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

View file

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

View file

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