]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gc: fix internal compiler error in struct compare
authorRuss Cox <rsc@golang.org>
Wed, 29 Oct 2014 03:22:46 +0000 (23:22 -0400)
committerRuss Cox <rsc@golang.org>
Wed, 29 Oct 2014 03:22:46 +0000 (23:22 -0400)
Fixes #9006.

LGTM=r
R=r
CC=golang-codereviews
https://golang.org/cl/167800043

src/cmd/gc/walk.c
test/fixedbugs/issue9006.go [new file with mode: 0644]

index e5f22179701e661480feeee0f816fedd314beabb..2986f4b542312ac0ec6b40bfb4b56a2c25f006fb 100644 (file)
@@ -3157,7 +3157,7 @@ countfield(Type *t)
 static void
 walkcompare(Node **np, NodeList **init)
 {
-       Node *n, *l, *r, *call, *a, *li, *ri, *expr;
+       Node *n, *l, *r, *call, *a, *li, *ri, *expr, *cmpl, *cmpr;
        int andor, i;
        Type *t, *t1;
        
@@ -3177,18 +3177,25 @@ walkcompare(Node **np, NodeList **init)
                break;
        }
        
-       if(!islvalue(n->left) || !islvalue(n->right)) {
-               fatal("arguments of comparison must be lvalues");
+       cmpl = n->left;
+       while(cmpl != N && cmpl->op == OCONVNOP)
+               cmpl = cmpl->left;
+       cmpr = n->right;
+       while(cmpr != N && cmpr->op == OCONVNOP)
+               cmpr = cmpr->left;
+       
+       if(!islvalue(cmpl) || !islvalue(cmpr)) {
+               fatal("arguments of comparison must be lvalues - %N %N", cmpl, cmpr);
        }
 
        l = temp(ptrto(t));
-       a = nod(OAS, l, nod(OADDR, n->left, N));
+       a = nod(OAS, l, nod(OADDR, cmpl, N));
        a->right->etype = 1;  // addr does not escape
        typecheck(&a, Etop);
        *init = list(*init, a);
 
        r = temp(ptrto(t));
-       a = nod(OAS, r, nod(OADDR, n->right, N));
+       a = nod(OAS, r, nod(OADDR, cmpr, N));
        a->right->etype = 1;  // addr does not escape
        typecheck(&a, Etop);
        *init = list(*init, a);
diff --git a/test/fixedbugs/issue9006.go b/test/fixedbugs/issue9006.go
new file mode 100644 (file)
index 0000000..c559f58
--- /dev/null
@@ -0,0 +1,37 @@
+// run
+
+// Copyright 2014 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 main
+
+type T1 struct {
+       X int
+}
+
+func NewT1(x int) T1 { return T1{x} }
+
+type T2 int
+
+func NewT2(x int) T2 { return T2(x) }
+
+func main() {
+       switch (T1{}) {
+       case NewT1(1):
+               panic("bad1")
+       case NewT1(0):
+               // ok
+       default:
+               panic("bad2")
+       }
+
+       switch T2(0) {
+       case NewT2(2):
+               panic("bad3")
+       case NewT2(0):
+               // ok
+       default:
+               panic("bad4")
+       }
+}