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:
parent
178089056e
commit
9dc22b6d6f
@ -907,6 +907,8 @@ nodarg(Type *t, int fp)
|
||||
n->class = PPARAM;
|
||||
break;
|
||||
}
|
||||
|
||||
n->typecheck = 1;
|
||||
return n;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
1470
src/cmd/gc/walk.c
1470
src/cmd/gc/walk.c
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -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"
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -7,5 +7,5 @@
|
||||
package main
|
||||
|
||||
func main() {
|
||||
var s string = nil; // ERROR "illegal|invalid"
|
||||
var s string = nil; // ERROR "illegal|invalid|cannot"
|
||||
}
|
||||
|
@ -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"
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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"
|
||||
}
|
||||
|
@ -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"
|
||||
}
|
||||
|
@ -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"
|
||||
}
|
||||
|
@ -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"
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user