Skip to content

Commit

Permalink
#314, supplemental.
Browse files Browse the repository at this point in the history
  • Loading branch information
MaartenHilferink committed Oct 5, 2023
1 parent d0c9f65 commit 5e828ff
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 87 deletions.
21 changes: 11 additions & 10 deletions clc/dll/include/AggrBinStructNum.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,9 @@ struct binary_assign_partial_accumulation
template <typename T>
struct cov_accumulation_type
{
typedef SizeT count_type;
typedef typename acc_type<T>::type sum_type;
typedef typename aggr_type<T>::type cov_type;

cov_accumulation_type(): n(), x(), y(), xy() {}
using count_type = SizeT;
using sum_type= acc_type<T>::type;
using cov_type = aggr_type<T>::type;

operator cov_type() const
{
Expand All @@ -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 <typename T>
Expand All @@ -124,10 +122,13 @@ struct binary_assign_cov: binary_assign<cov_accumulation_type<T>, 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<T>::sum_type;
safe_plus<sum_type> m_SafeAdder;
mulx_func<T> m_MulFunc;
};

Expand Down
33 changes: 4 additions & 29 deletions clc/dll/include/AggrUniStruct.h
Original file line number Diff line number Diff line change
@@ -1,31 +1,6 @@
//<HEADER>
/*
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
*/
//</HEADER>
// Copyright (C) 2023 Object Vision b.v.
// License: GNU GPL 3
/////////////////////////////////////////////////////////////////////////////

#pragma once

Expand Down Expand Up @@ -135,7 +110,7 @@ struct assign_partial_output_from_buffer
template<typename Container>
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(),
Expand Down
53 changes: 37 additions & 16 deletions clc/dll/include/AttrBinStruct.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <functional>

#include "mci/ValueClass.h"
#include "utl/mySPrintF.h"
#include "utl/StringFunc.h"

#include "Prototypes.h"
Expand Down Expand Up @@ -141,16 +142,23 @@ void do_binary_func(
// *****************************************************************************

template <typename T>
[[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<T>::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() : ""
Expand Down Expand Up @@ -277,7 +285,7 @@ struct safe_plus
if constexpr (!is_signed_v<V>)
{
if (result < a)
throwOverflow("adding", a, "and", b, "add_or_null", NextAddIntegral<V>());
throwOverflow("adding", a, "and", b, true, "add_or_null", NextAddIntegral<V>());
}
else
{
Expand All @@ -288,7 +296,7 @@ struct safe_plus
{
auto resultNonnegative = (result >= 0);
if (aNonnegative !=resultNonnegative)
throwOverflow("adding", a, "and", b, "add_or_null", NextAddIntegral<V>());
throwOverflow("adding", a, "and", b, true, "add_or_null", NextAddIntegral<V>());
}
}
}
Expand Down Expand Up @@ -321,7 +329,7 @@ struct safe_minus
if constexpr (!is_signed_v<T>)
{
if (a < b)
throwOverflow("subtracting", b, "from", a, "sub_or_null", NextSubIntegral<T>());
throwOverflow("subtracting", b, "from", a, true, "sub_or_null", NextSubIntegral<T>());
}
else
{
Expand All @@ -332,7 +340,7 @@ struct safe_minus
{
auto resultNonnegative = (result >= 0);
if (aNonnegative != resultNonnegative)
throwOverflow("subtracting", b, "from", a, "sub_or_null", NextSubIntegral<T>());
throwOverflow("subtracting", b, "from", a, true, "sub_or_null", NextSubIntegral<T>());
}
}
}
Expand Down Expand Up @@ -472,15 +480,10 @@ struct mul_func_impl : binary_func<V, V, V>
return UNDEFINED_VALUE(V);
}

V result = a * b;

if constexpr (!std::is_floating_point_v<V>)
{
if (a && b && b != result / a)
throwOverflow("multiplying", a, "and", b, "mul_or_null", NextAddIntegral<V>());
}

return result;
if constexpr (std::is_floating_point_v<V>)
return a * b;
else
return CheckedMul<V>(a, b, true);
}
};

Expand Down Expand Up @@ -542,6 +545,24 @@ struct mulx_func : binary_func<typename acc_type<T>::type, T, T>
}
};

template <>
struct mulx_func<UInt64> : binary_func<UInt64, UInt64, UInt64>
{
typename mulx_func::res_type operator()(UInt64 a1, UInt64 a2) const
{
return CheckedMul(a1, a2, false);
}
};

template <>
struct mulx_func<Int64> : binary_func<Int64, Int64, Int64>
{
typename mulx_func::res_type operator()(Int64 a1, Int64 a2) const
{
return CheckedMul(a1, a2, false);
}
};

