Index: third_party/WebKit/Source/wtf/StdLibExtras.h |
diff --git a/third_party/WebKit/Source/wtf/StdLibExtras.h b/third_party/WebKit/Source/wtf/StdLibExtras.h |
index 824c579a358dad705caacc8e528fe0d1ba322fe0..efaa3c65142fedce8a99dce73595bc5f6fac15b7 100644 |
--- a/third_party/WebKit/Source/wtf/StdLibExtras.h |
+++ b/third_party/WebKit/Source/wtf/StdLibExtras.h |
@@ -153,10 +153,40 @@ inline TO bitwise_cast(FROM from) |
template<typename To, typename From> |
inline To safeCast(From value) |
{ |
- ASSERT(isInBounds<To>(value)); |
+ RELEASE_ASSERT(isInBounds<To>(value)); |
return static_cast<To>(value); |
} |
+// Use the following macros to prevent errors caused by accidental |
+// implicit casting of function arguments. For example, this can |
+// be used to prevent overflows from non-promoting conversions. |
+// |
+// Example: |
+// |
+// HAS_STRICTLY_TYPED_ARG |
+// void sendData(void* data, STRICTLY_TYPED_ARG(size)) |
+// { |
+// ALLOW_NUMERIC_ARG_TYPES_PROMOTABLE_TO(size_t); |
+// ... |
+// } |
+// |
+// The previous example will prevent callers from passing, for example, an |
+// 'int'. On a 32-bit build, it will prevent use of an 'unsigned long long'. |
+#define HAS_STRICTLY_TYPED_ARG template<typename ActualArgType> |
+#define STRICTLY_TYPED_ARG(argName) ActualArgType argName |
+#define STRICT_ARG_TYPE(ExpectedArgType) \ |
+ static_assert(std::is_same<ActualArgType, ExpectedArgType>::value, \ |
+ "Strictly typed argument must be of type '" #ExpectedArgType "'." ) |
+#define ALLOW_NUMERIC_ARG_TYPES_PROMOTABLE_TO(ExpectedArgType) \ |
+ static_assert(std::numeric_limits<ExpectedArgType>::is_integer == std::numeric_limits<ActualArgType>::is_integer, \ |
+ "Conversion between integer and non-integer types not allowed."); \ |
+ static_assert(sizeof(ExpectedArgType) >= sizeof(ActualArgType), \ |
+ "Truncating conversions not allowed."); \ |
+ static_assert(!std::numeric_limits<ActualArgType>::is_signed || std::numeric_limits<ExpectedArgType>::is_signed, \ |
+ "Signed to unsigned conversion not allowed."); \ |
+ static_assert((sizeof(ExpectedArgType) != sizeof(ActualArgType)) || (std::numeric_limits<ActualArgType>::is_signed == std::numeric_limits<ExpectedArgType>::is_signed), \ |
+ "Unsigned to signed conversion not allowed for types with identical size (could overflow)."); |
+ |
// Macro that returns a compile time constant with the length of an array, but gives an error if passed a non-array. |
template<typename T, size_t Size> char (&ArrayLengthHelperFunction(T (&)[Size]))[Size]; |
// GCC needs some help to deduce a 0 length array. |