dubiousconst282/DistIL

Protected regions may sometimes lead to bad codegen

Closed this issue · 0 comments

Initial support for emitting protected regions was introduced in 2e6d632, with several bugs:

  1. Fix importing/IR generation for nested exception regions
  2. Separate unprotected blocks from nested regions when generating CFG layout. This issue results in e.g. ret instructions inside protected blocks.

This might require changes in the IR (maybe we can just split blocks to avoid case 1, but are leave instructions enough?).

Repros:

//Case 1 (the decompiled output swaps the code from the two methods, but the IL is actually invalid.)
public static void Try5(int[] a, int i) {
    try {
        Console.WriteLine("Try");
    } catch (InvalidOperationException) {
        Console.WriteLine("Catch");
    } finally {
        Console.WriteLine("Finally");
    }
}
public static void Try6(int[] a, int i) {
    try {
        try {
            Console.WriteLine("Try");
        } finally {
            Console.WriteLine("Finally");
        }
    } catch (InvalidOperationException) {
        Console.WriteLine("Catch");
    }
}
public static void Try8(int[] a, int i) {
    try {
        try {
            Console.WriteLine("A");
        } catch (InvalidOperationException) {
            Console.WriteLine("B");
        }
        Console.WriteLine("C");
    } catch (NullReferenceException) {
        Console.WriteLine("D");
    }
}

//For case 2 (ret added before finally block)
public static void Try7(int[] a, int i) {
    try {
        Console.WriteLine("Finally-Wrap");
        try {
            Console.WriteLine("Try");
        } catch (InvalidOperationException) {
            Console.WriteLine("Catch");
        }
    } finally {
        Console.WriteLine("Finally");
    }
}