From daf9308066a71802ed723ba96459afe2558c62d9 Mon Sep 17 00:00:00 2001
From: Russ Cox <rsc@golang.org>
Date: Tue, 27 May 2014 23:58:49 -0400
Subject: [PATCH] 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
---
 src/cmd/gc/popt.c           | 10 +++++++++-
 test/fixedbugs/issue8076.go | 17 +++++++++++++++++
 2 files changed, 26 insertions(+), 1 deletion(-)
 create mode 100644 test/fixedbugs/issue8076.go

diff --git a/src/cmd/gc/popt.c b/src/cmd/gc/popt.c
index d724637677..ea88b94dbe 100644
--- a/src/cmd/gc/popt.c
+++ b/src/cmd/gc/popt.c
@@ -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;
 	}
 }
diff --git a/test/fixedbugs/issue8076.go b/test/fixedbugs/issue8076.go
new file mode 100644
index 0000000000..ad89067753
--- /dev/null
+++ b/test/fixedbugs/issue8076.go
@@ -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
+}
-- 
2.30.9