Fix OverflowSafeInt INT64_MIN handling when not using overflow builtins

See: https://github.com/OpenTTD/OpenTTD/issues/8284
This commit is contained in:
Jonathan G Rennison
2020-10-02 17:52:41 +01:00
parent 609f37cef9
commit db0e25f7cd

View File

@@ -51,9 +51,10 @@ public:
this->m_value = (other.m_value < 0) ? T_MIN : T_MAX; this->m_value = (other.m_value < 0) ? T_MIN : T_MAX;
} }
#else #else
if ((T_MAX - abs(other.m_value)) < abs(this->m_value) && if ((this->m_value > 0) && (other.m_value > 0) && (T_MAX - other.m_value) < this->m_value) {
(this->m_value < 0) == (other.m_value < 0)) { this->m_value = T_MAX;
this->m_value = (this->m_value < 0) ? T_MIN : T_MAX ; } else if ((this->m_value < 0) && (other.m_value < 0) && (this->m_value == T_MIN || other.m_value == T_MIN || ((T_MAX + this->m_value) + other.m_value < (T_MIN + T_MAX)))) {
this->m_value = T_MIN;
} else { } else {
this->m_value += other.m_value; this->m_value += other.m_value;
} }
@@ -68,7 +69,13 @@ public:
this->m_value = (other.m_value < 0) ? T_MAX : T_MIN; this->m_value = (other.m_value < 0) ? T_MAX : T_MIN;
} }
#else #else
*this += (-other); if ((this->m_value > 0) && (other.m_value < 0) && (T_MAX + other.m_value) < this->m_value) {
this->m_value = T_MAX;
} else if ((this->m_value < 0) && (other.m_value > 0) && (T_MAX + this->m_value) < (T_MIN + T_MAX) + other.m_value) {
this->m_value = T_MIN;
} else {
this->m_value -= other.m_value;
}
#endif #endif
return *this; return *this;
} }
@@ -102,10 +109,18 @@ public:
this->m_value = ((this->m_value < 0) == (factor < 0)) ? T_MAX : T_MIN; this->m_value = ((this->m_value < 0) == (factor < 0)) ? T_MAX : T_MIN;
} }
#else #else
if (factor != 0 && (T_MAX / abs(factor)) < abs(this->m_value)) { if (factor == -1) {
this->m_value = ((this->m_value < 0) == (factor < 0)) ? T_MAX : T_MIN ; this->m_value = (this->m_value == T_MIN) ? T_MAX : -this->m_value;
} else if ((factor > 0) && (this->m_value > 0) && (T_MAX / factor) < this->m_value) {
this->m_value = T_MAX;
} else if ((factor > 0) && (this->m_value < 0) && (T_MIN / factor) > this->m_value) {
this->m_value = T_MIN;
} else if ((factor < 0) && (this->m_value > 0) && (T_MIN / factor) < this->m_value) {
this->m_value = T_MIN;
} else if ((factor < 0) && (this->m_value < 0) && (T_MAX / factor) > this->m_value) {
this->m_value = T_MAX;
} else { } else {
this->m_value *= factor ; this->m_value *= factor;
} }
#endif #endif
return *this; return *this;