Skip to content

Commit

Permalink
Merge pull request #8 from dcleblanc/SafeNegate
Browse files Browse the repository at this point in the history
Safe negate
  • Loading branch information
dcleblanc authored Aug 14, 2019
2 parents b81a4a5 + ea3f011 commit 67e5e59
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 12 deletions.
24 changes: 23 additions & 1 deletion SafeInt.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

/*-----------------------------------------------------------------------------------------------------------
SafeInt.hpp
Version 3.0.20p
Version 3.0.21p
This header implements an integer handling class designed to catch
unsafe integer operations
Expand Down Expand Up @@ -1024,6 +1024,17 @@ template < typename T > class NegationHelper <T, true> // Signed
}
E::SafeIntOnOverflow();
}

_CONSTEXPR14 static bool Negative(T t, T& out)
{
// corner case
if (t != std::numeric_limits<T>::min())
{
out = -t;
return true;
}
return false;
}
};

template < typename T > class NegationHelper <T, false> // unsigned
Expand All @@ -1039,6 +1050,11 @@ template < typename T > class NegationHelper <T, false> // unsigned
return (T)SignedNegation<std::int64_t>::Value(t);
}

_CONSTEXPR14 static bool Negative(T t, T& /*out*/)
{
// This will only be used by the SafeNegation function
return false;
}
};

//core logic to determine casting behavior
Expand Down Expand Up @@ -5597,6 +5613,12 @@ _CONSTEXPR11 inline bool SafeSubtract( T t, U u, T& result ) SAFEINT_NOTHROW
return SubtractionHelper< T, U, SubtractionMethod< T, U >::method >::Subtract( t, u, result );
}

template < typename T >
_CONSTEXPR11 inline bool SafeNegation(T t, T& result) SAFEINT_NOTHROW
{
return NegationHelper< T, std::numeric_limits<T>::is_signed>::Negative(t, result);
}

/***************** end external functions ************************************/

// Main SafeInt class
Expand Down
1 change: 1 addition & 0 deletions Test/ClangTest/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
SafeIntTest
CompileTest
CompileTest14
62 changes: 62 additions & 0 deletions Test/SubVerify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6954,4 +6954,66 @@ void SubVerify()
SubVerifyInt8Int8();
}

}

namespace negation_verify
{
template < typename T >
void NegationVerifyT()
{
T minInt = std::numeric_limits<T>::min();
T test = 2;
bool result = false;
T out = 0;

try
{
out = -SafeInt< T >(minInt);
}
catch (...)
{
result = true;
}

if (result == false)
cerr << "Error in NegationVerifyT throw (1): ";

try
{
out = -SafeInt< T >(test);
}
catch (...)
{
result = false;
}

if (result == false)
cerr << "Error in NegationVerifyT throw (2): ";

// Now try the non-throwing version

result = SafeNegation(minInt, out);

if (result != false)
cerr << "Error in NegationVerifyT nothrow (1): ";

result = SafeNegation(test, out);

if (result == false)
cerr << "Error in NegationVerifyT nothrow (2): ";
}

void NegationVerifyAll()
{
NegationVerifyT< std::int8_t>();
NegationVerifyT< std::int16_t>();
NegationVerifyT< std::int32_t>();
NegationVerifyT< std::int64_t>();
}

void NegationVerify()
{
cout << "Verifying Negation:" << endl;
NegationVerifyAll();
}
}
18 changes: 9 additions & 9 deletions Test/TestMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@

int main(int, char**)
{
cast_verify::CastVerify();
mult_verify::MultVerify();
div_verify::DivVerify();
sub_verify::SubVerify();
add_verify::AddVerify();
mod_verify::ModVerify();
incdec_verify::IncDecVerify();

return 0;
cast_verify::CastVerify();
mult_verify::MultVerify();
div_verify::DivVerify();
sub_verify::SubVerify();
add_verify::AddVerify();
mod_verify::ModVerify();
incdec_verify::IncDecVerify();
negation_verify::NegationVerify();
return 0;
}
5 changes: 3 additions & 2 deletions Test/TestMain.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ using std::dec;

// Suppress warnings in test files, but not in source header
#if SAFEINT_COMPILER == VISUAL_STUDIO_COMPILER

#pragma warning(disable: 4838 4477 4310)
// Disable Spectre mitigation warnings (5045)
#pragma warning(disable: 4838 4477 4310 5045)
#elif SAFEINT_COMPILER == CLANG_COMPILER
#pragma GCC diagnostic ignored "-Wc++11-narrowing"
#pragma GCC diagnostic ignored "-Wformat"
Expand All @@ -52,4 +52,5 @@ namespace add_verify { void AddVerify(); }
namespace mod_verify { void ModVerify(); }
namespace incdec_verify { void IncDecVerify(); }
namespace cast_verify { void CastVerify(); }
namespace negation_verify { void NegationVerify(); }

0 comments on commit 67e5e59

Please sign in to comment.