Skip to content

Commit

Permalink
#1 don't divide or multiply with 1
Browse files Browse the repository at this point in the history
  • Loading branch information
pauldreik committed May 27, 2019
1 parent 6248d08 commit ccacbd1
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 67 deletions.
38 changes: 5 additions & 33 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -30,62 +28,36 @@ 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

#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

69 changes: 40 additions & 29 deletions include/detail/chronoconv_detail.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<IntermediateRep>::max() / Factor::num;
if (count > max1) {
ec = 1;
return {};
}
constexpr auto min1 =
std::numeric_limits<IntermediateRep>::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<IntermediateRep>::max() / Factor::num;
if (count > max1) {
ec = 1;
return {};
}
constexpr auto min1 =
std::numeric_limits<IntermediateRep>::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<ToRep>(count, ec);
Expand Down Expand Up @@ -212,23 +217,29 @@ safe_duration_cast_dispatch(From from,
convert_and_check_cfenv<IntermediateRep>(from.count());

// multiply with Factor::num without overflow or underflow
constexpr auto max1 =
std::numeric_limits<IntermediateRep>::max() / Factor::num;
if (count > max1) {
ec = 1;
return {};
}
constexpr auto min1 =
std::numeric_limits<IntermediateRep>::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<IntermediateRep>::max() / Factor::num;
if (count > max1) {
ec = 1;
return {};
}
constexpr auto min1 =
std::numeric_limits<IntermediateRep>::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;

Expand Down
7 changes: 2 additions & 5 deletions tests/chronoconv_floating_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,6 @@ TEST_CASE("long double overflow/underflow should be noticed")
verifyInternalOverflow(std::numeric_limits<long double>::lowest() / 2);
}



/*
* make sure the largest finite values are preserved
*/
Expand All @@ -139,10 +137,9 @@ verifyIdentity(Rep val)
{
using D = std::chrono::duration<Rep>;
int err;
const auto to =
safe_duration_cast::safe_duration_cast<D>(D{ val }, err);
const auto to = safe_duration_cast::safe_duration_cast<D>(D{ val }, err);
REQUIRE(err == 0);
REQUIRE(to.count()==val);
REQUIRE(to.count() == val);
}
TEST_CASE("float limits should be preserved")
{
Expand Down

0 comments on commit ccacbd1

Please sign in to comment.