Commit 6b54cc93 authored by Russ Cox's avatar Russ Cox

cmd/gc: fix internal compiler error in struct compare

Fixes #9006.

LGTM=r
R=r
CC=golang-codereviews
https://golang.org/cl/167800043
parent c88ba199
......@@ -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);
......
// 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")
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment