Browse Source

Fix assertion fail in DeclareVariables: Make sure that we do not try to declare variables in non-assignment contexts.

pull/870/merge
Siegfried Pammer 8 years ago
parent
commit
d45e3bfb3c
  1. 12
      ICSharpCode.Decompiler.Tests/TestCases/Correctness/Patterns.cs
  2. 21
      ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs

12
ICSharpCode.Decompiler.Tests/TestCases/Correctness/Patterns.cs

@ -14,6 +14,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness @@ -14,6 +14,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
static void Main()
{
SimpleUsingNullStatement();
ForWithMultipleVariables();
}
/// <summary>
@ -27,5 +28,16 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness @@ -27,5 +28,16 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
}
Console.WriteLine("after using");
}
public static void ForWithMultipleVariables()
{
int x, y;
Console.WriteLine("before for");
for (x = y = 0; x < 10; x++) {
y++;
Console.WriteLine("x = " + x + ", y = " + y);
}
Console.WriteLine("after for");
}
}
}

21
ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs

@ -312,7 +312,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -312,7 +312,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
// guarantee that it finds only blocks.
// Fix that up now.
while (!(v.InsertionPoint.nextNode.Parent is BlockStatement)) {
if (v.InsertionPoint.nextNode.Parent is ForStatement f && v.InsertionPoint.nextNode == f.Initializers.FirstOrDefault())
if (v.InsertionPoint.nextNode.Parent is ForStatement f && v.InsertionPoint.nextNode == f.Initializers.FirstOrDefault() && IsMatchingAssignment(v, out _))
break;
v.InsertionPoint = v.InsertionPoint.Up();
}
@ -348,6 +348,18 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -348,6 +348,18 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
}
}
bool IsMatchingAssignment(VariableToDeclare v, out AssignmentExpression assignment)
{
assignment = (v.InsertionPoint.nextNode as ExpressionStatement)?.Expression as AssignmentExpression;
Expression expectedExpr = new IdentifierExpression(v.Name);
if (v.Type.Kind == TypeKind.ByReference) {
expectedExpr = new DirectionExpression(FieldDirection.Ref, expectedExpr);
}
if (assignment != null && assignment.Operator == AssignmentOperatorType.Assign && assignment.Left.IsMatch(expectedExpr))
return true;
return false;
}
void InsertVariableDeclarations(TransformContext context)
{
var replacements = new List<KeyValuePair<AstNode, AstNode>>();
@ -356,12 +368,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -356,12 +368,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
if (v.RemovedDueToCollision)
continue;
var assignment = (v.InsertionPoint.nextNode as ExpressionStatement)?.Expression as AssignmentExpression;
Expression expectedExpr = new IdentifierExpression(v.Name);
if (v.Type.Kind == TypeKind.ByReference) {
expectedExpr = new DirectionExpression(FieldDirection.Ref, expectedExpr);
}
if (assignment != null && assignment.Operator == AssignmentOperatorType.Assign && assignment.Left.IsMatch(expectedExpr)) {
if (IsMatchingAssignment(v, out AssignmentExpression assignment)) {
AstType type;
if (context.Settings.AnonymousTypes && v.Type.ContainsAnonymousType()) {
type = new SimpleType("var");

Loading…
Cancel
Save