summaryrefslogtreecommitdiff
path: root/src/cmd/gc
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/gc')
-rw-r--r--src/cmd/gc/align.c4
-rw-r--r--src/cmd/gc/cplx.c20
-rw-r--r--src/cmd/gc/dcl.c41
-rw-r--r--src/cmd/gc/go.h5
-rw-r--r--src/cmd/gc/go.y4
-rw-r--r--src/cmd/gc/lex.c10
-rw-r--r--src/cmd/gc/print.c11
-rw-r--r--src/cmd/gc/reflect.c87
-rw-r--r--src/cmd/gc/subr.c28
-rw-r--r--src/cmd/gc/swt.c4
-rw-r--r--src/cmd/gc/typecheck.c57
-rw-r--r--src/cmd/gc/walk.c83
12 files changed, 266 insertions, 88 deletions
diff --git a/src/cmd/gc/align.c b/src/cmd/gc/align.c
index a01e2ea46..a8454bf13 100644
--- a/src/cmd/gc/align.c
+++ b/src/cmd/gc/align.c
@@ -468,7 +468,7 @@ typeinit(void)
okforadd[i] = 1;
okforarith[i] = 1;
okforconst[i] = 1;
-// issimple[i] = 1;
+ issimple[i] = 1;
}
}
@@ -530,7 +530,7 @@ typeinit(void)
okfor[OCOM] = okforand;
okfor[OMINUS] = okforarith;
okfor[ONOT] = okforbool;
- okfor[OPLUS] = okforadd;
+ okfor[OPLUS] = okforarith;
// special
okfor[OCAP] = okforcap;
diff --git a/src/cmd/gc/cplx.c b/src/cmd/gc/cplx.c
index 3ec9fe5a2..890cf7f10 100644
--- a/src/cmd/gc/cplx.c
+++ b/src/cmd/gc/cplx.c
@@ -12,6 +12,19 @@ static void minus(Node *nl, Node *res);
#define CASE(a,b) (((a)<<16)|((b)<<0))
+static int
+overlap(Node *f, Node *t)
+{
+ // check whether f and t could be overlapping stack references.
+ // not exact, because it's hard to check for the stack register
+ // in portable code. close enough: worst case we will allocate
+ // an extra temporary and the registerizer will clean it up.
+ return f->op == OINDREG &&
+ t->op == OINDREG &&
+ f->xoffset+f->type->width >= t->xoffset &&
+ t->xoffset+t->type->width >= f->xoffset;
+}
+
/*
* generate:
* res = n;
@@ -43,9 +56,10 @@ complexmove(Node *f, Node *t)
case CASE(TCOMPLEX64,TCOMPLEX128):
case CASE(TCOMPLEX128,TCOMPLEX64):
case CASE(TCOMPLEX128,TCOMPLEX128):
- // complex to complex move/convert
- // make from addable
- if(!f->addable) {
+ // complex to complex move/convert.
+ // make f addable.
+ // also use temporary if possible stack overlap.
+ if(!f->addable || overlap(f, t)) {
tempname(&n1, f->type);
complexmove(f, &n1);
f = &n1;
diff --git a/src/cmd/gc/dcl.c b/src/cmd/gc/dcl.c
index 3089a23b0..99af18d9f 100644
--- a/src/cmd/gc/dcl.c
+++ b/src/cmd/gc/dcl.c
@@ -560,6 +560,7 @@ funcargs(Node *nt)
{
Node *n;
NodeList *l;
+ int gen;
if(nt->op != OTFUNC)
fatal("funcargs %O", nt->op);
@@ -589,6 +590,7 @@ funcargs(Node *nt)
}
// declare the out arguments.
+ gen = 0;
for(l=nt->rlist; l; l=l->next) {
n = l->n;
if(n->op != ODCLFIELD)
@@ -596,6 +598,11 @@ funcargs(Node *nt)
if(n->left != N) {
n->left->op = ONAME;
n->left->ntype = n->right;
+ if(isblank(n->left)) {
+ // Give it a name so we can assign to it during return.
+ snprint(namebuf, sizeof(namebuf), ".anon%d", gen++);
+ n->left->sym = lookup(namebuf);
+ }
declare(n->left, PPARAMOUT);
}
}
@@ -672,10 +679,10 @@ typedcl2(Type *pt, Type *t)
ok:
n = pt->nod;
- *pt = *t;
- pt->method = nil;
+ copytype(pt->nod, t);
+ // unzero nod
pt->nod = n;
- pt->sym = n->sym;
+
pt->sym->lastlineno = parserline();
declare(n, PEXTERN);
@@ -697,12 +704,10 @@ stotype(NodeList *l, int et, Type **t, int funarg)
Type *f, *t1, *t2, **t0;
Strlit *note;
int lno;
- NodeList *init;
Node *n, *left;
char *what;
t0 = t;
- init = nil;
lno = lineno;
what = "field";
if(et == TINTER)
@@ -1130,6 +1135,32 @@ addmethod(Sym *sf, Type *t, int local)
pa = pa->type;
f = methtype(pa);
if(f == T) {
+ t = pa;
+ if(t != T) {
+ if(isptr[t->etype]) {
+ if(t->sym != S) {
+ yyerror("invalid receiver type %T (%T is a pointer type)", pa, t);
+ return;
+ }
+ t = t->type;
+ }
+ }
+ if(t != T) {
+ if(t->sym == S) {
+ yyerror("invalid receiver type %T (%T is an unnamed type)", pa, t);
+ return;
+ }
+ if(isptr[t->etype]) {
+ yyerror("invalid receiver type %T (%T is a pointer type)", pa, t);
+ return;
+ }
+ if(t->etype == TINTER) {
+ yyerror("invalid receiver type %T (%T is an interface type)", pa, t);
+ return;
+ }
+ }
+ // Should have picked off all the reasons above,
+ // but just in case, fall back to generic error.
yyerror("invalid receiver type %T", pa);
return;
}
diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h
index bb258a193..f58b76789 100644
--- a/src/cmd/gc/go.h
+++ b/src/cmd/gc/go.h
@@ -315,6 +315,7 @@ struct Pkg
{
char* name;
Strlit* path;
+ Sym* pathsym;
char* prefix;
Pkg* link;
char exported; // import line written in export data
@@ -581,6 +582,7 @@ struct Io
Biobuf* bin;
int32 ilineno;
int nlsemi;
+ int eofnl;
int peekc;
int peekc1; // second peekc for ...
char* cp; // used for content when bin==nil
@@ -1170,9 +1172,12 @@ Node* unsafenmagic(Node *n);
*/
Node* callnew(Type *t);
Node* chanfn(char *name, int n, Type *t);
+void copytype(Node *n, Type *t);
+void defertypecopy(Node *n, Type *t);
Node* mkcall(char *name, Type *t, NodeList **init, ...);
Node* mkcall1(Node *fn, Type *t, NodeList **init, ...);
void queuemethod(Node *n);
+void resumetypecopy(void);
int vmatch1(Node *l, Node *r);
void walk(Node *fn);
Node* walkdef(Node *n);
diff --git a/src/cmd/gc/go.y b/src/cmd/gc/go.y
index 89899ae1e..7adfd002a 100644
--- a/src/cmd/gc/go.y
+++ b/src/cmd/gc/go.y
@@ -1853,6 +1853,10 @@ hidden_interfacedcl:
{
$$ = nod(ODCLFIELD, newname($1), typenod(functype(fakethis(), $3, $5)));
}
+| hidden_importsym '(' ohidden_funarg_list ')' ohidden_funres
+ {
+ $$ = nod(ODCLFIELD, newname($1), typenod(functype(fakethis(), $3, $5)));
+ }
ohidden_funres:
{
diff --git a/src/cmd/gc/lex.c b/src/cmd/gc/lex.c
index bfd96274e..04dd0d5b9 100644
--- a/src/cmd/gc/lex.c
+++ b/src/cmd/gc/lex.c
@@ -249,6 +249,7 @@ main(int argc, char *argv[])
for(l=xtop; l; l=l->next)
if(l->n->op == ODCL || l->n->op == OAS)
typecheck(&l->n, Etop);
+ resumetypecopy();
resumecheckwidth();
for(l=xtop; l; l=l->next)
if(l->n->op == ODCLFUNC)
@@ -1310,7 +1311,7 @@ getc(void)
lexlineno++;
return c;
}
-
+
if(curio.bin == nil) {
c = *curio.cp & 0xff;
if(c != 0)
@@ -1325,8 +1326,11 @@ getc(void)
break;
}
case EOF:
- return EOF;
-
+ // insert \n at EOF
+ if(curio.eofnl)
+ return EOF;
+ curio.eofnl = 1;
+ c = '\n';
case '\n':
if(pushedio.bin == nil)
lexlineno++;
diff --git a/src/cmd/gc/print.c b/src/cmd/gc/print.c
index fee37f6d0..e03a14080 100644
--- a/src/cmd/gc/print.c
+++ b/src/cmd/gc/print.c
@@ -242,6 +242,17 @@ exprfmt(Fmt *f, Node *n, int prec)
exprfmt(f, n->right, 0);
break;
+ case OAS2:
+ case OAS2DOTTYPE:
+ case OAS2FUNC:
+ case OAS2MAPR:
+ case OAS2MAPW:
+ case OAS2RECV:
+ exprlistfmt(f, n->list);
+ fmtprint(f, " = ");
+ exprlistfmt(f, n->rlist);
+ break;
+
case OADD:
case OANDAND:
case OANDNOT:
diff --git a/src/cmd/gc/reflect.c b/src/cmd/gc/reflect.c
index b98e820c6..810787d30 100644
--- a/src/cmd/gc/reflect.c
+++ b/src/cmd/gc/reflect.c
@@ -137,7 +137,6 @@ methodfunc(Type *f, Type *receiver)
static Sig*
methods(Type *t)
{
- int o;
Type *f, *mt, *it, *this;
Sig *a, *b;
Sym *method;
@@ -157,7 +156,6 @@ methods(Type *t)
// make list of methods for t,
// generating code if necessary.
a = nil;
- o = 0;
oldlist = nil;
for(f=mt->xmethod; f; f=f->down) {
if(f->type->etype != TFUNC)
@@ -184,6 +182,11 @@ methods(Type *t)
a = b;
a->name = method->name;
+ if(!exportname(method->name)) {
+ if(method->pkg == nil)
+ fatal("methods: missing package");
+ a->pkg = method->pkg;
+ }
a->isym = methodsym(method, it, 1);
a->tsym = methodsym(method, t, 0);
a->type = methodfunc(f->type, t);
@@ -240,14 +243,12 @@ static Sig*
imethods(Type *t)
{
Sig *a, *all, *last;
- int o;
Type *f;
Sym *method, *isym;
Prog *oldlist;
all = nil;
last = nil;
- o = 0;
oldlist = nil;
for(f=t->type; f; f=f->down) {
if(f->etype != TFIELD)
@@ -257,8 +258,11 @@ imethods(Type *t)
method = f->sym;
a = mal(sizeof(*a));
a->name = method->name;
- if(!exportname(method->name))
+ if(!exportname(method->name)) {
+ if(method->pkg == nil)
+ fatal("imethods: missing package");
a->pkg = method->pkg;
+ }
a->mtype = f->type;
a->offset = 0;
a->type = methodfunc(f->type, nil);
@@ -301,26 +305,6 @@ imethods(Type *t)
return all;
}
-static int
-dgopkgpath(Sym *s, int ot, Pkg *pkg)
-{
- if(pkg == nil)
- return dgostringptr(s, ot, nil);
-
- // Emit reference to go.importpath.""., which 6l will
- // rewrite using the correct import path. Every package
- // that imports this one directly defines the symbol.
- if(pkg == localpkg) {
- static Sym *ns;
-
- if(ns == nil)
- ns = pkglookup("importpath.\"\".", mkpkg(strlit("go")));
- return dsymptr(s, ot, ns, 0);
- }
-
- return dgostringptr(s, ot, pkg->name);
-}
-
static void
dimportpath(Pkg *p)
{
@@ -328,6 +312,9 @@ dimportpath(Pkg *p)
char *nam;
Node *n;
+ if(p->pathsym != S)
+ return;
+
if(gopkg == nil) {
gopkg = mkpkg(strlit("go"));
gopkg->name = "go";
@@ -339,11 +326,33 @@ dimportpath(Pkg *p)
free(nam);
n->class = PEXTERN;
n->xoffset = 0;
+ p->pathsym = n->sym;
gdatastring(n, p->path);
ggloblsym(n->sym, types[TSTRING]->width, 1);
}
+static int
+dgopkgpath(Sym *s, int ot, Pkg *pkg)
+{
+ if(pkg == nil)
+ return dgostringptr(s, ot, nil);
+
+ // Emit reference to go.importpath.""., which 6l will
+ // rewrite using the correct import path. Every package
+ // that imports this one directly defines the symbol.
+ if(pkg == localpkg) {
+ static Sym *ns;
+
+ if(ns == nil)
+ ns = pkglookup("importpath.\"\".", mkpkg(strlit("go")));
+ return dsymptr(s, ot, ns, 0);
+ }
+
+ dimportpath(pkg);
+ return dsymptr(s, ot, pkg->pathsym, 0);
+}
+
/*
* uncommonType
* ../../pkg/runtime/type.go:/uncommonType
@@ -694,7 +703,7 @@ dtypesym(Type *t)
int ot, xt, n, isddd, dupok;
Sym *s, *s1, *s2;
Sig *a, *m;
- Type *t1, *tbase;
+ Type *t1, *tbase, *t2;
if(isideal(t))
fatal("dtypesym %T", t);
@@ -731,15 +740,25 @@ ok:
break;
case TARRAY:
- // ../../pkg/runtime/type.go:/ArrayType
- s1 = dtypesym(t->type);
- ot = dcommontype(s, ot, t);
- xt = ot - 2*widthptr;
- ot = dsymptr(s, ot, s1, 0);
- if(t->bound < 0)
- ot = duintptr(s, ot, -1);
- else
+ if(t->bound >= 0) {
+ // ../../pkg/runtime/type.go:/ArrayType
+ s1 = dtypesym(t->type);
+ t2 = typ(TARRAY);
+ t2->type = t->type;
+ t2->bound = -1; // slice
+ s2 = dtypesym(t2);
+ ot = dcommontype(s, ot, t);
+ xt = ot - 2*widthptr;
+ ot = dsymptr(s, ot, s1, 0);
+ ot = dsymptr(s, ot, s2, 0);
ot = duintptr(s, ot, t->bound);
+ } else {
+ // ../../pkg/runtime/type.go:/SliceType
+ s1 = dtypesym(t->type);
+ ot = dcommontype(s, ot, t);
+ xt = ot - 2*widthptr;
+ ot = dsymptr(s, ot, s1, 0);
+ }
break;
case TCHAN:
diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c
index 2098794a7..bb2505694 100644
--- a/src/cmd/gc/subr.c
+++ b/src/cmd/gc/subr.c
@@ -488,7 +488,7 @@ algtype(Type *t)
{
int a;
- if(issimple[t->etype] || isptr[t->etype] || iscomplex[t->etype] ||
+ if(issimple[t->etype] || isptr[t->etype] ||
t->etype == TCHAN || t->etype == TFUNC || t->etype == TMAP) {
if(t->width == widthptr)
a = AMEMWORD;
@@ -660,12 +660,10 @@ nodbool(int b)
Type*
aindex(Node *b, Type *t)
{
- NodeList *init;
Type *r;
int bound;
bound = -1; // open bound
- init = nil;
typecheck(&b, Erv);
if(b != nil) {
switch(consttype(b)) {
@@ -1266,7 +1264,12 @@ Tpretty(Fmt *fp, Type *t)
case TINTER:
fmtprint(fp, "interface {");
for(t1=t->type; t1!=T; t1=t1->down) {
- fmtprint(fp, " %hS%hhT", t1->sym, t1->type);
+ fmtprint(fp, " ");
+ if(exportname(t1->sym->name))
+ fmtprint(fp, "%hS", t1->sym);
+ else
+ fmtprint(fp, "%S", t1->sym);
+ fmtprint(fp, "%hhT", t1->type);
if(t1->down)
fmtprint(fp, ";");
}
@@ -1728,17 +1731,13 @@ isideal(Type *t)
Type*
methtype(Type *t)
{
- int ptr;
-
if(t == T)
return T;
// strip away pointer if it's there
- ptr = 0;
if(isptr[t->etype]) {
if(t->sym != S)
return T;
- ptr = 1;
t = t->type;
if(t == T)
return T;
@@ -1929,13 +1928,14 @@ assignop(Type *src, Type *dst, char **why)
}
return 0;
}
+ if(isptrto(dst, TINTER)) {
+ if(why != nil)
+ *why = smprint(":\n\t%T is pointer to interface, not interface", dst);
+ return 0;
+ }
if(src->etype == TINTER && dst->etype != TBLANK) {
- if(why != nil) {
- if(isptrto(dst, TINTER))
- *why = smprint(":\n\t%T is interface, not pointer to interface", src);
- else
- *why = ": need type assertion";
- }
+ if(why != nil)
+ *why = ": need type assertion";
return 0;
}
diff --git a/src/cmd/gc/swt.c b/src/cmd/gc/swt.c
index fbc9c4903..6e8436c3c 100644
--- a/src/cmd/gc/swt.c
+++ b/src/cmd/gc/swt.c
@@ -250,7 +250,7 @@ newlabel(void)
static void
casebody(Node *sw, Node *typeswvar)
{
- Node *os, *oc, *n, *c, *last;
+ Node *n, *c, *last;
Node *def;
NodeList *cas, *stat, *l, *lc;
Node *go, *br;
@@ -263,8 +263,6 @@ casebody(Node *sw, Node *typeswvar)
cas = nil; // cases
stat = nil; // statements
def = N; // defaults
- os = N; // last statement
- oc = N; // last case
br = nod(OBREAK, N, N);
for(l=sw->list; l; l=l->next) {
diff --git a/src/cmd/gc/typecheck.c b/src/cmd/gc/typecheck.c
index 1cc5abd5c..c48bf7a29 100644
--- a/src/cmd/gc/typecheck.c
+++ b/src/cmd/gc/typecheck.c
@@ -31,6 +31,7 @@ static void checkassign(Node*);
static void checkassignlist(NodeList*);
static void stringtoarraylit(Node**);
static Node* resolve(Node*);
+static Type* getforwtype(Node*);
/*
* resolve ONONAME to definition, if any.
@@ -56,7 +57,7 @@ typechecklist(NodeList *l, int top)
typecheck(&l->n, top);
}
-static char* typekind[] = {
+static char* _typekind[] = {
[TINT] = "int",
[TUINT] = "uint",
[TINT8] = "int8",
@@ -82,8 +83,22 @@ static char* typekind[] = {
[TMAP] = "map",
[TARRAY] = "array",
[TFUNC] = "func",
+ [TNIL] = "nil",
+ [TIDEAL] = "ideal number",
};
+static char*
+typekind(int et)
+{
+ static char buf[50];
+ char *s;
+
+ if(0 <= et && et < nelem(_typekind) && (s=_typekind[et]) != nil)
+ return s;
+ snprint(buf, sizeof buf, "etype=%d", et);
+ return buf;
+}
+
/*
* type check node *np.
* replaces *np with a new pointer in some cases.
@@ -96,7 +111,7 @@ typecheck(Node **np, int top)
Node *n, *l, *r;
NodeList *args;
int lno, ok, ntop;
- Type *t, *tp, *missing, *have;
+ Type *t, *tp, *ft, *missing, *have;
Sym *sym;
Val v;
char *why;
@@ -139,6 +154,11 @@ typecheck(Node **np, int top)
yyerror("use of builtin %S not in function call", n->sym);
goto error;
}
+
+ // a dance to handle forward-declared recursive pointer types.
+ if(n->op == OTYPE && (ft = getforwtype(n->ntype)) != T)
+ defertypecopy(n, ft);
+
walkdef(n);
n->realtype = n->type;
if(n->op == ONONAME)
@@ -406,7 +426,7 @@ reswitch:
}
if(!okfor[op][et]) {
notokfor:
- yyerror("invalid operation: %#N (operator %#O not defined on %s)", n, op, typekind[et]);
+ yyerror("invalid operation: %#N (operator %#O not defined on %s)", n, op, typekind(et));
goto error;
}
// okfor allows any array == array;
@@ -992,9 +1012,13 @@ reswitch:
defaultlit(&n->right, T);
// copy([]byte, string)
- if(isslice(n->left->type) && n->left->type->type == types[TUINT8] && n->right->type->etype == TSTRING)
- goto ret;
-
+ if(isslice(n->left->type) && n->right->type->etype == TSTRING) {
+ if (n->left->type->type ==types[TUINT8])
+ goto ret;
+ yyerror("arguments to copy have different element types: %lT and string", n->left->type);
+ goto error;
+ }
+
if(!isslice(n->left->type) || !isslice(n->right->type)) {
if(!isslice(n->left->type) && !isslice(n->right->type))
yyerror("arguments to copy must be slices; have %lT, %lT", n->left->type, n->right->type);
@@ -2452,3 +2476,24 @@ stringtoarraylit(Node **np)
typecheck(&nn, Erv);
*np = nn;
}
+
+static Type*
+getforwtype(Node *n)
+{
+ Node *f1, *f2;
+
+ for(f1=f2=n; ; n=n->ntype) {
+ if((n = resolve(n)) == N || n->op != OTYPE)
+ return T;
+
+ if(n->type != T && n->type->etype == TFORW)
+ return n->type;
+
+ // Check for ntype cycle.
+ if((f2 = resolve(f2)) != N && (f1 = resolve(f2->ntype)) != N) {
+ f2 = resolve(f1->ntype);
+ if(f1 == n || f2 == n)
+ return T;
+ }
+ }
+}
diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c
index b8c6842e0..278eef414 100644
--- a/src/cmd/gc/walk.c
+++ b/src/cmd/gc/walk.c
@@ -119,6 +119,62 @@ domethod(Node *n)
checkwidth(n->type);
}
+typedef struct NodeTypeList NodeTypeList;
+struct NodeTypeList {
+ Node *n;
+ Type *t;
+ NodeTypeList *next;
+};
+
+static NodeTypeList *dntq;
+static NodeTypeList *dntend;
+
+void
+defertypecopy(Node *n, Type *t)
+{
+ NodeTypeList *ntl;
+
+ if(n == N || t == T)
+ return;
+
+ ntl = mal(sizeof *ntl);
+ ntl->n = n;
+ ntl->t = t;
+ ntl->next = nil;
+
+ if(dntq == nil)
+ dntq = ntl;
+ else
+ dntend->next = ntl;
+
+ dntend = ntl;
+}
+
+void
+resumetypecopy(void)
+{
+ NodeTypeList *l;
+
+ for(l=dntq; l; l=l->next)
+ copytype(l->n, l->t);
+}
+
+void
+copytype(Node *n, Type *t)
+{
+ *n->type = *t;
+
+ t = n->type;
+ t->sym = n->sym;
+ t->local = n->local;
+ t->vargen = n->vargen;
+ t->siggen = 0;
+ t->method = nil;
+ t->nod = N;
+ t->printed = 0;
+ t->deferwidth = 0;
+}
+
static void
walkdeftype(Node *n)
{
@@ -141,20 +197,14 @@ walkdeftype(Node *n)
goto ret;
}
- // copy new type and clear fields
- // that don't come along
maplineno = n->type->maplineno;
embedlineno = n->type->embedlineno;
- *n->type = *t;
- t = n->type;
- t->sym = n->sym;
- t->local = n->local;
- t->vargen = n->vargen;
- t->siggen = 0;
- t->method = nil;
- t->nod = N;
- t->printed = 0;
- t->deferwidth = 0;
+
+ // copy new type and clear fields
+ // that don't come along.
+ // anything zeroed here must be zeroed in
+ // typedcl2 too.
+ copytype(n, t);
// double-check use of type as map key.
if(maplineno) {
@@ -197,7 +247,6 @@ Node*
walkdef(Node *n)
{
int lno;
- NodeList *init;
Node *e;
Type *t;
NodeList *l;
@@ -236,7 +285,6 @@ walkdef(Node *n)
if(n->type != T || n->sym == S) // builtin or no name
goto ret;
- init = nil;
switch(n->op) {
default:
fatal("walkdef %O", n->op);
@@ -380,14 +428,13 @@ walkstmt(Node **np)
{
NodeList *init;
NodeList *ll, *rl;
- int cl, lno;
+ int cl;
Node *n, *f;
n = *np;
if(n == N)
return;
- lno = lineno;
setlineno(n);
switch(n->op) {
@@ -1359,7 +1406,7 @@ walkexpr(Node **np, NodeList **init)
case OSTRARRAYBYTE:
// stringtoslicebyte(string) []byte;
- n = mkcall("stringtoslicebyte", n->type, init, n->left);
+ n = mkcall("stringtoslicebyte", n->type, init, conv(n->left, types[TSTRING]));
goto ret;
case OSTRARRAYRUNE:
@@ -1788,7 +1835,7 @@ walkprint(Node *nn, NodeList **init, int defer)
on = syslook("printiface", 1);
argtype(on, n->type); // any-1
}
- } else if(isptr[et] || et == TCHAN || et == TMAP || et == TFUNC) {
+ } else if(isptr[et] || et == TCHAN || et == TMAP || et == TFUNC || et == TUNSAFEPTR) {
if(defer) {
fmtprint(&fmt, "%%p");
} else {