Commit 9dc22b6d authored by Russ Cox's avatar Russ Cox

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
parent 17808905
...@@ -907,6 +907,8 @@ nodarg(Type *t, int fp) ...@@ -907,6 +907,8 @@ nodarg(Type *t, int fp)
n->class = PPARAM; n->class = PPARAM;
break; break;
} }
n->typecheck = 1;
return n; return n;
} }
......
...@@ -200,8 +200,6 @@ bad: ...@@ -200,8 +200,6 @@ bad:
defaultlit(&n, T); defaultlit(&n, T);
*np = n; *np = n;
} }
yyerror("cannot convert %T constant to %T", n->type, t);
n->diag = 1;
return; return;
} }
...@@ -336,6 +334,9 @@ evconst(Node *n) ...@@ -336,6 +334,9 @@ evconst(Node *n)
switch(n->op) { switch(n->op) {
case OMAKE: case OMAKE:
case OMAKEMAP:
case OMAKESLICE:
case OMAKECHAN:
return; return;
} }
...@@ -557,7 +558,7 @@ evconst(Node *n) ...@@ -557,7 +558,7 @@ evconst(Node *n)
if(cmpslit(nl, nr) > 0) if(cmpslit(nl, nr) > 0)
goto settrue; goto settrue;
goto setfalse; goto setfalse;
case TUP(OADD, CTSTR): case TUP(OADDSTR, CTSTR):
len = v.u.sval->len + nr->val.u.sval->len; len = v.u.sval->len + nr->val.u.sval->len;
str = mal(sizeof(*str) + len); str = mal(sizeof(*str) + len);
str->len = len; str->len = len;
...@@ -605,6 +606,7 @@ unary: ...@@ -605,6 +606,7 @@ unary:
case TUP(OCONV, CTFLT): case TUP(OCONV, CTFLT):
case TUP(OCONV, CTSTR): case TUP(OCONV, CTSTR):
case TUP(OCONV, CTNIL): case TUP(OCONV, CTNIL):
case TUP(OARRAYBYTESTR, CTNIL):
convlit1(&nl, n->type, 1); convlit1(&nl, n->type, 1);
break; break;
......
...@@ -672,9 +672,9 @@ funclit1(Node *ntype, NodeList *body) ...@@ -672,9 +672,9 @@ funclit1(Node *ntype, NodeList *body)
for(l=func->cvars; l; l=l->next) { for(l=func->cvars; l; l=l->next) {
a = l->n; a = l->n;
d = oldname(a->sym); d = oldname(a->sym);
addrescapes(d);
args = list(args, nod(OADDR, d, N)); args = list(args, nod(OADDR, d, N));
} }
typechecklist(args, Erv);
n = nod(OCALL, clos, N); n = nod(OCALL, clos, N);
n->list = args; n->list = args;
...@@ -1642,7 +1642,7 @@ embedded(Sym *s) ...@@ -1642,7 +1642,7 @@ embedded(Sym *s)
NodeList* NodeList*
variter(NodeList *vl, Node *nt, NodeList *el) variter(NodeList *vl, Node *nt, NodeList *el)
{ {
int doexpr; int doexpr, lno;
Node *v, *e, *a; Node *v, *e, *a;
Type *tv; Type *tv;
NodeList *r; NodeList *r;
...@@ -1663,23 +1663,37 @@ variter(NodeList *vl, Node *nt, NodeList *el) ...@@ -1663,23 +1663,37 @@ variter(NodeList *vl, Node *nt, NodeList *el)
break; break;
} }
e = el->n; e = el->n;
el = el->next;
} else } else
e = N; e = N;
v = vl->n; v = vl->n;
tv = t; tv = t;
if(t == T) { if(e) {
lno = lineno;
lineno = v->lineno;
typecheck(&e, Erv); typecheck(&e, Erv);
defaultlit(&e, T); defaultlit(&e, t);
if(t)
e = typecheckconv(nil, e, t, 0);
if(tv == nil)
tv = e->type; tv = e->type;
if(tv && tv->etype == TNIL) {
yyerror("cannot initialize %#N to untyped nil", v);
tv = nil;
}
lineno = lno;
} }
a = N; a = N;
if(e != N || funcdepth > 0) if((e != N && tv != T) || funcdepth > 0)
a = nod(OAS, v, e); a = nod(OAS, v, e);
dodclvar(v, tv, &r); dodclvar(v, tv, &r);
if(a != N) if(a != N)
r = list(r, a); r = list(r, a);
if(el) {
el->n = e;
el = el->next;
}
} }
if(el != nil) if(el != nil)
yyerror("extra expr in var dcl"); yyerror("extra expr in var dcl");
......
...@@ -328,36 +328,41 @@ enum ...@@ -328,36 +328,41 @@ enum
OLITERAL, OLITERAL,
// exprs // exprs
OADD, OSUB, OOR, OXOR, OADD, OSUB, OOR, OXOR, OADDSTR,
OADDR, OADDR,
OANDAND, OANDAND,
OAPPENDSTR,
OARRAY, OARRAY,
OARRAYBYTESTR, OARRAYRUNESTR,
OAS, OAS2, OASOP, OAS, OAS2, OASOP,
OBAD, OBAD,
OCALL, OCALLFUNC, OCALLMETH, OCALLINTER, OCALL, OCALLFUNC, OCALLMETH, OCALLINTER,
OCAP, OCAP,
OCLOSE, OCLOSE,
OCLOSED, OCLOSED,
OCOMPOS, OCOMPSLICE, OCOMPMAP, OCMPIFACE, OCMPSTR,
OCONV, OCONVNOP, OCONVRUNE, OCONVSTRB, OCONVSTRI, OCONVA2S, OCOMPLIT, OMAPLIT, OSTRUCTLIT, OARRAYLIT,
OCOMPSLICE, OCOMPMAP,
OCONV, OCONVNOP, OCONVA2S, OCONVIFACE, OCONVSLICE,
ODCL, ODCLFUNC, ODCLFIELD, ODCLARG, ODCL, ODCLFUNC, ODCLFIELD, ODCLARG,
ODOT, ODOTPTR, ODOTMETH, ODOTINTER, ODOT, ODOTPTR, ODOTMETH, ODOTINTER,
ODOTTYPE, ODOTTYPE,
OEQ, ONE, OLT, OLE, OGE, OGT, OEQ, ONE, OLT, OLE, OGE, OGT,
OFUNC, OFUNC,
OIND, OIND,
OINDEX, OINDEXSTR, OINDEXMAP, OINDEXARR, OINDEX, OINDEXSTR, OINDEXMAP,
OKEY, OPARAM, OKEY, OPARAM,
OLEN, OLEN,
OMAKE, OMAKE, OMAKECHAN, OMAKEMAP, OMAKESLICE,
OMUL, ODIV, OMOD, OLSH, ORSH, OAND, OANDNOT, OMUL, ODIV, OMOD, OLSH, ORSH, OAND, OANDNOT,
ONEW, ONEW,
ONOT, OCOM, OPLUS, OMINUS, ONOT, OCOM, OPLUS, OMINUS,
OOROR, OOROR,
OPANIC, OPANICN, OPRINT, OPRINTN, OPANIC, OPANICN, OPRINT, OPRINTN,
OSEND, OSEND, OSENDNB,
OSLICE, OSLICESTR, OSLICEARR, OSLICE, OSLICEARR, OSLICESTR,
ORECV, ORECV,
ORUNESTR,
// stmts // stmts
OBLOCK, OBLOCK,
...@@ -470,10 +475,9 @@ enum ...@@ -470,10 +475,9 @@ enum
enum enum
{ {
Etop = 1<<1, // evaluated at statement level Etop = 1<<1, // evaluated at statement level
Elv = 1<<2, // evaluated in lvalue context Erv = 1<<2, // evaluated in value context
Erv = 1<<3, // evaluated in rvalue context Etype = 1<<3,
Etype = 1<<4, Ecall = 1<<4,
Ecall = 1<<5,
}; };
#define BITS 5 #define BITS 5
...@@ -658,6 +662,8 @@ EXTERN ushort blockgen; // max block number ...@@ -658,6 +662,8 @@ EXTERN ushort blockgen; // max block number
EXTERN ushort block; // current block number EXTERN ushort block; // current block number
EXTERN int hasdefer; // flag that curfn has defer statetment EXTERN int hasdefer; // flag that curfn has defer statetment
EXTERN Node* curfn;
EXTERN int maxround; EXTERN int maxround;
EXTERN int widthptr; EXTERN int widthptr;
...@@ -986,14 +992,12 @@ NodeList* ascompatet(int, NodeList*, Type**, int, NodeList**); ...@@ -986,14 +992,12 @@ NodeList* ascompatet(int, NodeList*, Type**, int, NodeList**);
NodeList* ascompatte(int, Type**, NodeList*, int, NodeList**); NodeList* ascompatte(int, Type**, NodeList*, int, NodeList**);
int ascompat(Type*, Type*); int ascompat(Type*, Type*);
Node* newcompat(Node*); Node* newcompat(Node*);
Node* makecompat(Node*);
Node* stringop(Node*, NodeList**); Node* stringop(Node*, NodeList**);
Type* fixmap(Type*); Type* fixmap(Type*);
Node* mapop(Node*, NodeList**); Node* mapop(Node*, NodeList**);
Type* fixchan(Type*); Type* fixchan(Type*);
Node* chanop(Node*, NodeList**); Node* chanop(Node*, NodeList**);
Node* arrayop(Node*); Node* ifacecvt(Type*, Node*, int, NodeList**);
Node* ifacecvt(Type*, Node*, int);
Node* ifaceop(Node*); Node* ifaceop(Node*);
int ifaceas(Type*, Type*, int); int ifaceas(Type*, Type*, int);
int ifaceas1(Type*, Type*, int); int ifaceas1(Type*, Type*, int);
...@@ -1011,11 +1015,11 @@ Node* arraylit(Node*, Node*, NodeList**); ...@@ -1011,11 +1015,11 @@ Node* arraylit(Node*, Node*, NodeList**);
Node* maplit(Node*, Node*, NodeList**); Node* maplit(Node*, Node*, NodeList**);
Node* selectas(Node*, Node*, NodeList**); Node* selectas(Node*, Node*, NodeList**);
Node* old2new(Node*, Type*, NodeList**); Node* old2new(Node*, Type*, NodeList**);
void addrescapes(Node*);
void heapmoves(void); void heapmoves(void);
void walkdeflist(NodeList*); void walkdeflist(NodeList*);
void walkdef(Node*); void walkdef(Node*);
void typechecklist(NodeList*, int); void typechecklist(NodeList*, int);
Node* typecheckconv(Node*, Node*, Type*, int);
Node* typecheck(Node**, int); Node* typecheck(Node**, int);
/* /*
......
...@@ -123,6 +123,7 @@ file: ...@@ -123,6 +123,7 @@ file:
{ {
if(debug['f']) if(debug['f'])
frame(1); frame(1);
if(nerrors == 0)
fninit($4); fninit($4);
if(nsyntaxerrors == 0) if(nsyntaxerrors == 0)
testdclstack(); testdclstack();
...@@ -882,7 +883,7 @@ pexpr: ...@@ -882,7 +883,7 @@ pexpr:
| convtype lbrace braced_keyval_list '}' | convtype lbrace braced_keyval_list '}'
{ {
// composite expression // composite expression
$$ = nod(OCOMPOS, N, $1); $$ = nod(OCOMPLIT, N, $1);
$$->list = $3; $$->list = $3;
// If the opening brace was an LBODY, // If the opening brace was an LBODY,
...@@ -894,7 +895,7 @@ pexpr: ...@@ -894,7 +895,7 @@ pexpr:
| pexpr '{' braced_keyval_list '}' | pexpr '{' braced_keyval_list '}'
{ {
// composite expression // composite expression
$$ = nod(OCOMPOS, N, $1); $$ = nod(OCOMPLIT, N, $1);
$$->list = $3; $$->list = $3;
} }
| fnliteral | fnliteral
......
...@@ -208,11 +208,12 @@ exprfmt(Fmt *f, Node *n, int prec) ...@@ -208,11 +208,12 @@ exprfmt(Fmt *f, Node *n, int prec)
exprfmt(f, n->left, 0); exprfmt(f, n->left, 0);
break; break;
case OCOMPOS: case OCOMPLIT:
fmtprint(f, "<compos>"); fmtprint(f, "<compos>");
break; break;
case ODOT: case ODOT:
case ODOTPTR:
case ODOTINTER: case ODOTINTER:
case ODOTMETH: case ODOTMETH:
exprfmt(f, n->left, 7); exprfmt(f, n->left, 7);
......
...@@ -2,6 +2,10 @@ ...@@ -2,6 +2,10 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
/*
* static initialization
*/
#include "go.h" #include "go.h"
static struct static struct
......
...@@ -1209,6 +1209,14 @@ Nconv(Fmt *fp) ...@@ -1209,6 +1209,14 @@ Nconv(Fmt *fp)
goto out; 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) { if(fp->flags & FmtSharp) {
exprfmt(fp, n, 0); exprfmt(fp, n, 0);
goto out; goto out;
...@@ -1593,22 +1601,7 @@ eqtype(Type *t1, Type *t2) ...@@ -1593,22 +1601,7 @@ eqtype(Type *t1, Type *t2)
int int
cvttype(Type *dst, Type *src) cvttype(Type *dst, Type *src)
{ {
Sym *ds, *ss; return eqtype1(dst, src, 0, 0);
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;
} }
int int
...@@ -1746,6 +1739,7 @@ noconv(Type *t1, Type *t2) ...@@ -1746,6 +1739,7 @@ noconv(Type *t1, Type *t2)
void void
argtype(Node *on, Type *t) argtype(Node *on, Type *t)
{ {
dowidth(t);
if(!subtype(&on->type, t, 0)) if(!subtype(&on->type, t, 0))
fatal("argtype: failed %N %T\n", on, t); fatal("argtype: failed %N %T\n", on, t);
} }
...@@ -2274,7 +2268,7 @@ saferef(Node *n, NodeList **init) ...@@ -2274,7 +2268,7 @@ saferef(Node *n, NodeList **init)
r = nod(OXXX, N, N); r = nod(OXXX, N, N);
*r = *n; *r = *n;
r->left = l; r->left = l;
typecheck(&r, Elv); typecheck(&r, Erv);
walkexpr(&r, init); walkexpr(&r, init);
return r; return r;
...@@ -2288,7 +2282,7 @@ saferef(Node *n, NodeList **init) ...@@ -2288,7 +2282,7 @@ saferef(Node *n, NodeList **init)
walkexpr(&a, init); walkexpr(&a, init);
*init = list(*init, a); *init = list(*init, a);
r = nod(OIND, l, N); r = nod(OIND, l, N);
typecheck(&r, Elv); typecheck(&r, Erv);
walkexpr(&r, init); walkexpr(&r, init);
return r; return r;
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -15,10 +15,10 @@ var ( ...@@ -15,10 +15,10 @@ var (
func main() { func main() {
cr = c; // ok cr = c; // ok
cs = c; // ok cs = c; // ok
c = cr; // ERROR "illegal types|incompatible" c = cr; // ERROR "illegal types|incompatible|cannot"
c = cs; // ERROR "illegal types|incompatible" c = cs; // ERROR "illegal types|incompatible|cannot"
cr = cs; // ERROR "illegal types|incompatible" cr = cs; // ERROR "illegal types|incompatible|cannot"
cs = cr; // ERROR "illegal types|incompatible" cs = cr; // ERROR "illegal types|incompatible|cannot"
c <- 0; // ok c <- 0; // ok
ok := c <- 0; // ok ok := c <- 0; // ok
......
...@@ -65,15 +65,15 @@ var ( ...@@ -65,15 +65,15 @@ var (
func f(int); func f(int);
func main() { func main() {
f(Int8); // ERROR "convert|wrong type" f(Int8); // ERROR "convert|wrong type|cannot"
f(Minus1); // ERROR "convert|wrong type" f(Minus1); // ERROR "convert|wrong type|cannot"
f(Uint8); // ERROR "convert|wrong type" f(Uint8); // ERROR "convert|wrong type|cannot"
f(Const); // OK f(Const); // OK
f(Float32); // ERROR "convert|wrong type" f(Float32); // ERROR "convert|wrong type|cannot"
f(Float); // ERROR "convert|wrong type" f(Float); // ERROR "convert|wrong type|cannot"
f(ConstFloat); // ERROR "truncate" f(ConstFloat); // ERROR "truncate"
f(ConstFloat - 0.5); // OK f(ConstFloat - 0.5); // OK
f(Big); // ERROR "convert|wrong type" f(Big); // ERROR "convert|wrong type|cannot"
f(String); // ERROR "convert|wrong type" f(String); // ERROR "convert|wrong type|cannot"
f(Bool); // ERROR "convert|wrong type" f(Bool); // ERROR "convert|wrong type|cannot"
} }
...@@ -21,5 +21,5 @@ var g = []int(nil) ...@@ -21,5 +21,5 @@ var g = []int(nil)
type H *[4]int type H *[4]int
type J []int type J []int
var h H var h H
var j1 J = h // ERROR "compat|illegal" var j1 J = h // ERROR "compat|illegal|cannot|cannot"
var j2 = J(h) var j2 = J(h)
...@@ -19,11 +19,11 @@ var x7 = float(1e1000); // ERROR "overflow" ...@@ -19,11 +19,11 @@ var x7 = float(1e1000); // ERROR "overflow"
// implicit conversions merit scrutiny // implicit conversions merit scrutiny
var s string; var s string;
var bad1 string = 1; // ERROR "conver|incompatible" var bad1 string = 1; // ERROR "conver|incompatible|invalid|cannot"
var bad2 = s + 1; // ERROR "conver|incompatible" var bad2 = s + 1; // ERROR "conver|incompatible|invalid"
var bad3 = s + 'a'; // ERROR "conver|incompatible" var bad3 = s + 'a'; // ERROR "conver|incompatible|invalid"
var bad4 = "a" + 1; // ERROR "literals|incompatible|convert" var bad4 = "a" + 1; // ERROR "literals|incompatible|convert|invalid"
var bad5 = "a" + 'a'; // ERROR "literals|incompatible|convert" var bad5 = "a" + 'a'; // ERROR "literals|incompatible|convert|invalid"
var bad6 int = 1.5; // ERROR "convert|truncate" var bad6 int = 1.5; // ERROR "convert|truncate"
var bad7 int = 1e100; // ERROR "overflow" var bad7 int = 1e100; // ERROR "overflow"
......
...@@ -6,12 +6,12 @@ ...@@ -6,12 +6,12 @@
package main package main
var a = []int { "a" }; // ERROR "conver|incompatible" var a = []int { "a" }; // ERROR "conver|incompatible|cannot"
var b = int { 1 }; // ERROR "compos" var b = int { 1 }; // ERROR "compos"
func f() int func f() int
func main() { func main() {
if f < 1 { } // ERROR "conver|incompatible" if f < 1 { } // ERROR "conver|incompatible|invalid"
} }
...@@ -9,7 +9,7 @@ package main ...@@ -9,7 +9,7 @@ package main
func putint(digits *string) { func putint(digits *string) {
var i byte; var i byte;
i = (*digits)[7]; // compiles i = (*digits)[7]; // compiles
i = digits[7]; // ERROR "illegal|is not" i = digits[7]; // ERROR "illegal|is not|invalid"
} }
func main() { func main() {
......
...@@ -7,5 +7,5 @@ ...@@ -7,5 +7,5 @@
package main package main
func main() { func main() {
var s string = nil; // ERROR "illegal|invalid" var s string = nil; // ERROR "illegal|invalid|cannot"
} }
...@@ -38,9 +38,9 @@ func main() { ...@@ -38,9 +38,9 @@ func main() {
assert(i != f3div2, "i != f3div2"); // ERROR "truncate" assert(i != f3div2, "i != f3div2"); // ERROR "truncate"
const g float64 = 1.0; const g float64 = 1.0;
i = g; // ERROR "convert|incompatible" i = g; // ERROR "convert|incompatible|cannot"
const h float64 = 3.14; const h float64 = 3.14;
i = h; // ERROR "convert|incompatible" i = h; // ERROR "convert|incompatible|cannot"
i = int(h); // ERROR "truncate" i = int(h); // ERROR "truncate"
} }
...@@ -10,16 +10,6 @@ type T func() ...@@ -10,16 +10,6 @@ type T func()
type I interface { type I interface {
f, g (); 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);
}
...@@ -8,5 +8,5 @@ package main ...@@ -8,5 +8,5 @@ package main
func main() { func main() {
const a uint64 = 10; const a uint64 = 10;
var b int64 = a; // ERROR "convert" var b int64 = a; // ERROR "convert|cannot"
} }
...@@ -10,5 +10,5 @@ func main() { ...@@ -10,5 +10,5 @@ func main() {
type Slice []byte; type Slice []byte;
a := [...]byte{ 0 }; a := [...]byte{ 0 };
b := Slice(&a); // This should be OK. b := Slice(&a); // This should be OK.
c := Slice(a); // ERROR "invalid|illegal" c := Slice(a); // ERROR "invalid|illegal|cannot"
} }
...@@ -5,9 +5,10 @@ ...@@ -5,9 +5,10 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package main package main
var v1 = ([10]int)(nil) // ERROR "illegal|nil|invalid" var v1 = ([10]int)(nil); // ERROR "illegal|nil|invalid"
var v2 [10]int = nil // ERROR "illegal|nil|incompatible" var v2 [10]int = nil; // ERROR "illegal|nil|incompatible"
var v3 [10]int var v3 [10]int;
var v4 = nil; // ERROR "nil"
func main() { func main() {
v3 = nil; // ERROR "illegal|nil|incompatible" v3 = nil; // ERROR "illegal|nil|incompatible"
} }
...@@ -9,6 +9,6 @@ package main ...@@ -9,6 +9,6 @@ package main
var notmain func() var notmain func()
func main() { func main() {
var x = &main; // ERROR "address of function|invalid" var x = &main; // ERROR "address of|invalid"
main = notmain; // ERROR "assign to function|invalid" main = notmain; // ERROR "assign to|invalid"
} }
...@@ -132,13 +132,6 @@ throw: interface conversion ...@@ -132,13 +132,6 @@ throw: interface conversion
panic PC=xxx 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 =========== fixedbugs/bug148.go
2 3 2 3
interface is main.T, not main.T·bug148·1 interface is main.T, not main.T·bug148·1
......
...@@ -32,6 +32,6 @@ func AddInst(Inst) *Inst { ...@@ -32,6 +32,6 @@ func AddInst(Inst) *Inst {
func main() { func main() {
re := new(Regexp); re := new(Regexp);
print("call addinst\n"); 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"); print("return from addinst\n");
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment