1
0
mirror of https://github.com/golang/go synced 2024-11-22 01:44:40 -07:00

defining package block names must override

universe block names.

BUG=2097244
R=ken
OCL=34295
CL=34473
This commit is contained in:
Russ Cox 2009-09-09 01:01:39 -07:00
parent 5d16d23362
commit e780fa8669
15 changed files with 255 additions and 102 deletions

View File

@ -237,7 +237,7 @@ typeinit(void)
{ {
int i, etype, sameas; int i, etype, sameas;
Type *t; Type *t;
Sym *s; Sym *s, *s1;
if(widthptr == 0) if(widthptr == 0)
fatal("typeinit before betypeinit"); fatal("typeinit before betypeinit");
@ -403,6 +403,7 @@ typeinit(void)
/* pick up the backend typedefs */ /* pick up the backend typedefs */
for(i=0; typedefs[i].name; i++) { for(i=0; typedefs[i].name; i++) {
s = lookup(typedefs[i].name); s = lookup(typedefs[i].name);
s1 = pkglookup(typedefs[i].name, "/builtin/");
etype = typedefs[i].etype; etype = typedefs[i].etype;
if(etype < 0 || etype >= nelem(types)) if(etype < 0 || etype >= nelem(types))
@ -425,7 +426,7 @@ typeinit(void)
dowidth(t); dowidth(t);
types[etype] = t; types[etype] = t;
s->def = typenod(t); s1->def = typenod(t);
} }
Array_array = rnd(0, widthptr); Array_array = rnd(0, widthptr);

View File

@ -722,6 +722,10 @@ defaultlit(Node **np, Type *t)
n->type = t; n->type = t;
return; return;
default: default:
if(n->left == N) {
dump("defaultlit", n);
fatal("defaultlit");
}
defaultlit(&n->left, t); defaultlit(&n->left, t);
defaultlit(&n->right, t); defaultlit(&n->right, t);
n->type = n->left->type; n->type = n->left->type;

View File

@ -417,10 +417,6 @@ dclname(Sym *s)
// referred to, in which case s->def is already // referred to, in which case s->def is already
// set to an ONONAME. // set to an ONONAME.
if(dclcontext == PEXTERN && s->block <= 1) { if(dclcontext == PEXTERN && s->block <= 1) {
// toss predefined name like "close"
// TODO(rsc): put close in at the end.
if(s->def != N && s->def->etype)
s->def = N;
if(s->def == N) if(s->def == N)
oldname(s); oldname(s);
if(s->def->op == ONONAME) if(s->def->op == ONONAME)
@ -971,11 +967,8 @@ checkarglist(NodeList *all)
t = n; t = n;
n = N; n = N;
} }
if(n != N) { if(n != N)
if(n->op == ONONAME && n->sym->def == n)
n->sym->def = N;
n = newname(n->sym); n = newname(n->sym);
}
n = nod(ODCLFIELD, n, t); n = nod(ODCLFIELD, n, t);
if(l->next != nil && n->right != N && n->right->op == OTYPE && isddd(n->right->type)) if(l->next != nil && n->right != N && n->right->op == OTYPE && isddd(n->right->type))
yyerror("only last argument can have type ..."); yyerror("only last argument can have type ...");

View File

@ -356,6 +356,7 @@ enum
ORECV, ORECV,
ORUNESTR, ORUNESTR,
OSELRECV, OSELRECV,
OIOTA,
// stmts // stmts
OBLOCK, OBLOCK,

View File

@ -1582,8 +1582,9 @@ hidden_type1:
| LNAME | LNAME
{ {
// predefined name like uint8 // predefined name like uint8
$1 = pkglookup($1->name, "/builtin/");
if($1->def == N || $1->def->op != OTYPE) { if($1->def == N || $1->def->op != OTYPE) {
yyerror("%S is not a type", $1); yyerror("%s is not a type", $1->name);
$$ = T; $$ = T;
} else } else
$$ = $1->def->type; $$ = $1->def->type;
@ -1660,11 +1661,15 @@ hidden_structdcl:
} }
| '?' hidden_type oliteral | '?' hidden_type oliteral
{ {
if(isptr[$2->etype]) { Sym *s;
$$ = embedded($2->type->sym);
$$->right = nod(OIND, $$->right, N); s = $2->sym;
} else if(s == S && isptr[$2->etype])
$$ = embedded($2->sym); s = $2->type->sym;
if(s && strcmp(s->package, "/builtin/") == 0)
s = lookup(s->name);
$$ = embedded(s);
$$->right = typenod($2);
$$->val = $3; $$->val = $3;
} }
@ -1709,9 +1714,9 @@ hidden_constant:
yyerror("bad negated constant"); yyerror("bad negated constant");
} }
} }
| name | sym
{ {
$$ = $1; $$ = oldname(pkglookup($1->name, "/builtin/"));
if($$->op != OLITERAL) if($$->op != OLITERAL)
yyerror("bad constant %S", $$->sym); yyerror("bad constant %S", $$->sym);
} }

