1
0
mirror of https://github.com/golang/go synced 2024-11-21 13:34:39 -07:00

more 6g reorg; checkpoint.

typecheck.c is now responsible for all type checking
except for assignment and function argument "..."

R=ken
OCL=32661
CL=32667
This commit is contained in:
Russ Cox 2009-08-03 11:58:52 -07:00
parent 178089056e
commit 9dc22b6d6f
25 changed files with 1178 additions and 1416 deletions

View File

@ -907,6 +907,8 @@ nodarg(Type *t, int fp)
n->class = PPARAM;
break;
}
n->typecheck = 1;
return n;
}

View File

@ -200,8 +200,6 @@ bad:
defaultlit(&n, T);
*np = n;
}
yyerror("cannot convert %T constant to %T", n->type, t);
n->diag = 1;
return;
}
@ -336,6 +334,9 @@ evconst(Node *n)
switch(n->op) {
case OMAKE:
case OMAKEMAP:
case OMAKESLICE:
case OMAKECHAN:
return;
}
@ -557,7 +558,7 @@ evconst(Node *n)
if(cmpslit(nl, nr) > 0)
goto settrue;
goto setfalse;
case TUP(OADD, CTSTR):
case TUP(OADDSTR, CTSTR):
len = v.u.sval->len + nr->val.u.sval->len;
str = mal(sizeof(*str) + len);
str->len = len;
@ -605,6 +606,7 @@ unary:
case TUP(OCONV, CTFLT):
case TUP(OCONV, CTSTR):
case TUP(OCONV, CTNIL):
case TUP(OARRAYBYTESTR, CTNIL):
convlit1(&nl, n->type, 1);
break;

View File

@ -672,9 +672,9 @@ funclit1(Node *ntype, NodeList *body)
for(l=func->cvars; l; l=l->next) {
a = l->n;
d = oldname(a->sym);
addrescapes(d);
args = list(args, nod(OADDR, d, N));
}
typechecklist(args, Erv);
n = nod(OCALL, clos, N);
n->list = args;
@ -1642,7 +1642,7 @@ embedded(Sym *s)
NodeList*
variter(NodeList *vl, Node *nt, NodeList *el)
{
int doexpr;
int doexpr, lno;
Node *v, *e, *a;
Type *tv;
NodeList *r;
@ -1663,23 +1663,37 @@ variter(NodeList *vl, Node *nt, NodeList *el)
break;
}
e = el->n;
el = el->next;
} else
e = N;
v = vl->n;
tv = t;
if(t == T) {
if(e) {
lno = lineno;
lineno = v->lineno;
typecheck(&e, Erv);
defaultlit(&e, T);
tv = e->type;
defaultlit(&e, t);
if(t)
e = typecheckconv(nil, e, t, 0);
if(tv == nil)
tv = e->type;
if(tv && tv->etype == TNIL) {
yyerror("cannot initialize %#N to untyped nil", v);
tv = nil;
}
lineno = lno;
}
a = N;
if(e != N || funcdepth > 0)
if((e != N && tv != T) || funcdepth > 0)
a = nod(OAS, v, e);
dodclvar(v, tv, &r);
if(a != N)
r = list(r, a);
if(el) {
el->n = e;
el = el->next;
}
}
if(el != nil)
yyerror("extra expr in var dcl");

View File

