tools/go
Dominik Honnef 5ec23663d0 go/cfg: stop once we've found the fallthrough target
The old code didn't stop after finding the fallthrough target, always
walking the entire list to the top. This would effectively break
fallthroughs, constructing an invalid graph, as the fallthrough target
would never be found.

The fix brings the loop condition in line with all the other
stack-walking loop conditions in the surrounding code, which abort
once the target block has been found.

Alternatively, the entire loop could been omitted, as 'fallthrough'
has to be the last statement in a case body and thus always refers to
the immediate element on the stack. However, since the builder already
handles malformed ASTs as gracefully as possible, it seemed better to
keep the loop and to construct a slightly less wrong graph in the
presence of malformed ASTs.

Before the fix, the following code

	func fn(x int) {
		for {
			switch x {
			case 1:
				println("case 1")
				fallthrough
			case 2:
				println("case 2")
			}
		}
	}

would result in the following graph. Note the presence of an
undefined.branch block.

	.0: # entry
		succs: 1

	.1: # for.body
		x
		1
		succs: 4 6

	.2: # for.done

	.3: # switch.done
		succs: 1

	.4: # switch.body
		println("case 1")
		succs: 7

	.5: # switch.body
		println("case 2")
		succs: 3

	.6: # switch.next
		2
		succs: 5 9

	.7: # undefined.branch

	.8: # unreachable.branch
		succs: 3

	.9: # switch.next
		succs: 3

After the fix, this graph is computed instead:

	.0: # entry
		succs: 1

	.1: # for.body
		x
		1
		succs: 4 6

	.2: # for.done

	.3: # switch.done
		succs: 1

	.4: # switch.body
		println("case 1")
		succs: 5

	.5: # switch.body
		println("case 2")
		succs: 3

	.6: # switch.next
		2
		succs: 5 8

	.7: # unreachable.branch
		succs: 3

	.8: # switch.next
		succs: 3

Change-Id: I3bb00eddec2a7da02cb929860f4c95cf477c848c
Reviewed-on: https://go-review.googlesource.com/c/tools/+/186857
Run-TryBot: Dominik Honnef <dominik@honnef.co>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
2019-07-19 00:04:45 +00:00
..
analysis go/analysis: update internal/facts and unit checker to support all(Package|Object)Facts methods 2019-07-12 16:23:23 +00:00
ast go/ast/inspector: fix a small typo 2019-01-10 14:16:07 +00:00
buildutil go/buildutil: get tests to pass when run from a module 2019-02-14 18:55:18 +00:00
callgraph go/...: use recommended issue tracker URLs 2018-12-05 01:41:16 +00:00
cfg go/cfg: stop once we've found the fallthrough target 2019-07-19 00:04:45 +00:00
expect go/expect: rewrite the expectation parser 2018-11-30 19:57:46 +00:00
gccgoexportdata go/gccgoexportdata: correctly handle archive files containing string tables 2016-11-09 21:28:38 +00:00
gcexportdata go/gcexportdata: fix example test for changes in net/rpc 2019-04-16 18:06:57 +00:00
internal go/internal/gccgoimporter: update package to match std lib version 2019-06-07 13:55:18 +00:00
loader go/loader: normalize cycle to remove flake 2019-07-15 17:29:21 +00:00
packages go/packages, internal/lsp: modify tests to expose overlays bug 2019-07-18 19:31:13 +00:00
pointer go/...: use recommended issue tracker URLs 2018-12-05 01:41:16 +00:00
ssa go/loader: document that package is deprecated 2019-06-24 19:02:45 +00:00
types go/analysis/passes/printf: changes for analysis API 2018-10-16 19:44:49 +00:00
vcs go/vcs: ignore "mod" VCS type 2019-05-06 14:53:03 +00:00