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

Fix: ensure the value in range #828

Merged
merged 14 commits into from
Dec 15, 2023
Merged
26 changes: 26 additions & 0 deletions src/Neo.Compiler.CSharp/MethodConvert.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2848,6 +2848,7 @@ private void ConvertElementAccessPostIncrementOrDecrementExpression(SemanticMode
AddInstruction(OpCode.REVERSE4);
AddInstruction(OpCode.REVERSE3);
EmitIncrementOrDecrement(operatorToken);
EnsureIntegerInRange(property.Type);
Call(model, property.SetMethod!, CallingConvention.StdCall);
}
else
Expand All @@ -2861,6 +2862,8 @@ private void ConvertElementAccessPostIncrementOrDecrementExpression(SemanticMode
AddInstruction(OpCode.REVERSE4);
AddInstruction(OpCode.REVERSE3);
EmitIncrementOrDecrement(operatorToken);
var typeSymbol = model.GetTypeInfo(operand).Type;
if (typeSymbol != null) EnsureIntegerInRange(typeSymbol);
AddInstruction(OpCode.SETITEM);
}
}
Expand Down Expand Up @@ -2895,6 +2898,7 @@ private void ConvertFieldIdentifierNamePostIncrementOrDecrementExpression(Syntax
AccessSlot(OpCode.LDSFLD, index);
AddInstruction(OpCode.DUP);
EmitIncrementOrDecrement(operatorToken);
EnsureIntegerInRange(symbol.Type);
AccessSlot(OpCode.STSFLD, index);
}
else
Expand All @@ -2906,6 +2910,7 @@ private void ConvertFieldIdentifierNamePostIncrementOrDecrementExpression(Syntax
AddInstruction(OpCode.PICKITEM);
AddInstruction(OpCode.TUCK);
EmitIncrementOrDecrement(operatorToken);
EnsureIntegerInRange(symbol.Type);
Push(index);
AddInstruction(OpCode.SWAP);
AddInstruction(OpCode.SETITEM);
Expand All @@ -2918,6 +2923,7 @@ private void ConvertLocalIdentifierNamePostIncrementOrDecrementExpression(Syntax
AccessSlot(OpCode.LDLOC, index);
AddInstruction(OpCode.DUP);
EmitIncrementOrDecrement(operatorToken);
EnsureIntegerInRange(symbol.Type);
AccessSlot(OpCode.STLOC, index);
}

Expand All @@ -2927,6 +2933,7 @@ private void ConvertParameterIdentifierNamePostIncrementOrDecrementExpression(Sy
AccessSlot(OpCode.LDARG, index);
AddInstruction(OpCode.DUP);
EmitIncrementOrDecrement(operatorToken);
EnsureIntegerInRange(symbol.Type);
AccessSlot(OpCode.STARG, index);
}

Expand All @@ -2937,6 +2944,7 @@ private void ConvertPropertyIdentifierNamePostIncrementOrDecrementExpression(Sem
Call(model, symbol.GetMethod!);
AddInstruction(OpCode.DUP);
EmitIncrementOrDecrement(operatorToken);
EnsureIntegerInRange(symbol.Type);
Call(model, symbol.SetMethod!);
}
else
Expand All @@ -2946,6 +2954,7 @@ private void ConvertPropertyIdentifierNamePostIncrementOrDecrementExpression(Sem
Call(model, symbol.GetMethod!);
AddInstruction(OpCode.TUCK);
EmitIncrementOrDecrement(operatorToken);
EnsureIntegerInRange(symbol.Type);
Call(model, symbol.SetMethod!, CallingConvention.StdCall);
}
}
Expand Down Expand Up @@ -2974,6 +2983,7 @@ private void ConvertFieldMemberAccessPostIncrementOrDecrementExpression(Semantic
AccessSlot(OpCode.LDSFLD, index);
AddInstruction(OpCode.DUP);
EmitIncrementOrDecrement(operatorToken);
EnsureIntegerInRange(symbol.Type);
AccessSlot(OpCode.STSFLD, index);
}
else
Expand All @@ -2985,6 +2995,7 @@ private void ConvertFieldMemberAccessPostIncrementOrDecrementExpression(Semantic
AddInstruction(OpCode.PICKITEM);
AddInstruction(OpCode.TUCK);
EmitIncrementOrDecrement(operatorToken);
EnsureIntegerInRange(symbol.Type);
Push(index);
AddInstruction(OpCode.SWAP);
AddInstruction(OpCode.SETITEM);
Expand All @@ -2998,6 +3009,7 @@ private void ConvertPropertyMemberAccessPostIncrementOrDecrementExpression(Seman
Call(model, symbol.GetMethod!);
AddInstruction(OpCode.DUP);
EmitIncrementOrDecrement(operatorToken);
EnsureIntegerInRange(symbol.Type);
Call(model, symbol.SetMethod!);
}
else
Expand All @@ -3007,6 +3019,7 @@ private void ConvertPropertyMemberAccessPostIncrementOrDecrementExpression(Seman
Call(model, symbol.GetMethod!);
AddInstruction(OpCode.TUCK);
EmitIncrementOrDecrement(operatorToken);
EnsureIntegerInRange(symbol.Type);
Call(model, symbol.SetMethod!, CallingConvention.StdCall);
}
}
Expand Down Expand Up @@ -3075,6 +3088,7 @@ private void ConvertElementAccessPreIncrementOrDecrementExpression(SemanticModel
AddInstruction(OpCode.OVER);
Call(model, property.GetMethod!, CallingConvention.StdCall);
EmitIncrementOrDecrement(operatorToken);
EnsureIntegerInRange(property.Type);
AddInstruction(OpCode.DUP);
AddInstruction(OpCode.REVERSE4);
Call(model, property.SetMethod!, CallingConvention.Cdecl);
Expand All @@ -3087,6 +3101,8 @@ private void ConvertElementAccessPreIncrementOrDecrementExpression(SemanticModel
AddInstruction(OpCode.OVER);
AddInstruction(OpCode.PICKITEM);
EmitIncrementOrDecrement(operatorToken);
var typeSymbol = model.GetTypeInfo(operand).Type;
if (typeSymbol != null) EnsureIntegerInRange(typeSymbol);
AddInstruction(OpCode.DUP);
AddInstruction(OpCode.REVERSE4);
AddInstruction(OpCode.REVERSE3);
Expand Down Expand Up @@ -3123,6 +3139,7 @@ private void ConvertFieldIdentifierNamePreIncrementOrDecrementExpression(SyntaxT
byte index = context.AddStaticField(symbol);
AccessSlot(OpCode.LDSFLD, index);
EmitIncrementOrDecrement(operatorToken);
EnsureIntegerInRange(symbol.Type);
AddInstruction(OpCode.DUP);
AccessSlot(OpCode.STSFLD, index);
}
Expand All @@ -3134,6 +3151,7 @@ private void ConvertFieldIdentifierNamePreIncrementOrDecrementExpression(SyntaxT
Push(index);
AddInstruction(OpCode.PICKITEM);
EmitIncrementOrDecrement(operatorToken);
EnsureIntegerInRange(symbol.Type);
AddInstruction(OpCode.TUCK);
Push(index);
AddInstruction(OpCode.SWAP);
Expand All @@ -3146,6 +3164,7 @@ private void ConvertLocalIdentifierNamePreIncrementOrDecrementExpression(SyntaxT
byte index = _localVariables[symbol];
AccessSlot(OpCode.LDLOC, index);
EmitIncrementOrDecrement(operatorToken);
EnsureIntegerInRange(symbol.Type);
AddInstruction(OpCode.DUP);
AccessSlot(OpCode.STLOC, index);
}
Expand All @@ -3155,6 +3174,7 @@ private void ConvertParameterIdentifierNamePreIncrementOrDecrementExpression(Syn
byte index = _parameters[symbol];
AccessSlot(OpCode.LDARG, index);
EmitIncrementOrDecrement(operatorToken);
EnsureIntegerInRange(symbol.Type);
AddInstruction(OpCode.DUP);
AccessSlot(OpCode.STARG, index);
}
Expand All @@ -3165,6 +3185,7 @@ private void ConvertPropertyIdentifierNamePreIncrementOrDecrementExpression(Sema
{
Call(model, symbol.GetMethod!);
EmitIncrementOrDecrement(operatorToken);
EnsureIntegerInRange(symbol.Type);
AddInstruction(OpCode.DUP);
Call(model, symbol.SetMethod!);
}
Expand All @@ -3174,6 +3195,7 @@ private void ConvertPropertyIdentifierNamePreIncrementOrDecrementExpression(Sema
AddInstruction(OpCode.DUP);
Call(model, symbol.GetMethod!);
EmitIncrementOrDecrement(operatorToken);
EnsureIntegerInRange(symbol.Type);
AddInstruction(OpCode.TUCK);
Call(model, symbol.SetMethod!, CallingConvention.StdCall);
}
Expand Down Expand Up @@ -3202,6 +3224,7 @@ private void ConvertFieldMemberAccessPreIncrementOrDecrementExpression(SemanticM
byte index = context.AddStaticField(symbol);
AccessSlot(OpCode.LDSFLD, index);
EmitIncrementOrDecrement(operatorToken);
EnsureIntegerInRange(symbol.Type);
AddInstruction(OpCode.DUP);
AccessSlot(OpCode.STSFLD, index);
}
Expand All @@ -3213,6 +3236,7 @@ private void ConvertFieldMemberAccessPreIncrementOrDecrementExpression(SemanticM
Push(index);
AddInstruction(OpCode.PICKITEM);
EmitIncrementOrDecrement(operatorToken);
EnsureIntegerInRange(symbol.Type);
AddInstruction(OpCode.TUCK);
Push(index);
AddInstruction(OpCode.SWAP);
Expand All @@ -3226,6 +3250,7 @@ private void ConvertPropertyMemberAccessPreIncrementOrDecrementExpression(Semant
{
Call(model, symbol.GetMethod!);
EmitIncrementOrDecrement(operatorToken);
EnsureIntegerInRange(symbol.Type);
AddInstruction(OpCode.DUP);
Call(model, symbol.SetMethod!);
}
Expand All @@ -3235,6 +3260,7 @@ private void ConvertPropertyMemberAccessPreIncrementOrDecrementExpression(Semant
AddInstruction(OpCode.DUP);
Call(model, symbol.GetMethod!);
EmitIncrementOrDecrement(operatorToken);
EnsureIntegerInRange(symbol.Type);
AddInstruction(OpCode.TUCK);
Call(model, symbol.SetMethod!, CallingConvention.StdCall);
}
Expand Down
147 changes: 147 additions & 0 deletions tests/Neo.Compiler.CSharp.UnitTests/TestClasses/Contract_Inc_Dec.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
using System;
using System.ComponentModel;

namespace Neo.Compiler.CSharp.UnitTests.TestClasses
{
public class Contract2_Inc_Dec : SmartContract.Framework.SmartContract
{
private static uint _property;

public static uint UnitTest_Property_Inc_Checked()
{
_property = uint.MaxValue;
checked
{
++_property;
_property++;
}
return _property;
}

public static uint UnitTest_Property_Inc_UnChecked()
{
_property = uint.MaxValue;
unchecked
{
++_property;
_property++;
}
return _property;
}

public static uint UnitTest_Property_Dec_Checked()
{
_property = uint.MinValue;
checked
{
--_property;
_property--;
}
return _property;
}
public static uint UnitTest_Property_Dec_UnChecked()
shargon marked this conversation as resolved.
Show resolved Hide resolved
{
_property = uint.MinValue;
unchecked
{
--_property;
_property--;
}
return _property;
}

public static uint UnitTest_Local_Dec_Checked()
{
uint local = uint.MinValue;
checked
{
--local;
local--;
}
return local;
}

public static uint UnitTest_Local_Dec_UnChecked()
{
uint local = uint.MinValue;
unchecked
{
--local;
local--;
}
return local;
}

public static uint UnitTest_Local_Inc_Checked()
{
uint local = uint.MaxValue;
checked
{
++local;
local++;
}
return local;
}

public static uint UnitTest_Local_Inc_UnChecked()
{
uint local = uint.MaxValue;
unchecked
{
++local;
local++;
}
return local;
}

public static uint UnitTest_Param_Dec_Checked(uint param)
{
param = uint.MinValue;
checked
{
--param;
param--;
}
return param;
}

public static uint UnitTest_Param_Dec_UnChecked(uint param)
{
param = uint.MinValue;
unchecked
{
--param;
param--;
}
return param;
}

public static uint UnitTest_Param_Inc_Checked(uint param)
{
param = uint.MaxValue;
checked
{
++param;
param++;
}
return param;
}

public static uint UnitTest_Param_Inc_UnChecked(uint param)
{
param = uint.MaxValue;
unchecked
{
++param;
param++;
}
return param;
}

public static void UnitTest_Not_DeadLoop()
{
for (uint i = 5; i < 7; i--) ;
}

}
shargon marked this conversation as resolved.
Show resolved Hide resolved
}
Loading