@ -328,36 +328,41 @@ enum
OLITERAL,
// exprs
OADD, OSUB, OOR, OXOR,
OADD, OSUB, OOR, OXOR, OADDSTR,
OADDR,
OANDAND,
OAPPENDSTR,
OARRAY,
OARRAYBYTESTR, OARRAYRUNESTR,
OAS, OAS2, OASOP,
OBAD,
OCALL, OCALLFUNC, OCALLMETH, OCALLINTER,
OCAP,
OCLOSE,
OCLOSED,
OCOMPOS, OCOMPSLICE, OCOMPMAP,
OCONV, OCONVNOP, OCONVRUNE, OCONVSTRB, OCONVSTRI, OCONVA2S,
OCMPIFACE, OCMPSTR,
OCOMPLIT, OMAPLIT, OSTRUCTLIT, OARRAYLIT,
OCOMPSLICE, OCOMPMAP,
OCONV, OCONVNOP, OCONVA2S, OCONVIFACE, OCONVSLICE,
ODCL, ODCLFUNC, ODCLFIELD, ODCLARG,
ODOT, ODOTPTR, ODOTMETH, ODOTINTER,
ODOTTYPE,
OEQ, ONE, OLT, OLE, OGE, OGT,
OFUNC,
OIND,
OINDEX, OINDEXSTR, OINDEXMAP, OINDEXARR,
OINDEX, OINDEXSTR, OINDEXMAP,
OKEY, OPARAM,
OLEN,
OMAKE,
OMAKE, OMAKECHAN, OMAKEMAP, OMAKESLICE,
OMUL, ODIV, OMOD, OLSH, ORSH, OAND, OANDNOT,
ONEW,
ONOT, OCOM, OPLUS, OMINUS,
OOROR,
OPANIC, OPANICN, OPRINT, OPRINTN,
OSEND,
OSLICE, OSLICESTR, OSLICEARR,
OSEND, OSENDNB,
OSLICE, OSLICEARR, OSLICESTR,
ORECV,
ORUNESTR,
// stmts
OBLOCK,
@ -470,10 +475,9 @@ enum
enum
{
Etop = 1<<1, // evaluated at statement level
Elv = 1<<2, // evaluated in lvalue context
Erv = 1<<3, // evaluated in rvalue context
Etype = 1<<4,
Ecall = 1<<5,
Erv = 1<<2, // evaluated in value context
Etype = 1<<3,
Ecall = 1<<4,
};
#define BITS 5
@ -658,6 +662,8 @@ EXTERN ushort blockgen; // max block number
EXTERN ushort block; // current block number
EXTERN int hasdefer; // flag that curfn has defer statetment
EXTERN Node* curfn;
EXTERN int maxround;
EXTERN int widthptr;
@ -986,14 +992,12 @@ NodeList* ascompatet(int, NodeList*, Type**, int, NodeList**);
NodeList* ascompatte(int, Type**, NodeList*, int, NodeList**);
int ascompat(Type*, Type*);
Node* newcompat(Node*);
Node* makecompat(Node*);
Node* stringop(Node*, NodeList**);
Type* fixmap(Type*);
Node* mapop(Node*, NodeList**);
Type* fixchan(Type*);
Node* chanop(Node*, NodeList**);
Node* arrayop(Node*);
Node* ifacecvt(Type*, Node*, int);
Node* ifacecvt(Type*, Node*, int, NodeList**);
Node* ifaceop(Node*);
int ifaceas(Type*, Type*, int);
int ifaceas1(Type*, Type*, int);
@ -1011,11 +1015,11 @@ Node* arraylit(Node*, Node*, NodeList**);
Node* maplit(Node*, Node*, NodeList**);
Node* selectas(Node*, Node*, NodeList**);
Node* old2new(Node*, Type*, NodeList**);
void addrescapes(Node*);
void heapmoves(void);
void walkdeflist(NodeList*);
void walkdef(Node*);
void typechecklist(NodeList*, int);
Node* typecheckconv(Node*, Node*, Type*, int);
Node* typecheck(Node**, int);
/*

View File

@ -123,7 +123,8 @@ file:
{
if(debug['f'])
frame(1);
fninit($4);
if(nerrors == 0)
fninit($4);
if(nsyntaxerrors == 0)
testdclstack();
}
@ -882,7 +883,7 @@ pexpr:
| convtype lbrace braced_keyval_list '}'
{
// composite expression
$$ = nod(OCOMPOS, N, $1);
$$ = nod(OCOMPLIT, N, $1);
$$->list = $3;
// If the opening brace was an LBODY,
@ -894,7 +895,7 @@ pexpr:
| pexpr '{' braced_keyval_list '}'
{
// composite expression
$$ = nod(OCOMPOS, N, $1);
$$ = nod(OCOMPLIT, N, $1);
$$->list = $3;
}
| fnliteral

View File

@ -208,11 +208,12 @@ exprfmt(Fmt *f, Node *n, int prec)
exprfmt(f, n->left, 0);
break;
case OCOMPOS:
case OCOMPLIT:
fmtprint(f, "<compos>");
break;
case ODOT:
case ODOTPTR:
case ODOTINTER:
case ODOTMETH:
exprfmt(f, n->left, 7);

View File

@ -2,6 +2,10 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
/*
* static initialization
*/
#include "go.h"
static struct

View File

