diff --git a/build.sh b/build.sh index 79a4f53..d42b855 100755 --- a/build.sh +++ b/build.sh @@ -8,8 +8,6 @@ set -e root=$(readlink -f $(dirname "$0")) me=$(basename $0) -stds="11 1y 1z 2a" - # $1 - name # $2... passed to cmake dobuild() { @@ -30,32 +28,26 @@ fi export CXX export CXXFLAGS -#make a sanitizers debug build with the default compiler, C++17 +#make a full sanitizers debug build with the default compiler, C++17 CXXFLAGS="-fsanitize=undefined,address -g -O0 -std=c++1z -Wall -Wextra" dobuild sanitizers_17 \ -DBUILD_EXAMPLES=On \ --DBUILD_FUZZERS=Off \ -DBUILD_UNITTESTS=On \ -DBUILD_EXHAUSTIVE_TESTS=On \ --DCMAKE_BUILD_TYPE=Debug \ --DFUZZ_LINKMAIN=On +-DCMAKE_BUILD_TYPE=Debug #make sure the examples can be built with c++11 CXXFLAGS="-g -O0 -std=c++11 -Wall -Wextra" dobuild normal_cpp11 \ -DBUILD_EXAMPLES=On \ --DBUILD_FUZZERS=Off \ -DBUILD_UNITTESTS=Off \ --DCMAKE_BUILD_TYPE=Debug \ --DFUZZ_LINKMAIN=On +-DCMAKE_BUILD_TYPE=Debug #make a libfuzzer build with sanitizers CXX=clang++ CXXFLAGS="-fsanitize=fuzzer-no-link,undefined,address -g -O0 -std=c++1z" dobuild libfuzzer_with_sanitizers \ --DBUILD_EXAMPLES=Off \ -DBUILD_FUZZERS=On \ --DBUILD_UNITTESTS=Off \ -DCMAKE_BUILD_TYPE=Debug \ -DFUZZ_LINKMAIN=Off \ -DFUZZ_LDFLAGS=-fsanitize=fuzzer @@ -63,29 +55,9 @@ dobuild libfuzzer_with_sanitizers \ #make a speed measurement build CXXFLAGS="-std=c++1z -Wall -Wextra" dobuild speedtest \ --DBUILD_EXAMPLES=Off \ --DBUILD_FUZZERS=Off \ --DBUILD_UNITTESTS=Off \ -DBUILD_SPEED_TESTS=On \ --DBUILD_EXHAUSTIVE_TESTS=Off \ --DCMAKE_BUILD_TYPE=Release \ --DFUZZ_LINKMAIN=On +-DBUILD_EXHAUSTIVE_TESTS=On \ +-DCMAKE_BUILD_TYPE=Release echo $me: all tests passed -exit 0 - -mkdir "$root/build-sanitizers" -cd "$root/build-sanitizers" -CXX=clang++ CXXFLAGS="-fsanitize=undefined,address -g -O0" \ -cmake $root -DBUILD_EXAMPLES=On -DBUILD_FUZZERS=Off -DBUILD_UNITTESTS=On \ --DCMAKE_BUILD_TYPE=Debug -DFUZZ_LINKMAIN=On -GNinja -ninja - -#make a fuzzer build -mkdir "$root/build-libfuzzer" -cd "$root/build-libfuzzer" -CXX=clang++ CXXFLAGS="-fsanitize=fuzzer-no-link,undefined,address" \ -cmake $root -DBUILD_EXAMPLES=Off -DBUILD_FUZZERS=On -DBUILD_UNITTESTS=Off \ --DCMAKE_BUILD_TYPE=Debug -DFUZZ_LINKMAIN=Off -GNinja -DFUZZ_LDFLAGS=-fsanitize=fuzzer -ninja diff --git a/include/detail/chronoconv_detail.hpp b/include/detail/chronoconv_detail.hpp index 777a97a..a0ca1a9 100644 --- a/include/detail/chronoconv_detail.hpp +++ b/include/detail/chronoconv_detail.hpp @@ -113,22 +113,27 @@ safe_duration_cast_dispatch(From from, int& ec, tags::FromIsInt, tags::ToIsInt) return {}; } // multiply with Factor::num without overflow or underflow - constexpr auto max1 = - std::numeric_limits::max() / Factor::num; - if (count > max1) { - ec = 1; - return {}; - } - constexpr auto min1 = - std::numeric_limits::min() / Factor::num; - if (count < min1) { - ec = 1; - return {}; - } - count *= Factor::num; + if + SDC_CONSTEXPR_IF(Factor::num != 1) + { + constexpr auto max1 = + std::numeric_limits::max() / Factor::num; + if (count > max1) { + ec = 1; + return {}; + } + constexpr auto min1 = + std::numeric_limits::min() / Factor::num; + if (count < min1) { + ec = 1; + return {}; + } + count *= Factor::num; + } // this can't go wrong, right? den>0 is checked earlier. - count /= Factor::den; + if + SDC_CONSTEXPR_IF(Factor::den != 1) { count /= Factor::den; } // convert to the to type, safely using ToRep = typename To::rep; const ToRep tocount = lossless_integral_conversion(count, ec); @@ -212,23 +217,29 @@ safe_duration_cast_dispatch(From from, convert_and_check_cfenv(from.count()); // multiply with Factor::num without overflow or underflow - constexpr auto max1 = - std::numeric_limits::max() / Factor::num; - if (count > max1) { - ec = 1; - return {}; - } - constexpr auto min1 = - std::numeric_limits::lowest() / Factor::num; - if (count < min1) { - ec = 1; - return {}; - } - count *= Factor::num; - assert(std::fetestexcept(FE_INVALID) == 0); + if + SDC_CONSTEXPR_IF(Factor::num != 1) + { + constexpr auto max1 = + std::numeric_limits::max() / Factor::num; + if (count > max1) { + ec = 1; + return {}; + } + constexpr auto min1 = + std::numeric_limits::lowest() / Factor::num; + if (count < min1) { + ec = 1; + return {}; + } + count *= Factor::num; + assert(std::fetestexcept(FE_INVALID) == 0); + } // this can't go wrong, right? den>0 is checked earlier. - count /= Factor::den; + if + SDC_CONSTEXPR_IF(Factor::den != 1) { count /= Factor::den; } + // convert to the to type, safely using ToRep = typename To::rep; diff --git a/tests/chronoconv_floating_test.cpp b/tests/chronoconv_floating_test.cpp index ae18261..ba8ac91 100644 --- a/tests/chronoconv_floating_test.cpp +++ b/tests/chronoconv_floating_test.cpp @@ -128,8 +128,6 @@ TEST_CASE("long double overflow/underflow should be noticed") verifyInternalOverflow(std::numeric_limits::lowest() / 2); } - - /* * make sure the largest finite values are preserved */ @@ -139,10 +137,9 @@ verifyIdentity(Rep val) { using D = std::chrono::duration; int err; - const auto to = - safe_duration_cast::safe_duration_cast(D{ val }, err); + const auto to = safe_duration_cast::safe_duration_cast(D{ val }, err); REQUIRE(err == 0); - REQUIRE(to.count()==val); + REQUIRE(to.count() == val); } TEST_CASE("float limits should be preserved") {