diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2016-12-15 14:39:52 +0100 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2016-12-16 14:57:15 +0000 |
commit | 8611bda3b346762e0589402f130b73f20dd75914 (patch) | |
tree | 3da6d62b83087371c0b6baa4516392f9dbc2bf5b | |
parent | 68d6802ae6f132108870b07627cc00f75eb58104 (diff) |
libshiboken: Output a warning when integer overflows occur
Output type and size.
Change-Id: Id24fe755e3be9f8d2afe9c668dafe49ad6ec42c7
Reviewed-by: Christian Tismer <tismer@stackless.com>
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
-rw-r--r-- | libshiboken/sbkconverter_p.h | 47 |
1 files changed, 38 insertions, 9 deletions
diff --git a/libshiboken/sbkconverter_p.h b/libshiboken/sbkconverter_p.h index 2a18578..d511620 100644 --- a/libshiboken/sbkconverter_p.h +++ b/libshiboken/sbkconverter_p.h @@ -45,6 +45,9 @@ #include "sbkstring.h" #include <list> #include <limits> +#include <typeinfo> +#include <sstream> +#include <iostream> #include "sbkdbg.h" @@ -106,20 +109,42 @@ struct SbkConverter } // extern "C" +template<typename T, bool isSigned> +struct OverFlowCheckerBase { + static void formatOverFlowMessage(const PY_LONG_LONG& value) + { + std::ostringstream str; + str << "libshiboken: Overflow: Value " << value << " exceeds limits of type " + << " [" << (isSigned ? "signed" : "unsigned") + << "] \"" << typeid(T).name() + << "\" (" << sizeof(T) << "bytes)."; + const std::string message = str.str(); + PyErr_WarnEx(PyExc_RuntimeWarning, message.c_str(), 0); + } +}; + // Helper template for checking if a value overflows when cast to type T. template<typename T, bool isSigned = std::numeric_limits<T>::is_signed > struct OverFlowChecker; template<typename T> -struct OverFlowChecker<T, true> { - static bool check(const PY_LONG_LONG& value) { - return value < std::numeric_limits<T>::min() || value > std::numeric_limits<T>::max(); +struct OverFlowChecker<T, true> : public OverFlowCheckerBase<T, true> { + static bool check(const PY_LONG_LONG& value) + { + const bool result = value < std::numeric_limits<T>::min() || value > std::numeric_limits<T>::max(); + if (result) + OverFlowChecker::formatOverFlowMessage(value); + return result; } }; template<typename T> -struct OverFlowChecker<T, false> { - static bool check(const PY_LONG_LONG& value) { - return value < 0 || static_cast<unsigned long long>(value) > std::numeric_limits<T>::max(); +struct OverFlowChecker<T, false> : public OverFlowCheckerBase<T, false> { + static bool check(const PY_LONG_LONG& value) + { + const bool result = value < 0 || static_cast<unsigned long long>(value) > std::numeric_limits<T>::max(); + if (result) + OverFlowChecker::formatOverFlowMessage(value); + return result; } }; template<> @@ -131,9 +156,13 @@ struct OverFlowChecker<double, true> { static bool check(const double &) { return false; } }; template<> -struct OverFlowChecker<float, true> { - static bool check(const double& value) { - return value < std::numeric_limits<float>::min() || value > std::numeric_limits<float>::max(); +struct OverFlowChecker<float, true> : public OverFlowCheckerBase<float, true> { + static bool check(const double& value) + { + const bool result = value < std::numeric_limits<float>::min() || value > std::numeric_limits<float>::max(); + if (result) + formatOverFlowMessage(value); + return result; } }; |