From: Fred Morcos Date: Mon, 21 Mar 2022 13:52:55 +0000 (+0100) Subject: Checked int conversions: Avoid checks when boundary values are equal X-Git-Tag: rec-4.7.0-beta1~41^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=bfd1f31bddfe3d214652274aff6f9edf88eb334b;p=thirdparty%2Fpdns.git Checked int conversions: Avoid checks when boundary values are equal --- diff --git a/pdns/misc.hh b/pdns/misc.hh index 4d27de7017..aee835b063 100644 --- a/pdns/misc.hh +++ b/pdns/misc.hh @@ -656,8 +656,20 @@ auto checked_conv(F from) -> T static_assert((std::numeric_limits::is_signed && std::numeric_limits::is_signed) || (!std::numeric_limits::is_signed && !std::numeric_limits::is_signed), "checked_conv: The `T` and `F` types must either both be signed or unsigned"); - if (from < std::numeric_limits::min() || from > std::numeric_limits::max()) { - throw std::out_of_range("checked_conv: conversion from value that is out of range for target type"); + constexpr auto tMin = std::numeric_limits::min(); + if constexpr (std::numeric_limits::min() != tMin) { + if (from < tMin) { + string s = "checked_conv: source value " + std::to_string(from) + " is smaller than target's minimum possible value " + std::to_string(tMin); + throw std::out_of_range(s); + } + } + + constexpr auto tMax = std::numeric_limits::max(); + if constexpr (std::numeric_limits::max() != tMax) { + if (from > tMax) { + string s = "checked_conv: source value " + std::to_string(from) + " is larger than target's maximum possible value " + std::to_string(tMax); + throw std::out_of_range(s); + } } return static_cast(from);