]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gc: unbreak exporting of composite literals.
authorRémy Oudompheng <oudomphe@phare.normalesup.org>
Mon, 4 Mar 2013 15:42:03 +0000 (16:42 +0100)
committerRémy Oudompheng <oudomphe@phare.normalesup.org>
Mon, 4 Mar 2013 15:42:03 +0000 (16:42 +0100)
Fixes #4932.

R=golang-dev, dave, rsc
CC=golang-dev
https://golang.org/cl/7437043

src/cmd/gc/fmt.c
src/cmd/gc/go.h
src/cmd/gc/subr.c
src/cmd/gc/typecheck.c
test/fixedbugs/issue4932.dir/foo.go [new file with mode: 0644]
test/fixedbugs/issue4932.dir/state.go [new file with mode: 0644]
test/fixedbugs/issue4932.dir/state2.go [new file with mode: 0644]
test/fixedbugs/issue4932.go [new file with mode: 0644]

index 64eb196928bcd2e38a7c254aefcbb3573463717f..ab81e6c887ac47c6ab65aa6d1aa0b32f7a42c9f2 100644 (file)
@@ -1091,6 +1091,7 @@ static int
 exprfmt(Fmt *f, Node *n, int prec)
 {
        int nprec;
+       int ptrlit;
        NodeList *l;
 
        while(n && n->implicit && (n->op == OIND || n->op == OADDR))
@@ -1201,12 +1202,23 @@ exprfmt(Fmt *f, Node *n, int prec)
                return fmtprint(f, "%T { %H }", n->type, n->closure->nbody);
 
        case OCOMPLIT:
-               if(fmtmode == FErr)
+               ptrlit = n->right != N && n->right->implicit && n->right->type && isptr[n->right->type->etype];
+               if(fmtmode == FErr) {
+                       if(n->right != N && n->right->type != T && !n->implicit) {
+                               if(ptrlit)
+                                       return fmtprint(f, "&%T literal", n->right->type->type);
+                               else
+                                       return fmtprint(f, "%T literal", n->right->type);
+                       }
                        return fmtstrcpy(f, "composite literal");
+               }
+               if(fmtmode == FExp && ptrlit)
+                       // typecheck has overwritten OIND by OTYPE with pointer type.
+                       return fmtprint(f, "&%T{ %,H }", n->right->type->type, n->list);
                return fmtprint(f, "(%N{ %,H })", n->right, n->list);
 
        case OPTRLIT:
-               if(fmtmode == FExp)  // handle printing of '&' below.
+               if(fmtmode == FExp && n->left->implicit)
                        return fmtprint(f, "%N", n->left);
                return fmtprint(f, "&%N", n->left);
 
@@ -1214,8 +1226,6 @@ exprfmt(Fmt *f, Node *n, int prec)
                if(fmtmode == FExp) {   // requires special handling of field names
                        if(n->implicit)
                                fmtstrcpy(f, "{");
-                       else if(n->right->implicit)
-                               fmtprint(f, "&%T{", n->type);
                        else
                                fmtprint(f, "(%T{", n->type);
                        for(l=n->list; l; l=l->next) {
@@ -1226,7 +1236,7 @@ exprfmt(Fmt *f, Node *n, int prec)
                                else
                                        fmtstrcpy(f, " ");
                        }
-                       if(!n->implicit && !n->right->implicit)
+                       if(!n->implicit)
                                return fmtstrcpy(f, "})");
                        return fmtstrcpy(f, "}");
                }
@@ -1238,13 +1248,16 @@ exprfmt(Fmt *f, Node *n, int prec)
                        return fmtprint(f, "%T literal", n->type);
                if(fmtmode == FExp && n->implicit)
                        return fmtprint(f, "{ %,H }", n->list);
-               if(fmtmode == FExp && n->right->implicit)
-                       return fmtprint(f, "&%T{ %,H }", n->type, n->list);
                return fmtprint(f, "(%T{ %,H })", n->type, n->list);
 
        case OKEY:
-               if(n->left && n->right)
-                       return fmtprint(f, "%N:%N", n->left, n->right);
+               if(n->left && n->right) {
+                       if(fmtmode == FExp && n->left->type && n->left->type->etype == TFIELD) {
+                               // requires special handling of field names
+                               return fmtprint(f, "%hhS:%N", n->left->sym, n->right);
+                       } else
+                               return fmtprint(f, "%N:%N", n->left, n->right);
+               }
                if(!n->left && n->right)
                        return fmtprint(f, ":%N", n->right);
                if(n->left && !n->right)
index 4da7a03ac2da9c99cadb6ed160e1f36f997ad13d..f86c152f2cbcbe5feeff6e360abb77ce73dc2f53 100644 (file)
@@ -1325,6 +1325,7 @@ Node*     safeexpr(Node *n, NodeList **init);
 void   saveerrors(void);
 Node*  cheapexpr(Node *n, NodeList **init);
 Node*  localexpr(Node *n, Type *t, NodeList **init);
+void   saveorignode(Node *n);
 int32  setlineno(Node *n);
 void   setmaxarg(Type *t);
 Type*  shallow(Type *t);
index db8b17014568b6d1daa5cdb695d5dd83cced275f..c53eaf28576447984460529eee4a382ac35f51bf 100644 (file)
@@ -513,6 +513,18 @@ nod(int op, Node *nleft, Node *nright)
        return n;
 }
 
