- made adjustments for proper int type promotion to allow internal ZScript to compile with it on.

* Emit a warning when relational comparisons are made between signed and unsigned ints.
* Handle shift operators so that they do not fail for constant definitions.
* changed return type of Array::Size() to signed int as most code out there is using it this way and would otherwise drown in warnings.
* fixed a few deprecation warnings.
This commit is contained in:
Christoph Oelckers 2022-08-03 10:26:29 +02:00
parent 388a5cb481
commit 3563c99ead
5 changed files with 76 additions and 15 deletions

View file

@ -2686,8 +2686,7 @@ bool FxBinary::Promote(FCompileContext &ctx, bool forceint, bool shiftop)
ValueType = TypeUInt32; ValueType = TypeUInt32;
} }
// If one side is an unsigned 32-bit int and the other side is a signed 32-bit int, the signed side is implicitly converted to unsigned, // If one side is an unsigned 32-bit int and the other side is a signed 32-bit int, the signed side is implicitly converted to unsigned,
// unless this is a shift operator where different rules must apply. else if (!ctx.FromDecorate && left->ValueType == TypeUInt32 && right->ValueType == TypeSInt32 && !shiftop && ctx.Version >= MakeVersion(4, 9, 0))
else if (((!ctx.FromDecorate && left->ValueType == TypeUInt32 && right->ValueType == TypeSInt32) || !shiftop) && ctx.Version >= MakeVersion(4, 9, 0))
{ {
right = new FxIntCast(right, false, false, true); right = new FxIntCast(right, false, false, true);
right = right->Resolve(ctx); right = right->Resolve(ctx);
@ -2742,6 +2741,15 @@ bool FxBinary::Promote(FCompileContext &ctx, bool forceint, bool shiftop)
delete this; delete this;
return false; return false;
} }
// shift operators are different: The left operand defines the type and the right operand must always be made unsigned
if (shiftop)
{
ValueType = left->ValueType == TypeUInt32 ? TypeUInt32 : TypeSInt32;
right = new FxIntCast(right, false, false, true);
right = right->Resolve(ctx);
}
return true; return true;
} }
@ -3338,6 +3346,59 @@ FxExpression *FxCompareRel::Resolve(FCompileContext& ctx)
} }
else if (left->IsNumeric() && right->IsNumeric()) else if (left->IsNumeric() && right->IsNumeric())
{ {
if (left->IsInteger() && right->IsInteger())
{
if (ctx.Version >= MakeVersion(4, 9, 0))
{
// We need to do more checks here to catch problem cases.
if (left->ValueType == TypeUInt32 && right->ValueType == TypeSInt32)
{
if (left->isConstant() && !right->isConstant())
{
auto val = static_cast<FxConstant*>(left)->GetValue().GetUInt();
if (val > INT_MAX)
{
ScriptPosition.Message(MSG_WARNING, "Comparison with out of range unsigned constant");
}
}
else if (right->isConstant() && !left->isConstant())
{
auto val = static_cast<FxConstant*>(right)->GetValue().GetInt();
if (val > INT_MAX)
{
ScriptPosition.Message(MSG_WARNING, "Comparison with out of range signed constant");
}
}
else if (!left->isConstant() && !right->isConstant())
{
ScriptPosition.Message(MSG_WARNING, "Comparison between signed and unsigned value");
}
}
else if (left->ValueType == TypeSInt32 && right->ValueType == TypeUInt32)
{
if (left->isConstant() && !right->isConstant())
{
auto val = static_cast<FxConstant*>(left)->GetValue().GetInt();
if (val > INT_MAX)
{
ScriptPosition.Message(MSG_WARNING, "Comparison with out of range signed constant");
}
}
else if (right->isConstant() && !left->isConstant())
{
auto val = static_cast<FxConstant*>(right)->GetValue().GetUInt();
if (val > INT_MAX)
{
ScriptPosition.Message(MSG_WARNING, "Comparison with out of range unsigned constant");
}
}
else if (!left->isConstant() && !right->isConstant())
{
ScriptPosition.Message(MSG_WARNING, "Comparison between signed and unsigned value");
}
}
}
}
Promote(ctx); Promote(ctx);
} }
else else
@ -8247,7 +8308,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
member->membervar = newfield; member->membervar = newfield;
Self = nullptr; Self = nullptr;
delete this; delete this;
member->ValueType = TypeUInt32; member->ValueType = TypeSInt32;
return member; return member;
} }
else else

