Fix bug 1213453 (GitHub issue #1421): incorrect EH scopes for optimized loops
authorBruce Forstall <brucefo@microsoft.com>
Mon, 24 Aug 2015 18:07:39 +0000 (11:07 -0700)
committerBruce Forstall <brucefo@microsoft.com>
Mon, 24 Aug 2015 18:07:39 +0000 (11:07 -0700)
commitad245f8f4faee15e9045f2d781ce41fa60458058
treee073a333788d03de23360bf9048ef771f7433f03
parent5d8b6c70296a4433745e81eaaff44238abb468bf
Fix bug 1213453 (GitHub issue #1421): incorrect EH scopes for optimized loops

(Port changeset 1518001 from CodeGen)

The bug occurs when fgOptWhileLoop() duplicates a condition from one 'try' region into another, and that condition throws an exception, such as for an array bounds check. This was the test case:

try
{
    Console.WriteLine("try");
}
catch (IndexOutOfRangeException)
{
    Console.WriteLine("bad");
    result = FAIL;
}
while (a[42] != 0) {}

Before the fix, the "a[42] != 0" condition was duplicated into the 'try' region, thus causing an IndexOutOfRange exception to be thrown, and caught in the wrong region.

The main fix is to compare the 'try' region of the region where the condition exists and the region we intend to copy it to. The other changes, in optimizer.cpp and flowgraph.cpp, are "defense in depth" -- to be more careful with EH checks in two very similar optimizations.

This bug existed in AMD64 and ARM32.

There are 2 functions with ARM32 asm diffs.

There are 70 functions with AMD64 SuperAsm diffs.

There are many cases where we prohibit the optimization that caused the bug. There are a few cases where we don't do the optimization but could have if we were more careful about checking for precise EH conditions that are allowed, namely, that branching to the first block of a 'try' region is ok.

[tfs-changeset: 1518014]
src/jit/flowgraph.cpp
src/jit/optimizer.cpp