diff --git a/clc/dll/include/AggrBinStructNum.h b/clc/dll/include/AggrBinStructNum.h index 19de73756..eb59f73b7 100644 --- a/clc/dll/include/AggrBinStructNum.h +++ b/clc/dll/include/AggrBinStructNum.h @@ -85,11 +85,9 @@ struct binary_assign_partial_accumulation template struct cov_accumulation_type { - typedef SizeT count_type; - typedef typename acc_type::type sum_type; - typedef typename aggr_type::type cov_type; - - cov_accumulation_type(): n(), x(), y(), xy() {} + using count_type = SizeT; + using sum_type= acc_type::type; + using cov_type = aggr_type::type; operator cov_type() const { @@ -107,8 +105,8 @@ struct cov_accumulation_type friend cov_type make_result(const cov_accumulation_type& output) { return output.operator cov_type(); } // move casting stuff here - count_type n; - sum_type x, y, xy; + count_type n = 0; + sum_type x = sum_type(), y = sum_type(), xy = sum_type(); }; template @@ -124,10 +122,13 @@ struct binary_assign_cov: binary_assign, T, T> return; } ++ a.n; - a.x += x; - a.y += y; - a.xy += m_MulFunc(x, y); + MG_CHECK(a.n); + a.x = m_SafeAdder(a.x, x); + a.y = m_SafeAdder(a.y, y); + a.xy = m_SafeAdder(a.xy, m_MulFunc(x, y)); } + using sum_type = typename cov_accumulation_type::sum_type; + safe_plus m_SafeAdder; mulx_func m_MulFunc; }; diff --git a/clc/dll/include/AggrUniStruct.h b/clc/dll/include/AggrUniStruct.h index 5548b0fa0..49f6f2fcd 100644 --- a/clc/dll/include/AggrUniStruct.h +++ b/clc/dll/include/AggrUniStruct.h @@ -1,31 +1,6 @@ -//
-/* -Data & Model Server (DMS) is a server written in C++ for DSS applications. -Version: see srv/dms/rtc/dll/src/RtcVersion.h for version info. - -Copyright (C) 1998-2004 YUSE GSO Object Vision BV. - -Documentation on using the Data & Model Server software can be found at: -http://www.ObjectVision.nl/DMS/ - -See additional guidelines and notes in srv/dms/Readme-srv.txt - -This library is free software; you can use, redistribute, and/or -modify it under the terms of the GNU General Public License version 2 -(the License) as published by the Free Software Foundation, -provided that this entire header notice and readme-srv.txt is preserved. - -See LICENSE.TXT for terms of distribution or look at our web site: -http://www.objectvision.nl/DMS/License.txt -or alternatively at: http://www.gnu.org/copyleft/gpl.html - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. However, specific warranties might be -granted by an additional written contract for support, assistance and/or development -*/ -//
+// Copyright (C) 2023 Object Vision b.v. +// License: GNU GPL 3 +///////////////////////////////////////////////////////////////////////////// #pragma once @@ -135,7 +110,7 @@ struct assign_partial_output_from_buffer template void AssignOutput(dms_seq res, const Container& outputs) const { - dms_assert(res.size() == outputs.size()); + assert(res.size() == outputs.size()); auto ri = res.begin(); auto oi = outputs.begin(), diff --git a/clc/dll/include/AttrBinStruct.h b/clc/dll/include/AttrBinStruct.h index b7e1146de..dd6e528de 100644 --- a/clc/dll/include/AttrBinStruct.h +++ b/clc/dll/include/AttrBinStruct.h @@ -10,6 +10,7 @@ #include #include "mci/ValueClass.h" +#include "utl/mySPrintF.h" #include "utl/StringFunc.h" #include "Prototypes.h" @@ -141,16 +142,23 @@ void do_binary_func( // ***************************************************************************** template -[[noreturn]] void throwOverflow(CharPtr opName, T a, CharPtr preposition, T b, CharPtr alternativeFunc, const ValueClass* alternativeValueClass) +[[noreturn]] void throwOverflow(CharPtr opName, T a, CharPtr preposition, T b, bool suggestAlternative, CharPtr alternativeFunc, const ValueClass* alternativeValueClass) { SharedStr vcName = AsString(ValueWrap::GetStaticClass()->GetID()); SharedStr acName; if (alternativeValueClass) acName = AsString(alternativeValueClass->GetID()); - throwDmsErrF("Numeric overflow when %1% %2% values %3% %4% %5%." - "\nConsider using %6% if your model deals with overflow as null values%7%%8%." + auto primaryMsg = mySSPrintF("Numeric overflow when %1% %2% values %3% %4% %5%." , opName, vcName.c_str(), AsString(a), preposition, AsString(b) + ); + + if (!suggestAlternative) + throwDmsErrD(primaryMsg.c_str()); + + throwDmsErrF("%1%" + "\nConsider using %2% if your model deals with overflow as null values%3%%4%." + , primaryMsg , alternativeFunc , alternativeValueClass ? " or consider converting the arguments to " : "" , alternativeValueClass ? acName.c_str() : "" @@ -277,7 +285,7 @@ struct safe_plus if constexpr (!is_signed_v) { if (result < a) - throwOverflow("adding", a, "and", b, "add_or_null", NextAddIntegral()); + throwOverflow("adding", a, "and", b, true, "add_or_null", NextAddIntegral()); } else { @@ -288,7 +296,7 @@ struct safe_plus { auto resultNonnegative = (result >= 0); if (aNonnegative !=resultNonnegative) - throwOverflow("adding", a, "and", b, "add_or_null", NextAddIntegral()); + throwOverflow("adding", a, "and", b, true, "add_or_null", NextAddIntegral()); } } } @@ -321,7 +329,7 @@ struct safe_minus if constexpr (!is_signed_v) { if (a < b) - throwOverflow("subtracting", b, "from", a, "sub_or_null", NextSubIntegral()); + throwOverflow("subtracting", b, "from", a, true, "sub_or_null", NextSubIntegral()); } else { @@ -332,7 +340,7 @@ struct safe_minus { auto resultNonnegative = (result >= 0); if (aNonnegative != resultNonnegative) - throwOverflow("subtracting", b, "from", a, "sub_or_null", NextSubIntegral()); + throwOverflow("subtracting", b, "from", a, true, "sub_or_null", NextSubIntegral()); } } } @@ -472,15 +480,10 @@ struct mul_func_impl : binary_func return UNDEFINED_VALUE(V); } - V result = a * b; - - if constexpr (!std::is_floating_point_v) - { - if (a && b && b != result / a) - throwOverflow("multiplying", a, "and", b, "mul_or_null", NextAddIntegral()); - } - - return result; + if constexpr (std::is_floating_point_v) + return a * b; + else + return CheckedMul(a, b, true); } }; @@ -542,6 +545,24 @@ struct mulx_func : binary_func::type, T, T> } }; +template <> +struct mulx_func : binary_func +{ + typename mulx_func::res_type operator()(UInt64 a1, UInt64 a2) const + { + return CheckedMul(a1, a2, false); + } +}; + +template <> +struct mulx_func : binary_func +{ + typename mulx_func::res_type operator()(Int64 a1, Int64 a2) const + { + return CheckedMul(a1, a2, false); + } +}; + template struct div_func_base: binary_func { diff --git a/clc/dll/src/OperAttrBin.cpp b/clc/dll/src/OperAttrBin.cpp index 2cec8ab26..1e57cc508 100644 --- a/clc/dll/src/OperAttrBin.cpp +++ b/clc/dll/src/OperAttrBin.cpp @@ -41,12 +41,10 @@ struct StrConcatOperator : BinaryAttrOper dms_assert(arg2Data.size() == (e2Void ? 1 : cardinality)); using data_size_type = sequence_traits::seq_t::data_size_type; - data_size_type - totalSize = - CheckedAdd( - CheckedMul(e1Void ? cardinality : 1, arg1Data.get_sa().actual_data_size()) - , CheckedMul(e2Void ? cardinality : 1, arg2Data.get_sa().actual_data_size()) - ); + data_size_type arg1Size = arg1Data.get_sa().actual_data_size(); if (e1Void) arg1Size = CheckedMul(cardinality, arg1Size, false); + data_size_type arg2Size = arg2Data.get_sa().actual_data_size(); if (e2Void) arg2Size = CheckedMul(cardinality, arg2Size, false); + + data_size_type totalSize = CheckedAdd(arg1Size, arg2Size); if (e1Void && !a1i->IsDefined()) totalSize = 0; if (e2Void && !a2i->IsDefined()) totalSize = 0; diff --git a/qtgui/exe/src/DmsMainWindow.cpp b/qtgui/exe/src/DmsMainWindow.cpp index 4997e0625..4ff09f807 100644 --- a/qtgui/exe/src/DmsMainWindow.cpp +++ b/qtgui/exe/src/DmsMainWindow.cpp @@ -320,7 +320,7 @@ auto MainWindow::CreateCodeAnalysisSubMenu(QMenu* menu) -> std::unique_ptr typename boost::disable_if, T >::type CheckedAdd(T a, T b) { - dms_assert(a>=0); - dms_assert(b>=0); + assert(a>=0); + assert(b>=0); T r = a+b; - dms_assert(r>=0); + assert(r>=0); if (r < a || r < b) throwDmsErrD("Overflow in addition"); return r; } template T -CheckedMul(T a,T b) +CheckedMul(T a,T b, bool suggestAlternative) { typename mul_type::type r = a; r *= b; if (r != T(r)) - throwDmsErrD("Overflow in multiplication"); + throwOverflow("multiplying", a, "and", b, suggestAlternative, "mul_or_null", NextAddIntegral()); return r; } template <> -inline UInt64 CheckedMul(UInt64 a, UInt64 b) +inline UInt64 CheckedMul(UInt64 a, UInt64 b, bool suggestAlternative) { UInt64 res = a * b; if ((a && (res / a != b)) || (b && (res / b != a))) @@ -81,7 +81,7 @@ inline UInt64 CheckedMul(UInt64 a, UInt64 b) } template <> -inline Int64 CheckedMul(Int64 a, Int64 b) +inline Int64 CheckedMul(Int64 a, Int64 b, bool suggestAlternative) { Int64 res = a * b; if ((a && (res / a != b)) || (b && (res / b != a))) @@ -89,19 +89,4 @@ inline Int64 CheckedMul(Int64 a, Int64 b) return res; } -inline UInt64 CheckedMul(UInt64 a, UInt64 b, UInt64*) -{ - return CheckedMul(a, b); -} - -inline UInt64 CheckedMul(UInt32 a, UInt32 b, UInt64*) -{ - return UInt64(a) * UInt64(b); -} - -inline UInt32 CheckedMul(UInt32 a, UInt32 b, UInt32*) -{ - return CheckedMul(a, b); -} - #endif // __RTC_GEO_CHECKEDCALC_H diff --git a/rtc/dll/src/geo/Point.h b/rtc/dll/src/geo/Point.h index e0bd99b24..aef56f039 100644 --- a/rtc/dll/src/geo/Point.h +++ b/rtc/dll/src/geo/Point.h @@ -321,7 +321,7 @@ operator /(const Point& a, const Point& b) template inline - SizeT Cardinality(const Point& v) { return CheckedMul(Cardinality(v.first), Cardinality(v.second)); } + SizeT Cardinality(const Point& v) { return CheckedMul(Cardinality(v.first), Cardinality(v.second), false); } template inline typename product_type::type diff --git a/shv/dll/src/GridFill.h b/shv/dll/src/GridFill.h index 15ddde594..06c858bc4 100644 --- a/shv/dll/src/GridFill.h +++ b/shv/dll/src/GridFill.h @@ -214,7 +214,7 @@ void GridFill( const grid_rowcol_id* currGridColPtr = gridColBeginPtr; - SizeT currGridRowBegin = CheckedMul(currGridRow, gridSize.Col()); + SizeT currGridRowBegin = CheckedMul(currGridRow, gridSize.Col(), false); GType currViewCol = viewColBegin; PixelType result; diff --git a/shv/dll/src/ScrollPort.cpp b/shv/dll/src/ScrollPort.cpp index 4a3155f3f..12ba9f4d6 100644 --- a/shv/dll/src/ScrollPort.cpp +++ b/shv/dll/src/ScrollPort.cpp @@ -369,7 +369,7 @@ TType CalcNewPos(HWND scrollBarCtl, UInt16 scrollCmd, GType nrTPerG) GType newPos = CalcNewPosBase(scrollBarCtl, scrollCmd); if (newPos < 0) return -1; - return CheckedMul(newPos, nrTPerG); + return CheckedMul(newPos, nrTPerG, false); } void ScrollPort::OnHScroll(UInt16 scollCmd)