Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VB -> C#: Select Case [object] can have incorrect converted code #1100

Open
TymurGubayev opened this issue May 2, 2024 · 0 comments
Open
Labels
output logic error A bug where the converted output behaves differently to the input code VB -> C# Specific to VB -> C# conversion

Comments

@TymurGubayev
Copy link
Contributor

TymurGubayev commented May 2, 2024

VB.Net input code

Option Strict Off

Public Class TestSelectObjectCaseInt
    Enum E
        A
        B
        C
    End Enum
    Shared Sub Test()
        Dim o As Object
        Dim j As Integer

        o = E.C
        Select Case o
            Case 1
                j = 1
            Case 2
                j = 2
            Case Else
                j = -1
        End Select
        System.Diagnostics.Debug.Assert(j = 2)
    End Sub
End Class

Erroneous output

public class TestSelectObjectCaseInt
{
    public enum E
    {
        A,
        B,
        C
    }
    public static void Test()
    {
        object o;
        int j;

        o = E.C;
        switch (o)
        {
            case 1:
                {
                    j = 1;
                    break;
                }

            case 2:
                {
                    j = 2;
                    break;
                }

            default:
                {
                    j = -1;
                    break;
                }
        }
        System.Diagnostics.Debug.Assert(j == 2);
    }
}

Expected output

public class TestSelectObjectCaseInt
{
    public enum E
    {
        A,
        B,
        C
    }
    public static void Test()
    {
        object o;
        int j;

        o = E.C;
        switch (o is int ? (int)o : o)
        {
            case 1:
                {
                    j = 1;
                    break;
                }

            case 2:
                {
                    j = 2;
                    break;
                }

            default:
                {
                    j = -1;
                    break;
                }
        }
        System.Diagnostics.Debug.Assert(j == 2);
    }
}

Note with Option Strict On the VB.NET example doesn't compile.
The issue is, in C# default branch is executed.
Cast to int (=type of the cases) fixes it.

Changing the expression into (int)o can result in runtime errors in case the object can't be converted to an int, which would be better than executing wrong branch without errors.
On the other hand, something like (o is int ? (int)o : o) would work correctly (I thinkmost of the time*), but would require introducing temporary variable (in case o is a property, an invocation, or an index access - do I have them all?)

*) o = "2" is same as 2, which is a problem. The code decompiled to C# uses Operators.ConditionalCompareObjectEqual(o, 1, false)

Details

  • Product in use: VS extension
  • Version in use: 5143c08
  • Did you see it working in a previous version, which? no
  • Any other relevant information to the issue, or your interest in contributing a fix.
@TymurGubayev TymurGubayev added the VB -> C# Specific to VB -> C# conversion label May 2, 2024
@GrahamTheCoder GrahamTheCoder added the output logic error A bug where the converted output behaves differently to the input code label May 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
output logic error A bug where the converted output behaves differently to the input code VB -> C# Specific to VB -> C# conversion
Projects
None yet
Development

No branches or pull requests

2 participants