- 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:
parent
388a5cb481
commit
3563c99ead
5 changed files with 76 additions and 15 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue