In https://github.com/dotnet/roslyn/pull/4569/files#r37368440 @AlekseyTs noted that we incorrectly treat a "no-op" statement as having side-effects. In the context where the problem occurs, that has the effect of sometimes suppressing the optimization that allows us to elide empty finally blocks, or elide catch blocks when the try block is empty. See case BoundKind.NoOpStatement below, which should return false.
/// <summary>
/// Is there any code to execute in the given statement that could have side-effects,
/// such as throwing an exception? This implementation is conserviative, in the sense
/// that it may return true when the statement actually may have no side effects.
/// </summary>
private static bool HasSideEffects(BoundStatement statement)
{
if (statement == null) return false;
switch (statement.Kind)
{
case BoundKind.NoOpStatement:
return true;
case BoundKind.Block:
{
var block = (BoundBlock)statement;
foreach (var stmt in block.Statements)
{
In https://github.com/dotnet/roslyn/pull/4569/files#r37368440 @AlekseyTs noted that we incorrectly treat a "no-op" statement as having side-effects. In the context where the problem occurs, that has the effect of sometimes suppressing the optimization that allows us to elide empty finally blocks, or elide catch blocks when the try block is empty. See
case BoundKind.NoOpStatementbelow, which shouldreturn false.