1
0
mirror of https://github.com/golang/go synced 2024-11-11 20:50:23 -07:00

cmd/gc: do not lower copy to a value node in go/defer.

The existing tests issue4463.go and issue4654.go had failures at
typechecking and did not test walking the AST.

Fixes #7272.

LGTM=khr
R=khr, rsc, iant
CC=golang-codereviews
https://golang.org/cl/60550044
This commit is contained in:
Rémy Oudompheng 2014-02-15 16:39:04 +01:00
parent 71575a97ab
commit 15d294991f
2 changed files with 69 additions and 16 deletions

View File

@ -21,7 +21,7 @@ static NodeList* reorder3(NodeList*);
static Node* addstr(Node*, NodeList**);
static Node* appendslice(Node*, NodeList**);
static Node* append(Node*, NodeList**);
static Node* copyany(Node*, NodeList**);
static Node* copyany(Node*, NodeList**, int);
static Node* sliceany(Node*, NodeList**);
static void walkcompare(Node**, NodeList**);
static void walkrotate(Node**);
@ -223,6 +223,9 @@ walkstmt(Node **np)
walkexprlist(n->left->list, &n->ninit);
n->left = walkprint(n->left, &n->ninit, 1);
break;
case OCOPY:
n->left = copyany(n->left, &n->ninit, 1);
break;
default:
walkexpr(&n->left, &n->ninit);
break;
@ -254,6 +257,9 @@ walkstmt(Node **np)
walkexprlist(n->left->list, &n->ninit);
n->left = walkprint(n->left, &n->ninit, 1);
break;
case OCOPY:
n->left = copyany(n->left, &n->ninit, 1);
break;
default:
walkexpr(&n->left, &n->ninit);
break;
@ -1311,19 +1317,7 @@ walkexpr(Node **np, NodeList **init)
goto ret;
case OCOPY:
if(flag_race) {
if(n->right->type->etype == TSTRING)
fn = syslook("slicestringcopy", 1);
else
fn = syslook("copy", 1);
argtype(fn, n->left->type);
argtype(fn, n->right->type);
n = mkcall1(fn, n->type, init,
n->left, n->right,
nodintconst(n->left->type->type->width));
goto ret;
}
n = copyany(n, init);
n = copyany(n, init, flag_race);
goto ret;
case OCLOSE:
@ -2821,7 +2815,7 @@ append(Node *n, NodeList **init)
return ns;
}
// Lower copy(a, b) to a memmove call.
// Lower copy(a, b) to a memmove call or a runtime call.
//
// init {
// n := len(a)
@ -2833,11 +2827,22 @@ append(Node *n, NodeList **init)
// Also works if b is a string.
//
static Node*
copyany(Node *n, NodeList **init)
copyany(Node *n, NodeList **init, int runtimecall)
{
Node *nl, *nr, *nfrm, *nto, *nif, *nlen, *nwid, *fn;
NodeList *l;
if(runtimecall) {
if(n->right->type->etype == TSTRING)
fn = syslook("slicestringcopy", 1);
else
fn = syslook("copy", 1);
argtype(fn, n->left->type);
argtype(fn, n->right->type);
return mkcall1(fn, n->type, init,
n->left, n->right,
nodintconst(n->left->type->type->width));
}
walkexpr(&n->left, init);
walkexpr(&n->right, init);
nl = temp(n->left->type);

View File

@ -0,0 +1,48 @@
// compile
// Copyright 2012 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.
// Issue 7272: test builtin functions in statement context and in
// go/defer functions.
package p
func F() {
var a []int
var c chan int
var m map[int]int
close(c)
copy(a, a)
delete(m, 0)
panic(0)
print("foo")
println("bar")
recover()
(close(c))
(copy(a, a))
(delete(m, 0))
(panic(0))
(print("foo"))
(println("bar"))
(recover())
go close(c)
go copy(a, a)
go delete(m, 0)
go panic(0)
go print("foo")
go println("bar")
go recover()
defer close(c)
defer copy(a, a)
defer delete(m, 0)
defer panic(0)
defer print("foo")
defer println("bar")
defer recover()
}