+void
+saveorignode(Node *n)
+{
+       Node *norig;
+
+       if(n->orig != N)
+               return;
+       norig = nod(n->op, N, N);
+       *norig = *n;
+       n->orig = norig;
+}
+
 // ispaddedfield returns whether the given field
 // is followed by padding. For the case where t is
 // the last field, total gives the size of the enclosing struct.
@@ -1416,7 +1428,7 @@ assignconv(Node *n, Type *t, char *context)
        r->type = t;
        r->typecheck = 1;
        r->implicit = 1;
-       r->orig = n;
+       r->orig = n->orig;
        return r;
 }
 
index 63ad4a92eb25115d6a0c08ea849744c59adf9c7e..0889b92f8187c5c1557e691d2b2adfdf676030b7 100644 (file)
@@ -1340,9 +1340,7 @@ reswitch:
        case OCONV:
        doconv:
                ok |= Erv;
-               l = nod(OXXX, N, N);
-               n->orig = l;
-               *l = *n;
+               saveorignode(n);
                typecheck(&n->left, Erv | (top & (Eindir | Eiota)));
                convlit1(&n->left, n->type, 1);
                if((t = n->left->type) == T || n->type == T)
@@ -2322,7 +2320,7 @@ static void
 typecheckcomplit(Node **np)
 {
        int bad, i, len, nerr;
-       Node *l, *n, *r, **hash;
+       Node *l, *n, *norig, *r, **hash;
        NodeList *ll;
        Type *t, *f;
        Sym *s, *s1;
@@ -2339,14 +2337,18 @@ typecheckcomplit(Node **np)
                yyerror("missing type in composite literal");
                goto error;
        }
-       
+
+       // Save original node (including n->right)
+       norig = nod(n->op, N, N);
+       *norig = *n;
+
        setlineno(n->right);
        l = typecheck(&n->right /* sic */, Etype|Ecomplit);
        if((t = l->type) == T)
                goto error;
        nerr = nerrors;
        n->type = t;
-       
+
        if(isptr[t->etype]) {
                // For better or worse, we don't allow pointers as the composite literal type,
                // except when using the &T syntax, which sets implicit on the OIND.
@@ -2413,9 +2415,6 @@ typecheckcomplit(Node **np)
                if(t->bound < 0)
                        n->right = nodintconst(len);
                n->op = OARRAYLIT;
-               // restore implicitness.
-               if(isptr[n->type->etype])
-                       n->right->implicit = 1;
                break;
 
        case TMAP:
@@ -2520,6 +2519,7 @@ typecheckcomplit(Node **np)
        if(nerr != nerrors)
                goto error;
        
+       n->orig = norig;
        if(isptr[n->type->etype]) {
                n = nod(OPTRLIT, n, N);
                n->typecheck = 1;
@@ -2528,6 +2528,7 @@ typecheckcomplit(Node **np)
                n->left->typecheck = 1;
        }
 
+       n->orig = norig;
        *np = n;
        lineno = lno;
        return;
diff --git a/test/fixedbugs/issue4932.dir/foo.go b/test/fixedbugs/issue4932.dir/foo.go
new file mode 100644 (file)
index 0000000..19b73a0
--- /dev/null
@@ -0,0 +1,7 @@
+// Copyright 2013 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 foo
+
+type Op struct{}
diff --git a/test/fixedbugs/issue4932.dir/state.go b/test/fixedbugs/issue4932.dir/state.go
new file mode 100644 (file)
index 0000000..c017b96
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright 2013 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 state
+
+import "./foo"
+
+func Public() {
+       var s Settings
+       s.op()
+}
+
+type State struct{}
+
+func (s *State) x(*Settings) {}
+
+type Settings struct{}
+
+func (c *Settings) x() {
+       run([]foo.Op{{}})
+}
+
+func run([]foo.Op) {}
+
+func (s *Settings) op() foo.Op {
+       return foo.Op{}
+}
diff --git a/test/fixedbugs/issue4932.dir/state2.go b/test/fixedbugs/issue4932.dir/state2.go
new file mode 100644 (file)
index 0000000..50f75db
--- /dev/null
@@ -0,0 +1,9 @@
+// Copyright 2013 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 state2
+
+import "./state"
+
+type Foo *state.State
diff --git a/test/fixedbugs/issue4932.go b/test/fixedbugs/issue4932.go
new file mode 100644 (file)
index 0000000..2a6bc69
--- /dev/null
@@ -0,0 +1,9 @@
+// compiledir
+
+// Copyright 2013 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 4932: regression in export of composite literals.
+
+package ignored