- 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;
}
// 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 = right->Resolve(ctx);
@ -2742,6 +2741,15 @@ bool FxBinary::Promote(FCompileContext &ctx, bool forceint, bool shiftop)
delete this;
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;
}
@ -3338,6 +3346,59 @@ FxExpression *FxCompareRel::Resolve(FCompileContext& ctx)
}
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);
}
else
@ -8247,7 +8308,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
member->membervar = newfield;
Self = nullptr;
delete this;
member->ValueType = TypeUInt32;
member->ValueType = TypeSInt32;
return member;
}
else

View file

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

View file

@ -3,7 +3,7 @@
struct DynArray_I8 native
{
native readonly uint Size;
native readonly int Size;
native void Copy(DynArray_I8 other);
native void Move(DynArray_I8 other);
@ -23,7 +23,7 @@ struct DynArray_I8 native
struct DynArray_I16 native
{
native readonly uint Size;
native readonly int Size;
native void Copy(DynArray_I16 other);
native void Move(DynArray_I16 other);
@ -43,7 +43,7 @@ struct DynArray_I16 native
struct DynArray_I32 native
{
native readonly uint Size;
native readonly int Size;
native void Copy(DynArray_I32 other);
native void Move(DynArray_I32 other);
@ -64,7 +64,7 @@ struct DynArray_I32 native
struct DynArray_F32 native
{
native readonly uint Size;
native readonly int Size;
native void Copy(DynArray_F32 other);
native void Move(DynArray_F32 other);
@ -84,7 +84,7 @@ struct DynArray_F32 native
struct DynArray_F64 native
{
native readonly uint Size;
native readonly int Size;
native void Copy(DynArray_F64 other);
native void Move(DynArray_F64 other);
@ -104,7 +104,7 @@ struct DynArray_F64 native
struct DynArray_Ptr native
{
native readonly uint Size;
native readonly int Size;
native void Copy(DynArray_Ptr other);
native void Move(DynArray_Ptr other);
@ -124,7 +124,7 @@ struct DynArray_Ptr native
struct DynArray_Obj native
{
native readonly uint Size;
native readonly int Size;
native void Copy(DynArray_Obj other);
native void Move(DynArray_Obj other);
@ -144,7 +144,7 @@ struct DynArray_Obj native
struct DynArray_String native
{
native readonly uint Size;
native readonly int Size;
native void Copy(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
// 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));
screen.Clear (box_x, box_y, box_x + w, box_y + 1, col);

View file

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