diff --git a/src/common/scripting/backend/codegen.cpp b/src/common/scripting/backend/codegen.cpp index 2482dd699..214cb483c 100644 --- a/src/common/scripting/backend/codegen.cpp +++ b/src/common/scripting/backend/codegen.cpp @@ -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(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(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(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(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 diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index 380e53e9a..d3c7dd883 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -1,4 +1,4 @@ -version "4.6" +version "4.9" // Generic engine code #include "zscript/engine/base.zs" diff --git a/wadsrc/static/zscript/engine/dynarrays.zs b/wadsrc/static/zscript/engine/dynarrays.zs index 009350b8e..85d135d87 100644 --- a/wadsrc/static/zscript/engine/dynarrays.zs +++ b/wadsrc/static/zscript/engine/dynarrays.zs @@ -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); diff --git a/wadsrc/static/zscript/engine/ui/menu/colorpickermenu.zs b/wadsrc/static/zscript/engine/ui/menu/colorpickermenu.zs index ac02f7394..218a215fc 100644 --- a/wadsrc/static/zscript/engine/ui/menu/colorpickermenu.zs +++ b/wadsrc/static/zscript/engine/ui/menu/colorpickermenu.zs @@ -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); diff --git a/wadsrc/static/zscript/engine/ui/menu/imagescroller.zs b/wadsrc/static/zscript/engine/ui/menu/imagescroller.zs index 6fd58bb6a..d56d770ce 100644 --- a/wadsrc/static/zscript/engine/ui/menu/imagescroller.zs +++ b/wadsrc/static/zscript/engine/ui/menu/imagescroller.zs @@ -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;