aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2016-12-15 14:39:52 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2016-12-16 14:57:15 +0000
commit8611bda3b346762e0589402f130b73f20dd75914 (patch)
tree3da6d62b83087371c0b6baa4516392f9dbc2bf5b
parent68d6802ae6f132108870b07627cc00f75eb58104 (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.h47
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;
}
};