From 2393d1614736eb3ece950d6dd70883120237e209 Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Wed, 28 Aug 2019 12:56:26 -0700 Subject: [PATCH] cmd/compile: handle infinite loops in shortcircuit pass The newly upgraded shortcircuit pass attempted to remove infinite loops. Stop doing that. Fixes #33903 Change-Id: I0fc9c1b5f2427e54ce650806602ef5e3ad65aca5 Reviewed-on: https://go-review.googlesource.com/c/go/+/192144 Run-TryBot: Josh Bleecher Snyder TryBot-Result: Gobot Gobot Reviewed-by: Keith Randall --- src/cmd/compile/internal/ssa/shortcircuit.go | 10 ++++++++-- test/fixedbugs/issue33903.go | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 test/fixedbugs/issue33903.go diff --git a/src/cmd/compile/internal/ssa/shortcircuit.go b/src/cmd/compile/internal/ssa/shortcircuit.go index e881a4cf1e..5bf0888043 100644 --- a/src/cmd/compile/internal/ssa/shortcircuit.go +++ b/src/cmd/compile/internal/ssa/shortcircuit.go @@ -50,7 +50,7 @@ func shortcircuit(f *Func) { } } - // Step 3: Redirect control flow around known branches. + // Step 2: Redirect control flow around known branches. // p: // ... goto b ... // b: <- p ... @@ -124,7 +124,6 @@ func shortcircuitBlock(b *Block) bool { if a.Op != OpConstBool { continue } - changed = true // The predecessor we come in from. e1 := b.Preds[i] p := e1.b @@ -138,8 +137,15 @@ func shortcircuitBlock(b *Block) bool { } e2 := b.Succs[si] t := e2.b + if p == b || t == b { + // This is an infinite loop; we can't remove it. See issue 33903. + continue + } ti := e2.i + // Update CFG and Phis. + changed = true + // Remove b's incoming edge from p. b.removePred(i) n := len(b.Preds) diff --git a/test/fixedbugs/issue33903.go b/test/fixedbugs/issue33903.go new file mode 100644 index 0000000000..de03282264 --- /dev/null +++ b/test/fixedbugs/issue33903.go @@ -0,0 +1,16 @@ +// compile + +// Copyright 2019 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. + +// Check that the shortcircuit pass correctly handles infinite loops. + +package p + +func f() { + var p, q bool + for { + p = p && q + } +} -- 2.50.0