diff options
author | Austin Clements <austin@google.com> | 2014-10-22 11:21:16 -0400 |
---|---|---|
committer | Austin Clements <austin@google.com> | 2014-10-22 11:21:16 -0400 |
commit | 2c586384223e980fd3303625ea6b02ed5d9fb9c0 (patch) | |
tree | 54aa72cd9d5eb1566f682d3b0770141a11b54fc2 /src/cmd/gc/walk.c | |
parent | ebe8a09fb603d9510cb982a6c11a3e1638f7f8fb (diff) | |
parent | 45fcda1dc8d9b4d4a9b642faf8e78941873f508d (diff) | |
download | go-2c586384223e980fd3303625ea6b02ed5d9fb9c0.tar.gz |
[dev.power64] build: merge default into dev.power64
LGTM=rsc
R=rsc
CC=golang-codereviews
https://codereview.appspot.com/160200044
Diffstat (limited to 'src/cmd/gc/walk.c')
-rw-r--r-- | src/cmd/gc/walk.c | 105 |
1 files changed, 38 insertions, 67 deletions
diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c index cf25a3eac..365ece267 100644 --- a/src/cmd/gc/walk.c +++ b/src/cmd/gc/walk.c @@ -543,11 +543,11 @@ walkexpr(Node **np, NodeList **init) goto ret; case OPANIC: - n = mkcall("panic", T, init, n->left); + n = mkcall("gopanic", T, init, n->left); goto ret; case ORECOVER: - n = mkcall("recover", n->type, init, nod(OADDR, nodfp, N)); + n = mkcall("gorecover", n->type, init, nod(OADDR, nodfp, N)); goto ret; case OLITERAL: @@ -673,7 +673,7 @@ walkexpr(Node **np, NodeList **init) n1 = nod(OADDR, n->list->n, N); n1->etype = 1; // addr does not escape fn = chanfn("chanrecv2", 2, r->left->type); - r = mkcall1(fn, types[TBOOL], init, typename(r->left->type), r->left, n1); + r = mkcall1(fn, n->list->next->n->type, init, typename(r->left->type), r->left, n1); n = nod(OAS, n->list->next->n, r); typecheck(&n, Etop); goto ret; @@ -723,6 +723,12 @@ walkexpr(Node **np, NodeList **init) var->typecheck = 1; fn = mapfn(p, t); r = mkcall1(fn, getoutargx(fn->type), init, typename(t), r->left, key); + + // mapaccess2* returns a typed bool, but due to spec changes, + // the boolean result of i.(T) is now untyped so we make it the + // same type as the variable on the lhs. + if(!isblank(n->list->next->n)) + r->type->type->down->type = n->list->next->n->type; n->rlist = list1(r); n->op = OAS2FUNC; n->list->n = var; @@ -770,6 +776,12 @@ walkexpr(Node **np, NodeList **init) *p = '\0'; fn = syslook(buf, 1); + + // runtime.assert(E|I)2TOK returns a typed bool, but due + // to spec changes, the boolean result of i.(T) is now untyped + // so we make it the same type as the variable on the lhs. + if(!isblank(n->list->next->n)) + fn->type->type->down->type->type = n->list->next->n->type; ll = list1(typename(r->type)); ll = list(ll, r->left); argtype(fn, r->left->type); @@ -822,9 +834,7 @@ walkexpr(Node **np, NodeList **init) walkexpr(&n->left, init); // Optimize convT2E as a two-word copy when T is uintptr-shaped. - if(!isinter(n->left->type) && isnilinter(n->type) && - (n->left->type->width == widthptr) && - isint[simsimtype(n->left->type)]) { + if(isnilinter(n->type) && isdirectiface(n->left->type) && n->left->type->width == widthptr && isint[simsimtype(n->left->type)]) { l = nod(OEFACE, typename(n->left->type), n->left); l->type = n->type; l->typecheck = n->typecheck; @@ -872,8 +882,7 @@ walkexpr(Node **np, NodeList **init) l->addable = 1; ll = list(ll, l); - if(n->left->type->width == widthptr && - isint[simsimtype(n->left->type)]) { + if(isdirectiface(n->left->type) && n->left->type->width == widthptr && isint[simsimtype(n->left->type)]) { /* For pointer types, we can make a special form of optimization * * These statements are put onto the expression init list: @@ -1828,9 +1837,12 @@ walkprint(Node *nn, NodeList **init, int defer) t = types[TINT64]; } } else { - if(et == TUINT64) - on = syslook("printuint", 0); - else + if(et == TUINT64) { + if((t->sym->pkg == runtimepkg || compiling_runtime) && strcmp(t->sym->name, "hex") == 0) + on = syslook("printhex", 0); + else + on = syslook("printuint", 0); + } else on = syslook("printint", 0); } } else if(isfloat[et]) { @@ -2866,14 +2878,14 @@ sliceany(Node* n, NodeList **init) lb = N; } - // dynamic checks convert all bounds to unsigned to save us the bound < 0 comparison - // generate - // if hb > bound || lb > hb { panicslice() } + // Checking src[lb:hb:cb] or src[lb:hb]. + // if chk0 || chk1 || chk2 { panicslice() } chk = N; - chk0 = N; - chk1 = N; - chk2 = N; + chk0 = N; // cap(src) < cb + chk1 = N; // cb < hb for src[lb:hb:cb]; cap(src) < hb for src[lb:hb] + chk2 = N; // hb < lb + // All comparisons are unsigned to avoid testing < 0. bt = types[simtype[TUINT]]; if(cb != N && cb->type->width > 4) bt = types[TUINT64]; @@ -3013,10 +3025,10 @@ eqfor(Type *t) n = newname(sym); n->class = PFUNC; ntype = nod(OTFUNC, N, N); - ntype->list = list(ntype->list, nod(ODCLFIELD, N, typenod(ptrto(types[TBOOL])))); - ntype->list = list(ntype->list, nod(ODCLFIELD, N, typenod(types[TUINTPTR]))); ntype->list = list(ntype->list, nod(ODCLFIELD, N, typenod(ptrto(t)))); ntype->list = list(ntype->list, nod(ODCLFIELD, N, typenod(ptrto(t)))); + ntype->list = list(ntype->list, nod(ODCLFIELD, N, typenod(types[TUINTPTR]))); + ntype->rlist = list(ntype->rlist, nod(ODCLFIELD, N, typenod(types[TBOOL]))); typecheck(&ntype, Etype); n->type = ntype->type; return n; @@ -3037,10 +3049,9 @@ countfield(Type *t) static void walkcompare(Node **np, NodeList **init) { - Node *n, *l, *r, *fn, *call, *a, *li, *ri, *expr; + Node *n, *l, *r, *call, *a, *li, *ri, *expr; int andor, i; Type *t, *t1; - static Node *tempbool; n = *np; @@ -3058,8 +3069,9 @@ walkcompare(Node **np, NodeList **init) break; } - if(!islvalue(n->left) || !islvalue(n->right)) - goto hard; + if(!islvalue(n->left) || !islvalue(n->right)) { + fatal("arguments of comparison must be lvalues"); + } l = temp(ptrto(t)); a = nod(OAS, l, nod(OADDR, n->left, N)); @@ -3118,57 +3130,16 @@ walkcompare(Node **np, NodeList **init) goto ret; } - // Chose not to inline, but still have addresses. - // Call equality function directly. - // The equality function requires a bool pointer for - // storing its address, because it has to be callable - // from C, and C can't access an ordinary Go return value. - // To avoid creating many temporaries, cache one per function. - if(tempbool == N || tempbool->curfn != curfn) - tempbool = temp(types[TBOOL]); - + // Chose not to inline. Call equality function directly. call = nod(OCALL, eqfor(t), N); - a = nod(OADDR, tempbool, N); - a->etype = 1; // does not escape - call->list = list(call->list, a); - call->list = list(call->list, nodintconst(t->width)); call->list = list(call->list, l); call->list = list(call->list, r); - typecheck(&call, Etop); - walkstmt(&call); - *init = list(*init, call); - - // tempbool cannot be used directly as multiple comparison - // expressions may exist in the same statement. Create another - // temporary to hold the value (its address is not taken so it can - // be optimized away). - r = temp(types[TBOOL]); - a = nod(OAS, r, tempbool); - typecheck(&a, Etop); - walkstmt(&a); - *init = list(*init, a); - + call->list = list(call->list, nodintconst(t->width)); + r = call; if(n->op != OEQ) r = nod(ONOT, r, N); goto ret; -hard: - // Cannot take address of one or both of the operands. - // Instead, pass directly to runtime helper function. - // Easier on the stack than passing the address - // of temporary variables, because we are better at reusing - // the argument space than temporary variable space. - fn = syslook("equal", 1); - l = n->left; - r = n->right; - argtype(fn, n->left->type); - argtype(fn, n->left->type); - r = mkcall1(fn, n->type, init, typename(n->left->type), l, r); - if(n->op == ONE) { - r = nod(ONOT, r, N); - } - goto ret; - ret: typecheck(&r, Erv); walkexpr(&r, init); |