or implicit sequence point without creating overlapping sequence points.
If such a location cannot be found do, nothing. Fill in the
gaps with hidden sequence points.
Also emit a sequence point for
the prolog to account for seqeunce point there emitted by the C#
compiler. Without this, the debugger can stop there on a step in
using the original pdb, then decompile resulting in a no-code at this
location failure.
Unreachable code is not part of the dominator tree, which most of our transforms are based on.
In particular, dominance-based loop detection runs into the problem where unreachable code might have jumps into two independent loops. In that case, it's impossible to place the unreachable code in a way that avoids assertions / generating invalid C#.
We establish the invariant that all blocks in a BlockContainer must be statically reachable from the entry point (-> every block is part of the dominator tree). This means transforms no longer have to deal with special cases for unreachable code.
The "Remove dead and side effect free code" option still has an effect on dead stores, but unreachable code is now always removed (previously this also was dependent on this option).
Roslyn re-uses the same "this.Finally(); return v;" block for both "yield break;" instructions, so the yield break pattern needs to support multiple stores to the helper variable.
* remove redundant casts on yield-return-expression
* keep variable name from metadata for foreach loops
* fix 'yield break;' in nested try-finally sometimes causing a decompiler error
This works if all addresses are immediately used in calls (as common with method calls on value-type,
which take 'this' by-reference); as long as the call doesn't return the reference again.
Closes#1136.