Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1848)

Unified Diff: base/numerics/safe_math_impl.h

Issue 2554803002: Cleanup some undefined floating point behavior in base/numerics (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« base/numerics/safe_conversions.h ('K') | « base/numerics/safe_conversions.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/numerics/safe_math_impl.h
diff --git a/base/numerics/safe_math_impl.h b/base/numerics/safe_math_impl.h
index 679cfa4e5a0e73c84b541128ed9f9e963b3f2262..57497a2abb4139db2ce223cead8fc49457b0c58d 100644
--- a/base/numerics/safe_math_impl.h
+++ b/base/numerics/safe_math_impl.h
@@ -635,6 +635,19 @@ class CheckedNumericState<T, NUMERIC_INTEGER> {
bool is_valid_;
T value_;
+ // Ensures that a type conversion does not trigger undefined behavior.
+ template <typename Src>
+ static constexpr T WellDefinedConversionOrZero(const Src value,
+ const bool is_valid) {
+ using SrcType = typename internal::UnderlyingType<Src>::type;
+ return (std::is_integral<Src>::value ||
Nico 2016/12/06 14:03:37 Nice!
+ StaticDstRangeRelationToSrcRange<T, SrcType>::value ==
+ NUMERIC_RANGE_CONTAINED ||
Nico 2016/12/06 14:03:38 Isn't the is_integral check on Src stronger than t
jschuh 2016/12/06 15:07:55 Weird. Somehow I posted this in an incomplete stat
+ is_valid)
+ ? static_cast<T>(value)
+ : static_cast<T>(0);
+ }
+
public:
template <typename Src, NumericRepresentation type>
friend class CheckedNumericState;
@@ -644,7 +657,7 @@ class CheckedNumericState<T, NUMERIC_INTEGER> {
template <typename Src>
constexpr CheckedNumericState(Src value, bool is_valid)
: is_valid_(is_valid && IsValueInRangeForNumericType<T>(value)),
- value_(is_valid_ ? static_cast<T>(value) : 0) {
+ value_(WellDefinedConversionOrZero(value, is_valid_)) {
static_assert(std::is_arithmetic<Src>::value, "Argument must be numeric.");
}
@@ -652,12 +665,12 @@ class CheckedNumericState<T, NUMERIC_INTEGER> {
template <typename Src>
constexpr CheckedNumericState(const CheckedNumericState<Src>& rhs)
: is_valid_(rhs.IsValid()),
- value_(is_valid_ ? static_cast<T>(rhs.value()) : 0) {}
+ value_(WellDefinedConversionOrZero(rhs.value(), is_valid_)) {}
template <typename Src>
constexpr explicit CheckedNumericState(Src value)
: is_valid_(IsValueInRangeForNumericType<T>(value)),
- value_(is_valid_ ? static_cast<T>(value) : 0) {}
+ value_(WellDefinedConversionOrZero(value, is_valid_)) {}
constexpr bool is_valid() const { return is_valid_; }
constexpr T value() const { return value_; }
« base/numerics/safe_conversions.h ('K') | « base/numerics/safe_conversions.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698