Multiple Issues Decompiling Switch Statements

3 posts, 0 answers
  1. Dave
    Dave avatar
    5 posts
    Member since:
    Aug 2010

    Posted 24 May 2011 Link to this post

    I found multiple issues with C# switch statements in JustDecompile some of which result in invalid C#.

    Consider the following code and assume that SampleEnum only consists of the three values listed:

    public string SampleMethod(SampleEnum enumValue)
    {
        switch (enumValue)
        {
            case SampleEnum.Item1:
                return "Item 1";
      
            case SampleEnum.Item2:
                return "Item 2";
      
            case SampleEnum.Unknown:
                return "Unknown";
        }
      
        return String.Empty;
    }

    JustDecompile produces the following:
    public string SampleMethod(SampleEnum enumValue)
    {
        switch (enumValue)
        {
            case SampleEnum.Unknown:
            {
                return "Unknown";
            }
            case SampleEnum.Item1:
            {
                return "Item 1";
            }
            case SampleEnum.Item2:
            {
                return "Item 2";
            }
        }
        return string.Empty;
    }

    This case could probably be considered ok despite the different sequence of the cases but what observe what happens when we alter the original statement to set a variable rather than return.
    public string SampleMethod(SampleEnum enumValue)
    {
        var val = String.Empty;
      
        switch (enumValue)
        {
            case SampleEnum.Item1:
                val = "Item 1";
                break;
      
            case SampleEnum.Item2:
                    val = "Item 2";
                break;
      
            case SampleEnum.Unknown:
                val = "Unknown";
                break;
        }
      
        return val;
    }

    From this version JustDecompile produces:
    public string SampleMethod(SampleEnum enumValue)
    {
        string empty = string.Empty;
        switch (enumValue)
        {
            case SampleEnum.Unknown:
            {
                empty = "Unknown";
            }
            case SampleEnum.Item1:
            {
                empty = "Item 1";
            }
            case SampleEnum.Item2:
            {
                empty = "Item 2";
            }
        }
        return empty;
    }

    There are two issues here
    1. The generated C# is invalid.  Attempting to compile the generated code will produce the message "error CS0163: Control cannot fall through from one case label ('case 0:') to another"
    2. Although not specific to switch statements the variable name "val" is disregarded (despite being included in the .locals init block of the MSIL) and replaced with the "made-up" name "empty"

    We can throw off JustDecompile even more by introducing a default block like so:

    public string SampleMethod(SampleEnum enumValue)
    {
        var val = String.Empty;
      
        switch (enumValue)
        {
            case SampleEnum.Item1:
                val = "Item 1";
                break;
      
            case SampleEnum.Item2:
                    val = "Item 2";
                break;
      
            default:
                val = "Unknown";
                break;
        }
      
        return val;
    }

    For the above sample JustDecompile produces:
    public string SampleMethod(SampleEnum enumValue)
    {
        string empty = string.Empty;
        switch (enumValue)
        {
            case SampleEnum.Unknown:
            {
                empty = "Item 1";
            }
            case SampleEnum.Item1:
            {
                empty = "Item 2";
            }
            default     :
            {
                empty = "Unknown";
            }
        }
        return empty;
    }

    In addition to the problems listed in the previous example we have the added issue that the first case is using the wrong enum value.  It should be using SampleEnum.Item1 but JustDecompile is incorrectly reporting SampleEnum.Unknown.

    One final "fun trick" I noticed was when a method call is included in the default block JustDecompile is including the MSIL label and corresponding goto statement in the default block.
    public string SampleMethod(SampleEnum enumValue)
    {
        var val = String.Empty;
      
        switch (enumValue)
        {
            case SampleEnum.Item1:
                val = "Item 1";
                break;
      
            case SampleEnum.Item2:
                val = "Item 2";
                break;
      
            default:
                Console.WriteLine("Unknown");
                break;
        }
      
        return val;
    }

    Results in:
    public string SampleMethod(SampleEnum enumValue)
    {
        string empty = string.Empty;
        switch (enumValue)
        {
            case SampleEnum.Unknown:
            {
                empty = "Item 1";
            }
            case SampleEnum.Item1:
            {
                empty = "Item 2";
            }
            default     :
            {
                Console.WriteLine("Unknown");
                goto L_0038;
            }
        }
    L_0038:
        return empty;
    }
  2. Chris
    Admin
    Chris avatar
    221 posts

    Posted 27 May 2011 Link to this post

    Hi Dave,
    Thanks a lot for the detailed feedback and sorry for the inconvenience caused. All these problems have been logged and will be fixed for the official version (in July) or even earlier in some of the next internal builds.
    I've added some Telerik points to your account to compensate you for your efforts.

    Regards,
    Chris
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get now >>

  3. DevCraft banner
  4. Dave
    Dave avatar
    5 posts
    Member since:
    Aug 2010

    Posted 27 May 2011 Link to this post

    Thanks, Chris - I appreciate the gesture.  Telerik is a great company and I'd love to see JustDecompile reach the level of quality I've come to expect.  I'm looking forward to trying out a later version.
Back to Top