View File

@ -8,8 +8,8 @@
#include <ar.h> #include <ar.h>
extern int yychar; extern int yychar;
Sym *anysym;
char nopackage[] = "____"; char nopackage[] = "____";
void lexfini(void);
#define DBG if(!debug['x']);else print #define DBG if(!debug['x']);else print
enum enum
@ -96,8 +96,8 @@ main(int argc, char *argv[])
if(curio.bin != nil) if(curio.bin != nil)
Bterm(curio.bin); Bterm(curio.bin);
} }
testdclstack(); testdclstack();
lexfini();
typecheckok = 1; typecheckok = 1;
if(debug['f']) if(debug['f'])
@ -278,9 +278,6 @@ importfile(Val *f)
return; return;
} }
if(!debug['A'])
anysym->def = typenod(types[TANY]);
if(!findpkg(f->u.sval)) if(!findpkg(f->u.sval))
fatal("can't find import: %Z", f->u.sval); fatal("can't find import: %Z", f->u.sval);
imp = Bopen(namebuf, OREAD); imp = Bopen(namebuf, OREAD);
@ -337,9 +334,6 @@ unimportfile(void)
{ {
linehist(nil, 0, 0); linehist(nil, 0, 0);
if(!debug['A'])
anysym->def = nil;
if(curio.bin != nil) { if(curio.bin != nil) {
Bterm(curio.bin); Bterm(curio.bin);
curio.bin = nil; curio.bin = nil;
@ -354,9 +348,6 @@ unimportfile(void)
void void
cannedimports(char *file, char *cp) cannedimports(char *file, char *cp)
{ {
if(!debug['A'])
anysym->def = typenod(types[TANY]);
lexlineno++; // if sys.6 is included on line 1, lexlineno++; // if sys.6 is included on line 1,
linehist(file, 0, 0); // the debugger gets confused linehist(file, 0, 0); // the debugger gets confused
@ -1274,10 +1265,9 @@ void
lexinit(void) lexinit(void)
{ {
int i, lex; int i, lex;
Sym *s; Sym *s, *s1;
Type *t; Type *t;
int etype; int etype;
Val v;
/* /*
* initialize basic types array * initialize basic types array
@ -1287,7 +1277,6 @@ lexinit(void)
lex = syms[i].lexical; lex = syms[i].lexical;
s = lookup(syms[i].name); s = lookup(syms[i].name);
s->lexical = lex; s->lexical = lex;
s->package = package;
etype = syms[i].etype; etype = syms[i].etype;
if(etype != Txxx) { if(etype != Txxx) {
@ -1302,48 +1291,26 @@ lexinit(void)
dowidth(t); dowidth(t);
types[etype] = t; types[etype] = t;
} }
s->def = typenod(t); s1 = pkglookup(syms[i].name, "/builtin/"); // impossible pkg name for builtins
if(etype == TANY) { s1->lexical = LNAME;
anysym = s; s1->def = typenod(t);
if(!debug['A'])
s->def = nil;
}
continue;
}
etype = syms[i].op;
if(etype != OXXX) {
s->def = nod(ONAME, N, N);
s->def->sym = s;
s->def->etype = etype;
s->def->builtin = 1;
continue; continue;
} }
} }
// there's only so much table-driven we can handle.
// these are special cases.
types[TNIL] = typ(TNIL);
s = lookup("nil");
v.ctype = CTNIL;
s->def = nodlit(v);
s->def->sym = s;
s->block = -1; // above top level
s = lookup("true");
s->def = nodbool(1);
s->def->sym = s;
s->block = -1; // above top level
s = lookup("false");
s->def = nodbool(0);
s->def->sym = s;
s->block = -1; // above top level
s = lookup("iota"); s = lookup("iota");
s->def = nodintconst(iota); s->def = nod(ONONAME, N, N);
s->def->iota = 1; // flag to reevaluate on copy s->def->iota = 1;
s->block = -1; // above top level s->def->sym = s;
s = pkglookup("true", "/builtin/");
s->def = nodbool(1);
s->def->sym = lookup("true");
s = pkglookup("false", "/builtin/");
s->def = nodbool(0);
s->def->sym = lookup("false");
// logically, the type of a string literal. // logically, the type of a string literal.
// types[TSTRING] is the named type string // types[TSTRING] is the named type string
@ -1362,6 +1329,63 @@ lexinit(void)
nblank = s->def; nblank = s->def;
} }
void
lexfini(void)
{
Sym *s;
int lex, etype, i;
Val v;
for(i=0; i<nelem(syms); i++) {
lex = syms[i].lexical;
if(lex != LNAME)
continue;
s = lookup(syms[i].name);
s->lexical = lex;
etype = syms[i].etype;
if(etype != Txxx && (etype != TANY || debug['A']))
if(s->def != N && s->def->op == ONONAME)
*s->def = *typenod(types[etype]);
etype = syms[i].op;
if(etype != OXXX && s->def != N && s->def->op == ONONAME) {
s->def->op = ONAME;
s->def->sym = s;
s->def->etype = etype;
s->def->builtin = 1;
}
}
for(i=0; typedefs[i].name; i++) {
s = lookup(typedefs[i].name);
if(s->def != N && s->def->op == ONONAME)
*s->def = *typenod(types[typedefs[i].etype]);
}
// there's only so much table-driven we can handle.
// these are special cases.
types[TNIL] = typ(TNIL);
s = lookup("nil");
if(s->def != N && s->def->op == ONONAME) {
v.ctype = CTNIL;
*s->def = *nodlit(v);
s->def->sym = s;
}
s = lookup("true");
if(s->def != N && s->def->op == ONONAME) {
*s->def = *nodbool(1);
s->def->sym = s;
}
s = lookup("false");
if(s->def != N && s->def->op == ONONAME) {
*s->def = *nodbool(0);
s->def->sym = s;
}
}
struct struct
{ {
int lex; int lex;
@ -1422,16 +1446,6 @@ lexname(int lex)
return buf; return buf;
} }
int
specialsym(Sym *s)
{
if(strcmp(s->name, "byte") == 0 && s->def->sym == lookup("uint8"))
return 1;
if(strcmp(s->name, "iota") == 0 && s->def->sym == S)
return 1;
return 0;
}
void void
mkpackage(char* pkg) mkpackage(char* pkg)
{ {
@ -1459,10 +1473,13 @@ mkpackage(char* pkg)
if(s->def->op == OPACK) { if(s->def->op == OPACK) {
// throw away top-level package name leftover // throw away top-level package name leftover
// from previous file. // from previous file.
// TODO(rsc): remember that there was a package
// name, so that the name cannot be redeclared
// as a non-package in other files.
s->def = N; s->def = N;
continue; continue;
} }
if(s->def->sym != s && !specialsym(s)) { if(s->def->sym != s) {
// throw away top-level name left over // throw away top-level name left over
// from previous import . "x" // from previous import . "x"
s->def = N; s->def = N;

View File

@ -1324,13 +1324,13 @@ treecopy(Node *n)
abort(); abort();
break; break;
case OLITERAL: case ONONAME:
if(n->iota) { if(n->iota) {
m = nodintconst(iota); m = nod(OIOTA, n, nodintconst(iota));
break; break;
} }
// fall through // fall through
case ONONAME: case OLITERAL:
case ONAME: case ONAME:
case OTYPE: case OTYPE:
m = n; m = n;

View File

@ -63,14 +63,25 @@ typecheck(Node **np, int top)
return N; return N;
// Skip typecheck if already done. // Skip typecheck if already done.
// But re-typecheck ONAME node in case context has changed. // But re-typecheck ONAME/OTYPE/OLITERAL/OPACK node in case context has changed.
if(n->typecheck == 1 && n->op != ONAME) if(n->typecheck == 1) {
switch(n->op) {
case ONAME:
case OTYPE:
case OLITERAL:
case OPACK:
break;
default:
return n; return n;
}
}
if(n->typecheck == 2) if(n->typecheck == 2)
fatal("typecheck loop"); fatal("typecheck loop");
n->typecheck = 2; n->typecheck = 2;
if(n->sym && n->walkdef != 1) redo:
if(n->sym)
walkdef(n); walkdef(n);
lno = setlineno(n); lno = setlineno(n);
@ -88,10 +99,6 @@ reswitch:
*/ */
case OLITERAL: case OLITERAL:
ok |= Erv; ok |= Erv;
if(n->iota && !(top & Eiota)) {
yyerror("use of iota not in constant initializer");
goto error;
}
if(n->val.ctype == CTSTR) if(n->val.ctype == CTSTR)
n->type = idealstring; n->type = idealstring;
goto ret; goto ret;
@ -116,6 +123,15 @@ reswitch:
yyerror("use of package %S not in selector", n->sym); yyerror("use of package %S not in selector", n->sym);
goto error; goto error;
case OIOTA:
// looked like iota during parsing but might
// have been redefined. decide.
if(n->left->op != ONONAME)
n = n->left;
else
n = n->right;
goto redo;
/* /*
* types (OIND is with exprs) * types (OIND is with exprs)
*/ */
@ -1025,8 +1041,6 @@ error:
out: out:
lineno = lno; lineno = lno;
n->typecheck = 1; n->typecheck = 1;
if(n->iota)
n->typecheck = 0;
*np = n; *np = n;
return n; return n;
} }
@ -1592,7 +1606,7 @@ typecheckcomplit(Node **np)
len = i; len = i;
if(t->bound >= 0 && len > t->bound) { if(t->bound >= 0 && len > t->bound) {
setlineno(l); setlineno(l);
yyerror("array index out of bounds"); yyerror("array index %d out of bounds [0:%d]", len, t->bound);
t->bound = -1; // no more errors t->bound = -1; // no more errors
} }
} }

View File

@ -161,7 +161,7 @@ walkdef(Node *n)
yyerror("xxx"); yyerror("xxx");
} }
typecheck(&e, Erv | Eiota); typecheck(&e, Erv | Eiota);
if(e->op != OLITERAL) { if(e->type != T && e->op != OLITERAL) {
yyerror("const initializer must be constant"); yyerror("const initializer must be constant");
goto ret; goto ret;
} }

View File

@ -13,7 +13,7 @@ import "unsafe"
type Word uintptr type Word uintptr
const ( const (
_S = uintptr(unsafe.Sizeof(Word)); // TODO(gri) should Sizeof return a uintptr? _S = uintptr(unsafe.Sizeof(Word(0))); // TODO(gri) should Sizeof return a uintptr?
_W = _S*8; _W = _S*8;
_B = 1<<_W; _B = 1<<_W;
_M = _B-1; _M = _B-1;

View File

@ -12,7 +12,6 @@ func f(x int) { }
func main() { func main() {
f(X); f(X);
f(iota); // ERROR "iota.*initializer" f(iota); // ERROR "iota"
f(X); f(X);
f(iota); // ERROR "iota.*initializer"
} }

View File

@ -163,10 +163,6 @@ BUG: should compile
=========== bugs/bug193.go =========== bugs/bug193.go
BUG: errchk: bugs/bug193.go:14: missing expected error: 'shift' BUG: errchk: bugs/bug193.go:14: missing expected error: 'shift'
=========== bugs/bug194.go
bugs/bug194.go:15: array index must be non-negative integer constant
BUG should compile and run
=========== bugs/bug196.go =========== bugs/bug196.go
too many calls: 5 too many calls: 5
panic PC=xxx panic PC=xxx

75
test/rename.go Normal file
View File

@ -0,0 +1,75 @@
// $G $D/$F.go && $L $F.$A && ./$A.out
// Copyright 2009 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 main
import "fmt"
func main() {
n :=
bool +
byte +
float +
float32 +
float64 +
int +
int8 +
int16 +
int32 +
int64 +
uint +
uint8 +
uint16 +
uint32 +
uint64 +
uintptr +
true +
false +
iota +
nil +
cap +
len +
make +
new +
panic +
panicln +
print +
println;
if n != 28*29/2 {
fmt.Println("BUG: wrong n", n, 28*29/2)
}
}
const (
bool = 1;
byte = 2;
float = 3;
float32 = 4;
float64 = 5;
int = 6;
int8 = 7;
int16 = 8;
int32 = 9;
int64 = 10;
uint = 11;
uint8 = 12;
uint16 = 13;
uint32 = 14;
uint64 = 15;
uintptr = 16;
true = 17;
false = 18;
iota = 19;
nil = 20;
cap = 21;
len = 22;
make = 23;
new = 24;
panic = 25;
panicln = 26;
print = 27;
println = 28;
)

48
test/rename1.go Normal file
View File

@ -0,0 +1,48 @@
// errchk $G -e $D/$F.go
// Copyright 2009 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 main
func main() {
var n byte; // ERROR "not a type"
var y = float(0); // ERROR "cannot call"
const (
a = 1+iota; // ERROR "string"
)
}
const (
bool = 1;
byte = 2;
float = 3;
float32 = 4;
float64 = 5;
int = 6;
int8 = 7;
int16 = 8;
int32 = 9;
int64 = 10;
uint = 11;
uint8 = 12;
uint16 = 13;
uint32 = 14;
uint64 = 15;
uintptr = 16;
true = 17;
false = 18;
iota = "abc";
nil = 20;
cap = 21;
len = 22;
make = 23;
new = 24;
panic = 25;
panicln = 26;
print = 27;
println = 28;
)