View file

@ -1,4 +1,4 @@
version "4.6" version "4.9"
// Generic engine code // Generic engine code
#include "zscript/engine/base.zs" #include "zscript/engine/base.zs"

View file

@ -3,7 +3,7 @@
struct DynArray_I8 native struct DynArray_I8 native
{ {
native readonly uint Size; native readonly int Size;
native void Copy(DynArray_I8 other); native void Copy(DynArray_I8 other);
native void Move(DynArray_I8 other); native void Move(DynArray_I8 other);
@ -23,7 +23,7 @@ struct DynArray_I8 native
struct DynArray_I16 native struct DynArray_I16 native
{ {
native readonly uint Size; native readonly int Size;
native void Copy(DynArray_I16 other); native void Copy(DynArray_I16 other);
native void Move(DynArray_I16 other); native void Move(DynArray_I16 other);
@ -43,7 +43,7 @@ struct DynArray_I16 native
struct DynArray_I32 native struct DynArray_I32 native
{ {
native readonly uint Size; native readonly int Size;
native void Copy(DynArray_I32 other); native void Copy(DynArray_I32 other);
native void Move(DynArray_I32 other); native void Move(DynArray_I32 other);
@ -64,7 +64,7 @@ struct DynArray_I32 native
struct DynArray_F32 native struct DynArray_F32 native
{ {
native readonly uint Size; native readonly int Size;
native void Copy(DynArray_F32 other); native void Copy(DynArray_F32 other);
native void Move(DynArray_F32 other); native void Move(DynArray_F32 other);
@ -84,7 +84,7 @@ struct DynArray_F32 native
struct DynArray_F64 native struct DynArray_F64 native
{ {
native readonly uint Size; native readonly int Size;
native void Copy(DynArray_F64 other); native void Copy(DynArray_F64 other);
native void Move(DynArray_F64 other); native void Move(DynArray_F64 other);
@ -104,7 +104,7 @@ struct DynArray_F64 native
struct DynArray_Ptr native struct DynArray_Ptr native
{ {
native readonly uint Size; native readonly int Size;
native void Copy(DynArray_Ptr other); native void Copy(DynArray_Ptr other);
native void Move(DynArray_Ptr other); native void Move(DynArray_Ptr other);
@ -124,7 +124,7 @@ struct DynArray_Ptr native
struct DynArray_Obj native struct DynArray_Obj native
{ {
native readonly uint Size; native readonly int Size;
native void Copy(DynArray_Obj other); native void Copy(DynArray_Obj other);
native void Move(DynArray_Obj other); native void Move(DynArray_Obj other);
@ -144,7 +144,7 @@ struct DynArray_Obj native
struct DynArray_String native struct DynArray_String native
{ {
native readonly uint Size; native readonly int Size;
native void Copy(DynArray_String other); native void Copy(DynArray_String other);
native void Move(DynArray_String other); native void Move(DynArray_String other);

View file

@ -303,7 +303,7 @@ class ColorpickerMenu : OptionMenu
} }
// Make sure the cursors stand out against similar colors // Make sure the cursors stand out against similar colors
// by pulsing them. // by pulsing them.
blinky = abs(sin(MSTime()/1000.0)) * 0.5 + 0.5; blinky = abs(sin(MSTimeF()/1000.0)) * 0.5 + 0.5;
col = Color(255, int(r*blinky), int(g*blinky), int(b*blinky)); col = Color(255, int(r*blinky), int(g*blinky), int(b*blinky));
screen.Clear (box_x, box_y, box_x + w, box_y + 1, col); screen.Clear (box_x, box_y, box_x + w, box_y + 1, col);

View file

@ -154,7 +154,7 @@ class ImageScrollerMenu : Menu
{ {
if (AnimatedTransition) if (AnimatedTransition)
{ {
start = MSTime() * (120. / 1000.); start = MSTimeF() * (120. / 1000.);
length = 30; length = 30;
dir = animtype; dir = animtype;
previous = current; previous = current;
@ -247,7 +247,7 @@ class ImageScrollerMenu : Menu
private bool DrawTransition() private bool DrawTransition()
{ {
double now = MSTime() * (120. / 1000.); double now = MSTimeF() * (120. / 1000.);
if (now < start + length) if (now < start + length)
{ {
double factor = screen.GetWidth()/2; double factor = screen.GetWidth()/2;