@ -1209,6 +1209,14 @@ Nconv(Fmt *fp)
goto out;
}
if(fp->flags & FmtSign) {
if(n->type == T || n->type->etype == TNIL)
fmtprint(fp, "nil");
else
fmtprint(fp, "%#N (type %T)", n, n->type);
goto out;
}
if(fp->flags & FmtSharp) {
exprfmt(fp, n, 0);
goto out;
@ -1593,22 +1601,7 @@ eqtype(Type *t1, Type *t2)
int
cvttype(Type *dst, Type *src)
{
Sym *ds, *ss;
int ret;
if(eqtype1(dst, src, 0, 0))
return 1;
// Can convert if assignment compatible when
// top-level names are ignored.
ds = dst->sym;
dst->sym = nil;
ss = src->sym;
src->sym = nil;
ret = ascompat(dst, src);
dst->sym = ds;
src->sym = ss;
return ret == 1;
return eqtype1(dst, src, 0, 0);
}
int
@ -1746,6 +1739,7 @@ noconv(Type *t1, Type *t2)
void
argtype(Node *on, Type *t)
{
dowidth(t);
if(!subtype(&on->type, t, 0))
fatal("argtype: failed %N %T\n", on, t);
}
@ -2274,7 +2268,7 @@ saferef(Node *n, NodeList **init)
r = nod(OXXX, N, N);
*r = *n;
r->left = l;
typecheck(&r, Elv);
typecheck(&r, Erv);
walkexpr(&r, init);
return r;
@ -2288,7 +2282,7 @@ saferef(Node *n, NodeList **init)
walkexpr(&a, init);
*init = list(*init, a);
r = nod(OIND, l, N);
typecheck(&r, Elv);
typecheck(&r, Erv);
walkexpr(&r, init);
return r;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -15,10 +15,10 @@ var (
func main() {
cr = c; // ok
cs = c; // ok
c = cr; // ERROR "illegal types|incompatible"
c = cs; // ERROR "illegal types|incompatible"
cr = cs; // ERROR "illegal types|incompatible"
cs = cr; // ERROR "illegal types|incompatible"
c = cr; // ERROR "illegal types|incompatible|cannot"
c = cs; // ERROR "illegal types|incompatible|cannot"
cr = cs; // ERROR "illegal types|incompatible|cannot"
cs = cr; // ERROR "illegal types|incompatible|cannot"
c <- 0; // ok
ok := c <- 0; // ok

View File

@ -65,15 +65,15 @@ var (
func f(int);
func main() {
f(Int8); // ERROR "convert|wrong type"
f(Minus1); // ERROR "convert|wrong type"
f(Uint8); // ERROR "convert|wrong type"
f(Int8); // ERROR "convert|wrong type|cannot"
f(Minus1); // ERROR "convert|wrong type|cannot"
f(Uint8); // ERROR "convert|wrong type|cannot"
f(Const); // OK
f(Float32); // ERROR "convert|wrong type"
f(Float); // ERROR "convert|wrong type"
f(Float32); // ERROR "convert|wrong type|cannot"
f(Float); // ERROR "convert|wrong type|cannot"
f(ConstFloat); // ERROR "truncate"
f(ConstFloat - 0.5); // OK
f(Big); // ERROR "convert|wrong type"
f(String); // ERROR "convert|wrong type"
f(Bool); // ERROR "convert|wrong type"
f(Big); // ERROR "convert|wrong type|cannot"
f(String); // ERROR "convert|wrong type|cannot"
f(Bool); // ERROR "convert|wrong type|cannot"
}

View File

@ -21,5 +21,5 @@ var g = []int(nil)
type H *[4]int
type J []int
var h H
var j1 J = h // ERROR "compat|illegal"
var j1 J = h // ERROR "compat|illegal|cannot|cannot"
var j2 = J(h)

View File

@ -19,11 +19,11 @@ var x7 = float(1e1000); // ERROR "overflow"
// implicit conversions merit scrutiny
var s string;
var bad1 string = 1; // ERROR "conver|incompatible"
var bad2 = s + 1; // ERROR "conver|incompatible"
var bad3 = s + 'a'; // ERROR "conver|incompatible"
var bad4 = "a" + 1; // ERROR "literals|incompatible|convert"
var bad5 = "a" + 'a'; // ERROR "literals|incompatible|convert"
var bad1 string = 1; // ERROR "conver|incompatible|invalid|cannot"
var bad2 = s + 1; // ERROR "conver|incompatible|invalid"
var bad3 = s + 'a'; // ERROR "conver|incompatible|invalid"
var bad4 = "a" + 1; // ERROR "literals|incompatible|convert|invalid"
var bad5 = "a" + 'a'; // ERROR "literals|incompatible|convert|invalid"
var bad6 int = 1.5; // ERROR "convert|truncate"
var bad7 int = 1e100; // ERROR "overflow"

View File

@ -6,12 +6,12 @@
package main
var a = []int { "a" }; // ERROR "conver|incompatible"
var a = []int { "a" }; // ERROR "conver|incompatible|cannot"
var b = int { 1 }; // ERROR "compos"
func f() int
func main() {
if f < 1 { } // ERROR "conver|incompatible"
if f < 1 { } // ERROR "conver|incompatible|invalid"
}

View File

@ -9,7 +9,7 @@ package main
func putint(digits *string) {
var i byte;
i = (*digits)[7]; // compiles
i = digits[7]; // ERROR "illegal|is not"
i = digits[7]; // ERROR "illegal|is not|invalid"
}
func main() {

View File

@ -7,5 +7,5 @@
package main
func main() {
var s string = nil; // ERROR "illegal|invalid"
var s string = nil; // ERROR "illegal|invalid|cannot"
}

View File

@ -38,9 +38,9 @@ func main() {
assert(i != f3div2, "i != f3div2"); // ERROR "truncate"
const g float64 = 1.0;
i = g; // ERROR "convert|incompatible"
i = g; // ERROR "convert|incompatible|cannot"
const h float64 = 3.14;
i = h; // ERROR "convert|incompatible"
i = h; // ERROR "convert|incompatible|cannot"
i = int(h); // ERROR "truncate"
}

View File

@ -10,16 +10,6 @@ type T func()
type I interface {
f, g ();
h T; // should only allow FunctionType here
h T; // ERROR "syntax"
}
type S struct {
}
func (s *S) f() {}
func (s *S) g() {}
func (s *S) h() {} // here we can't write (s *S) T either
func main() {
var i I = new(S);
}

View File

@ -8,5 +8,5 @@ package main
func main() {
const a uint64 = 10;
var b int64 = a; // ERROR "convert"
var b int64 = a; // ERROR "convert|cannot"
}

View File

@ -10,5 +10,5 @@ func main() {
type Slice []byte;
a := [...]byte{ 0 };
b := Slice(&a); // This should be OK.
c := Slice(a); // ERROR "invalid|illegal"
c := Slice(a); // ERROR "invalid|illegal|cannot"
}

View File

@ -5,9 +5,10 @@
// license that can be found in the LICENSE file.
package main
var v1 = ([10]int)(nil) // ERROR "illegal|nil|invalid"
var v2 [10]int = nil // ERROR "illegal|nil|incompatible"
var v3 [10]int
var v1 = ([10]int)(nil); // ERROR "illegal|nil|invalid"
var v2 [10]int = nil; // ERROR "illegal|nil|incompatible"
var v3 [10]int;
var v4 = nil; // ERROR "nil"
func main() {
v3 = nil; // ERROR "illegal|nil|incompatible"
}

View File

@ -9,6 +9,6 @@ package main
var notmain func()
func main() {
var x = &main; // ERROR "address of function|invalid"
main = notmain; // ERROR "assign to function|invalid"
var x = &main; // ERROR "address of|invalid"
main = notmain; // ERROR "assign to|invalid"
}

View File

@ -132,13 +132,6 @@ throw: interface conversion
panic PC=xxx
=========== fixedbugs/bug121.go
fixedbugs/bug121.go:9: syntax error near T
fixedbugs/bug121.go:20: incomplete type I
fixedbugs/bug121.go:20: illegal types for operand: AS
I
*S
=========== fixedbugs/bug148.go
2 3
interface is main.T, not main.T·bug148·1

View File

@ -32,6 +32,6 @@ func AddInst(Inst) *Inst {
func main() {
re := new(Regexp);
print("call addinst\n");
var x Inst = AddInst(new(Start)); // ERROR "illegal|incompatible"
var x Inst = AddInst(new(Start)); // ERROR "illegal|incompatible|is not"
print("return from addinst\n");
}