cmd/gc: fix infinite loop in nil check removal

Fixes #8076.

LGTM=iant
R=golang-codereviews, iant
CC=golang-codereviews
https://golang.org/cl/93610043
This commit is contained in:
Russ Cox 2014-05-27 23:58:49 -04:00
parent 6c0bcb1863
commit daf9308066
2 changed files with 26 additions and 1 deletions

View file

@ -956,7 +956,7 @@ nilwalkback(NilFlow *rcheck)
static void
nilwalkfwd(NilFlow *rcheck)
{
NilFlow *r;
NilFlow *r, *last;
Prog *p;
ProgInfo info;
@ -967,6 +967,7 @@ nilwalkfwd(NilFlow *rcheck)
// avoid problems like:
// _ = *x // should panic
// for {} // no writes but infinite loop may be considered visible
last = nil;
for(r = (NilFlow*)uniqs(&rcheck->f); r != nil; r = (NilFlow*)uniqs(&r->f)) {
p = r->f.prog;
proginfo(&info, p);
@ -989,5 +990,12 @@ nilwalkfwd(NilFlow *rcheck)
// Stop if memory write.
if((info.flags & RightWrite) && !regtyp(&p->to))
return;
// Stop if we jump backward.
// This test is valid because all the NilFlow* are pointers into
// a single contiguous array. We will need to add an explicit
// numbering when the code is converted to Go.
if(last != nil && r <= last)
return;
last = r;
}
}

View file

@ -0,0 +1,17 @@
// compile
// 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.
// Issue 8076. nilwalkfwd walked forward forever
// on the instruction loop following the dereference.
package main
func main() {
_ = *(*int)(nil)
L:
_ = 0
goto L
}