template <typename R, typename T, typename U=T>
struct div_func_base: binary_func<R, T, U>
{
Expand Down
10 changes: 4 additions & 6 deletions clc/dll/src/OperAttrBin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,10 @@ struct StrConcatOperator : BinaryAttrOper<SharedStr, SharedStr, SharedStr>
dms_assert(arg2Data.size() == (e2Void ? 1 : cardinality));

using data_size_type = sequence_traits<SharedStr>::seq_t::data_size_type;
data_size_type
totalSize =
CheckedAdd<data_size_type>(
CheckedMul<data_size_type>(e1Void ? cardinality : 1, arg1Data.get_sa().actual_data_size())
, CheckedMul<data_size_type>(e2Void ? cardinality : 1, arg2Data.get_sa().actual_data_size())
);
data_size_type arg1Size = arg1Data.get_sa().actual_data_size(); if (e1Void) arg1Size = CheckedMul<data_size_type>(cardinality, arg1Size, false);
data_size_type arg2Size = arg2Data.get_sa().actual_data_size(); if (e2Void) arg2Size = CheckedMul<data_size_type>(cardinality, arg2Size, false);

data_size_type totalSize = CheckedAdd<data_size_type>(arg1Size, arg2Size);
if (e1Void && !a1i->IsDefined()) totalSize = 0;
if (e2Void && !a2i->IsDefined()) totalSize = 0;

Expand Down
2 changes: 1 addition & 1 deletion qtgui/exe/src/DmsMainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ auto MainWindow::CreateCodeAnalysisSubMenu(QMenu* menu) -> std::unique_ptr<QMenu
MainWindow* MainWindow::TheOne()
{
assert(IsMainThread()); // or use a mutex to guard access to TheOne.
assert(s_CurrMainWindow);
// assert(s_CurrMainWindow);// main window destructor might already be in session, such as when called from the destructor of ValueInfoPanel
return s_CurrMainWindow;
}

Expand Down
29 changes: 7 additions & 22 deletions rtc/dll/src/geo/CheckedCalc.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,27 +52,27 @@ template <typename T>
typename boost::disable_if<is_signed<T>, 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 <typename T> T
CheckedMul(T a,T b)
CheckedMul(T a,T b, bool suggestAlternative)
{
typename mul_type<T>::type r = a;
r *= b;
if (r != T(r))
throwDmsErrD("Overflow in multiplication");
throwOverflow("multiplying", a, "and", b, suggestAlternative, "mul_or_null", NextAddIntegral<T>());
return r;
}

template <>
inline UInt64 CheckedMul<UInt64>(UInt64 a, UInt64 b)
inline UInt64 CheckedMul<UInt64>(UInt64 a, UInt64 b, bool suggestAlternative)
{
UInt64 res = a * b;
if ((a && (res / a != b)) || (b && (res / b != a)))
Expand All @@ -81,27 +81,12 @@ inline UInt64 CheckedMul<UInt64>(UInt64 a, UInt64 b)
}

template <>
inline Int64 CheckedMul<Int64>(Int64 a, Int64 b)
inline Int64 CheckedMul<Int64>(Int64 a, Int64 b, bool suggestAlternative)
{
Int64 res = a * b;
if ((a && (res / a != b)) || (b && (res / b != a)))
throwDmsErrD("Overflow in multiplication");
return res;
}

inline UInt64 CheckedMul(UInt64 a, UInt64 b, UInt64*)
{
return CheckedMul<UInt64>(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<UInt32>(a, b);
}

#endif // __RTC_GEO_CHECKEDCALC_H
2 changes: 1 addition & 1 deletion rtc/dll/src/geo/Point.h
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ operator /(const Point<T>& a, const Point<U>& b)


template <class T> inline
SizeT Cardinality(const Point<T>& v) { return CheckedMul<SizeT>(Cardinality(v.first), Cardinality(v.second)); }
SizeT Cardinality(const Point<T>& v) { return CheckedMul<SizeT>(Cardinality(v.first), Cardinality(v.second), false); }

template <class T> inline
typename product_type<T>::type
Expand Down
2 changes: 1 addition & 1 deletion shv/dll/src/GridFill.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ void GridFill(

const grid_rowcol_id* currGridColPtr = gridColBeginPtr;

SizeT currGridRowBegin = CheckedMul<SizeT>(currGridRow, gridSize.Col());
SizeT currGridRowBegin = CheckedMul<SizeT>(currGridRow, gridSize.Col(), false);

GType currViewCol = viewColBegin;
PixelType result;
Expand Down
2 changes: 1 addition & 1 deletion shv/dll/src/ScrollPort.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ TType CalcNewPos(HWND scrollBarCtl, UInt16 scrollCmd, GType nrTPerG)
GType newPos = CalcNewPosBase(scrollBarCtl, scrollCmd);
if (newPos < 0)
return -1;
return CheckedMul<TType>(newPos, nrTPerG);
return CheckedMul<TType>(newPos, nrTPerG, false);
}

void ScrollPort::OnHScroll(UInt16 scollCmd)
Expand Down

0 comments on commit 5e828ff

Please sign in to comment.