summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2009-08-27 11:16:34 -0700
committerRuss Cox <rsc@golang.org>2009-08-27 11:16:34 -0700
commit5ecf1c5811984c302a7eaa909390c022c2c0371b (patch)
treee55a8f7a791bf33dbe650602f838635e05e508b5
parent40ccd463b86d9b794c0cdb7354ac0f29fe9033bf (diff)
downloadgolang-5ecf1c5811984c302a7eaa909390c022c2c0371b.tar.gz
clean up ideal handling; reject attempts
to write type descriptors for ideal types R=ken OCL=33958 CL=33958
-rw-r--r--src/cmd/gc/const.c40
-rw-r--r--src/cmd/gc/go.h1
-rw-r--r--src/cmd/gc/reflect.c13
-rw-r--r--src/cmd/gc/subr.c10
4 files changed, 33 insertions, 31 deletions
diff --git a/src/cmd/gc/const.c b/src/cmd/gc/const.c
index 1433eb9ba..59bd9a388 100644
--- a/src/cmd/gc/const.c
+++ b/src/cmd/gc/const.c
@@ -66,18 +66,13 @@ convlit(Node **np, Type *t)
void
convlit1(Node **np, Type *t, int explicit)
{
- int et, ct;
+ int ct, et;
Node *n, *nn;
n = *np;
- if(n == N || t == T || n->type == T)
+ if(n == N || t == T || n->type == T || isideal(t) || eqtype(t, n->type))
return;
- et = t->etype;
- if(et == TIDEAL || et == TNIL)
- return;
- if(eqtype(t, n->type))
- return;
- if(!explicit && n->type->etype != TIDEAL && n->type != idealstring && n->type->etype != TNIL)
+ if(!explicit && !isideal(n->type))
return;
//dump("convlit1", n);
@@ -120,6 +115,7 @@ convlit1(Node **np, Type *t, int explicit)
if(ct < 0)
goto bad;
+ et = t->etype;
if(et == TINTER) {
if(ct == CTNIL && n->type == types[TNIL]) {
n->type = t;
@@ -129,21 +125,6 @@ convlit1(Node **np, Type *t, int explicit)
return;
}
- // if already has non-ideal type, cannot change implicitly
- if(!explicit) {
- switch(n->type->etype) {
- case TIDEAL:
- case TNIL:
- break;
- case TSTRING:
- if(n->type == idealstring)
- break;
- // fall through
- default:
- goto bad;
- }
- }
-
switch(ct) {
default:
goto bad;
@@ -203,7 +184,7 @@ convlit1(Node **np, Type *t, int explicit)
return;
bad:
- if(n->type->etype == TIDEAL) {
+ if(isideal(n->type)) {
defaultlit(&n, T);
*np = n;
}
@@ -720,9 +701,7 @@ defaultlit(Node **np, Type *t)
Node *n, *nn;
n = *np;
- if(n == N)
- return;
- if(n->type == T || (n->type->etype != TIDEAL && n->type->etype != TNIL))
+ if(n == N || !isideal(n->type))
return;
switch(n->op) {
@@ -749,8 +728,7 @@ defaultlit(Node **np, Type *t)
return;
}
- lno = lineno;
- lineno = n->lineno;
+ lno = setlineno(n);
switch(n->val.ctype) {
default:
if(t != T) {
@@ -763,6 +741,10 @@ defaultlit(Node **np, Type *t)
n->type = T;
break;
}
+ if(n->val.ctype == CTSTR) {
+ n->type = types[TSTRING];
+ break;
+ }
yyerror("defaultlit: unknown literal: %#N", n);
break;
case CTINT:
diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h
index f7d6f83c9..bcbc5f84c 100644
--- a/src/cmd/gc/go.h
+++ b/src/cmd/gc/go.h
@@ -805,6 +805,7 @@ int isslice(Type*);
int isinter(Type*);
int isnilinter(Type*);
int isddd(Type*);
+int isideal(Type*);
Type* maptype(Type*, Type*);
Type* methtype(Type*);
Node* typename(Type*);
diff --git a/src/cmd/gc/reflect.c b/src/cmd/gc/reflect.c
index 597b6a6a3..c82875ca8 100644
--- a/src/cmd/gc/reflect.c
+++ b/src/cmd/gc/reflect.c
@@ -320,7 +320,7 @@ dextratype(Type *t)
else
ot = duintptr(s, ot, 0);
}
- ggloblsym(s, ot, 1);
+ ggloblsym(s, ot, 0);
return s;
}
@@ -480,6 +480,10 @@ dtypesym(Type *t)
Sym *s, *s1, *s2;
Sig *a, *m;
Type *t1;
+ Sym *tsym;
+
+ if(t->etype == TNIL || t->etype == TIDEAL || t == idealstring)
+ fatal("dtypesym ideal %T", t);
s = typesym(t);
if(s->flags & SymSiggen)
@@ -492,6 +496,11 @@ dtypesym(Type *t)
t1 = T;
if(isptr[t->etype])
t1 = t->type;
+ tsym = S;
+ if(t1)
+ tsym = t1->sym;
+ else
+ tsym = t->sym;
if(strcmp(package, "runtime") == 0) {
if(t == types[t->etype])
@@ -639,7 +648,7 @@ ok:
break;
}
- ggloblsym(s, ot, 1);
+ ggloblsym(s, ot, tsym == nil);
return s;
}
diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c
index 3c4aaf2fe..052be2a84 100644
--- a/src/cmd/gc/subr.c
+++ b/src/cmd/gc/subr.c
@@ -1468,6 +1468,16 @@ isddd(Type *t)
return 0;
}
+int
+isideal(Type *t)
+{
+ if(t == T)
+ return 0;
+ if(t == idealstring)
+ return 1;
+ return t->etype == TNIL || t->etype == TIDEAL;
+}
+
/*
* given receiver of type t (t == r or t == *r)
* return type to hang methods off (r).