Fix #4137: Keep nint in conditionals with mixed native int branches

When the branches of a conditional have different types, its type falls
back to the IL stack slot type, which is (U)IntPtr. IntroduceNativeIntTypeOnLocals
only retypes variables, so with native integers enabled the branches got
cast to IntPtr. Map (U)IntPtr to n(u)int the same way boxing does; pointer
types are unaffected.
This commit is contained in:
dualfroz committed 2026-10-10 13:50:52 +02:00
1 parent 197acf8cbe
commit 999d3b48fa
2 files changed
+24 -10

No files matched your search

@@ -1825,6 +1825,22 @@ namespace ICSharpCode.Decompiler.CSharp
}
}
IType PreferNativeIntegerType(IType type)
{
if (settings.NativeIntegers)
{
if (type.IsKnownType(KnownTypeCode.IntPtr))
{
return SpecialType.NInt;
}
else if (type.IsKnownType(KnownTypeCode.UIntPtr))
{
return SpecialType.NUInt;
}
}
return type;
}
/// <summary>
/// Gets a type used for performing arithmetic with the stack type and sign.
///
@@ -3525,16 +3541,9 @@ namespace ICSharpCode.Decompiler.CSharp
{
IType targetType = inst.Type;
var arg = Translate(inst.Argument, typeHint: targetType);
if (settings.NativeIntegers && !arg.Type.Equals(targetType))
if (!arg.Type.Equals(targetType))
{
if (targetType.IsKnownType(KnownTypeCode.IntPtr))
{
targetType = SpecialType.NInt;
}
else if (targetType.IsKnownType(KnownTypeCode.UIntPtr))
{
targetType = SpecialType.NUInt;
}
targetType = PreferNativeIntegerType(targetType);
}
arg = arg.ConvertTo(targetType, this);
var obj = compilation.FindType(KnownTypeCode.Object);
@@ -4241,7 +4250,7 @@ namespace ICSharpCode.Decompiler.CSharp
}
else
{
targetType = inst.InferType(compilation);
targetType = PreferNativeIntegerType(inst.InferType(compilation));
}
}
}