Browse Source

Fix `stackalloc char[4]` turning to `stackalloc short[4]`.

pull/4091/head
Daniel Grunwald 1 week ago
parent
commit
fb9ff796da
  1. 1
      .gitignore
  2. 13
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/CS73_StackAllocInitializers.cs
  3. 8
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  4. 2
      ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs

1
.gitignore vendored

@ -22,6 +22,7 @@ ILSpy.Installer/wix/ @@ -22,6 +22,7 @@ ILSpy.Installer/wix/
**/.vscode/
DecompilerTests.config.json
*.trx
report/
# Claude Code local session/skills directory
/.claude/
/.understand-anything

13
ICSharpCode.Decompiler.Tests/TestCases/Pretty/CS73_StackAllocInitializers.cs

@ -332,6 +332,12 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -332,6 +332,12 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
return UseSpan(span);
}
public string GetSpan5()
{
Span<char> span = stackalloc char[4] { '1', '2', '3', '4' };
return UseSpan(span);
}
public void Issue2103a()
{
Span<byte> span = stackalloc byte[3] { 1, 2, 3 };
@ -354,12 +360,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -354,12 +360,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
Console.WriteLine((stackalloc byte[3])[1]);
}
public string UseSpan(Span<int> span)
{
throw new NotImplementedException();
}
public string UseSpan(Span<decimal> span)
public string UseSpan<T>(Span<T> span)
{
throw new NotImplementedException();
}

8
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -586,11 +586,11 @@ namespace ICSharpCode.Decompiler.CSharp @@ -586,11 +586,11 @@ namespace ICSharpCode.Decompiler.CSharp
protected internal override TranslatedExpression VisitLocAllocSpan(LocAllocSpan inst, TranslationContext context)
{
return TranslateLocAllocSpan(inst, context.TypeHint, out _)
return TranslateLocAllocSpan(inst, out _)
.WithILInstruction(inst).WithRR(new ResolveResult(inst.Type));
}
StackAllocExpression TranslateLocAllocSpan(LocAllocSpan inst, IType typeHint, out IType elementType)
StackAllocExpression TranslateLocAllocSpan(LocAllocSpan inst, out IType elementType)
{
elementType = inst.Type.TypeArguments[0];
TranslatedExpression countExpression = Translate(inst.Argument)
@ -3985,6 +3985,8 @@ namespace ICSharpCode.Decompiler.CSharp @@ -3985,6 +3985,8 @@ namespace ICSharpCode.Decompiler.CSharp
{
final = spanCtor.Arguments[0] as LdLoc;
resultType = spanCtor.Method.DeclaringType;
// The following function expects typeHint to be a pointer type.
typeHint = new PointerType(spanCtor.Method.DeclaringType.TypeArguments[0]);
}
if (stloc == null || final == null || stloc.Variable != final.Variable || stloc.Variable.Kind != VariableKind.InitializerTarget)
throw new ArgumentException("given Block is invalid!");
@ -4008,7 +4010,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -4008,7 +4010,7 @@ namespace ICSharpCode.Decompiler.CSharp
stackAllocExpression = TranslateLocAlloc(locAlloc, typeHint, out elementType);
break;
case LocAllocSpan locAllocSpan:
stackAllocExpression = TranslateLocAllocSpan(locAllocSpan, typeHint, out elementType);
stackAllocExpression = TranslateLocAllocSpan(locAllocSpan, out elementType);
break;
default:
throw new ArgumentException("given Block is invalid!");

2
ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs

@ -414,6 +414,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -414,6 +414,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{
if (!initializer.Instructions[0].MatchStLoc(out var initializerVariable, out var value))
return false;
if (!TypeUtils.IsCompatiblePointerTypeForMemoryAccess(initializerVariable.Type, elementType))
return false;
if (!(value.MatchLocAlloc(out sizeInBytes) && MatchesElementCount(sizeInBytes, elementType, newObj.Arguments[1])))
return false;
// The block addresses the allocation through the localloc pointer and only its

Loading…
Cancel
Save