diff options
author | Marshall Clow <mclow.lists@gmail.com> | 2019-04-01 16:38:02 +0000 |
---|---|---|
committer | Marshall Clow <mclow.lists@gmail.com> | 2019-04-01 16:38:02 +0000 |
commit | efa6d803c624f9251d0ab7881122501bb9d27368 (patch) | |
tree | b00dad7fc97cd2c6a2e2c92cd1d87c5c738acd88 /libcxx/test/std/utilities | |
parent | 2a67c910764b6c20f6d146797b354dfb0028bd52 (diff) | |
download | bcm5719-llvm-efa6d803c624f9251d0ab7881122501bb9d27368.tar.gz bcm5719-llvm-efa6d803c624f9251d0ab7881122501bb9d27368.zip |
Fix PR41130 - 'operator/ of std::chrono::duration and custom type'. Thanks to Zulan for the report, and Howard for the direction of the fix.
llvm-svn: 357410
Diffstat (limited to 'libcxx/test/std/utilities')
8 files changed, 127 insertions, 2 deletions
diff --git a/libcxx/test/std/utilities/time/rep.h b/libcxx/test/std/utilities/time/rep.h index f54eef3efe7..45a7b1db174 100644 --- a/libcxx/test/std/utilities/time/rep.h +++ b/libcxx/test/std/utilities/time/rep.h @@ -25,4 +25,40 @@ public: Rep& operator/=(Rep x) {data_ /= x.data_; return *this;} }; +// This is PR#41130 + +struct NotARep {}; + +// std::chrono:::duration has only '*', '/' and '%' taking a "Rep" parameter + +// Multiplication is commutative, division is not. +template <class Rep, class Period> +std::chrono::duration<Rep, Period> +operator*(std::chrono::duration<Rep, Period> d, NotARep) { return d; } + +template <class Rep, class Period> +std::chrono::duration<Rep, Period> +operator*(NotARep, std::chrono::duration<Rep, Period> d) { return d; } + +template <class Rep, class Period> +std::chrono::duration<Rep, Period> +operator/(std::chrono::duration<Rep, Period> d, NotARep) { return d; } + +template <class Rep, class Period> +std::chrono::duration<Rep, Period> +operator%(std::chrono::duration<Rep, Period> d, NotARep) { return d; } + +// op= is not commutative. +template <class Rep, class Period> +std::chrono::duration<Rep, Period>& +operator*=(std::chrono::duration<Rep, Period>& d, NotARep) { return d; } + +template <class Rep, class Period> +std::chrono::duration<Rep, Period>& +operator/=(std::chrono::duration<Rep, Period>& d, NotARep) { return d; } + +template <class Rep, class Period> +std::chrono::duration<Rep, Period>& +operator%=(std::chrono::duration<Rep, Period>& d, NotARep) { return d; } + #endif // REP_H diff --git a/libcxx/test/std/utilities/time/time.duration/time.duration.arithmetic/op_divide=.pass.cpp b/libcxx/test/std/utilities/time/time.duration/time.duration.arithmetic/op_divide=.pass.cpp index 753ea5a8bc1..64b08a86beb 100644 --- a/libcxx/test/std/utilities/time/time.duration/time.duration.arithmetic/op_divide=.pass.cpp +++ b/libcxx/test/std/utilities/time/time.duration/time.duration.arithmetic/op_divide=.pass.cpp @@ -16,6 +16,7 @@ #include <cassert> #include "test_macros.h" +#include "../../rep.h" #if TEST_STD_VER > 14 constexpr bool test_constexpr() @@ -38,5 +39,14 @@ int main(int, char**) static_assert(test_constexpr(), ""); #endif +#if TEST_STD_VER >= 11 + { // This is PR#41130 + std::chrono::nanoseconds d(5); + NotARep n; + d /= n; + assert(d.count() == 5); + } +#endif + return 0; } diff --git a/libcxx/test/std/utilities/time/time.duration/time.duration.arithmetic/op_mod=duration.pass.cpp b/libcxx/test/std/utilities/time/time.duration/time.duration.arithmetic/op_mod=duration.pass.cpp index 649f4aa1a4c..499a06e2738 100644 --- a/libcxx/test/std/utilities/time/time.duration/time.duration.arithmetic/op_mod=duration.pass.cpp +++ b/libcxx/test/std/utilities/time/time.duration/time.duration.arithmetic/op_mod=duration.pass.cpp @@ -16,6 +16,7 @@ #include <cassert> #include "test_macros.h" +#include "../../rep.h" #if TEST_STD_VER > 14 constexpr bool test_constexpr() @@ -42,5 +43,14 @@ int main(int, char**) static_assert(test_constexpr(), ""); #endif +#if TEST_STD_VER >= 11 + { // This is PR#41130 + std::chrono::nanoseconds d(5); + NotARep n; + d %= n; + assert(d.count() == 5); + } +#endif + return 0; } diff --git a/libcxx/test/std/utilities/time/time.duration/time.duration.arithmetic/op_mod=rep.pass.cpp b/libcxx/test/std/utilities/time/time.duration/time.duration.arithmetic/op_mod=rep.pass.cpp index 0eb73ee674f..f5ef512381a 100644 --- a/libcxx/test/std/utilities/time/time.duration/time.duration.arithmetic/op_mod=rep.pass.cpp +++ b/libcxx/test/std/utilities/time/time.duration/time.duration.arithmetic/op_mod=rep.pass.cpp @@ -17,6 +17,11 @@ #include "test_macros.h" +class NotARep {}; + +typedef std::chrono::seconds Duration; +Duration operator%=(Duration d, NotARep) { return d; } + #if TEST_STD_VER > 14 constexpr bool test_constexpr() { @@ -38,5 +43,15 @@ int main(int, char**) static_assert(test_constexpr(), ""); #endif +#if TEST_STD_VER >= 11 + { // This is PR#41130 + Duration d(5); + NotARep n; + d %= n; + assert(d.count() == 5); + } +#endif + + return 0; } diff --git a/libcxx/test/std/utilities/time/time.duration/time.duration.arithmetic/op_times=.pass.cpp b/libcxx/test/std/utilities/time/time.duration/time.duration.arithmetic/op_times=.pass.cpp index 51c20c50764..06c98556e47 100644 --- a/libcxx/test/std/utilities/time/time.duration/time.duration.arithmetic/op_times=.pass.cpp +++ b/libcxx/test/std/utilities/time/time.duration/time.duration.arithmetic/op_times=.pass.cpp @@ -16,6 +16,7 @@ #include <cassert> #include "test_macros.h" +#include "../../rep.h" #if TEST_STD_VER > 14 constexpr bool test_constexpr() @@ -38,5 +39,14 @@ int main(int, char**) static_assert(test_constexpr(), ""); #endif +#if TEST_STD_VER >= 11 + { // This is PR#41130 + std::chrono::nanoseconds d(5); + NotARep n; + d *= n; + assert(d.count() == 5); + } +#endif + return 0; } diff --git a/libcxx/test/std/utilities/time/time.duration/time.duration.nonmember/op_divide_rep.pass.cpp b/libcxx/test/std/utilities/time/time.duration/time.duration.nonmember/op_divide_rep.pass.cpp index 94da11302bf..8b623aabe9e 100644 --- a/libcxx/test/std/utilities/time/time.duration/time.duration.nonmember/op_divide_rep.pass.cpp +++ b/libcxx/test/std/utilities/time/time.duration/time.duration.nonmember/op_divide_rep.pass.cpp @@ -19,11 +19,14 @@ #include <cassert> #include "test_macros.h" +#include "../../rep.h" int main(int, char**) { { - std::chrono::nanoseconds ns(15); + typedef std::chrono::nanoseconds Dur; + Dur ns(15); + ASSERT_SAME_TYPE(Dur, decltype(ns / 5)); ns = ns / 5; assert(ns.count() == 3); } @@ -35,5 +38,16 @@ int main(int, char**) } #endif +#if TEST_STD_VER >= 11 + { // This is PR#41130 + typedef std::chrono::nanoseconds Duration; + Duration d(5); + NotARep n; + ASSERT_SAME_TYPE(Duration, decltype(d / n)); + d = d / n; + assert(d.count() == 5); + } +#endif + return 0; } diff --git a/libcxx/test/std/utilities/time/time.duration/time.duration.nonmember/op_mod_rep.pass.cpp b/libcxx/test/std/utilities/time/time.duration/time.duration.nonmember/op_mod_rep.pass.cpp index 754b9800a7d..0878aff6484 100644 --- a/libcxx/test/std/utilities/time/time.duration/time.duration.nonmember/op_mod_rep.pass.cpp +++ b/libcxx/test/std/utilities/time/time.duration/time.duration.nonmember/op_mod_rep.pass.cpp @@ -19,11 +19,14 @@ #include <cassert> #include "test_macros.h" +#include "../../rep.h" int main(int, char**) { { - std::chrono::nanoseconds ns(15); + typedef std::chrono::nanoseconds Dur; + Dur ns(15); + ASSERT_SAME_TYPE(Dur, decltype(ns % 6)); ns = ns % 6; assert(ns.count() == 3); } @@ -35,5 +38,16 @@ int main(int, char**) } #endif +#if TEST_STD_VER >= 11 + { // This is PR#41130 + typedef std::chrono::seconds Duration; + Duration d(5); + NotARep n; + ASSERT_SAME_TYPE(Duration, decltype(d % n)); + d = d % n; + assert(d.count() == 5); + } +#endif + return 0; } diff --git a/libcxx/test/std/utilities/time/time.duration/time.duration.nonmember/op_times_rep.pass.cpp b/libcxx/test/std/utilities/time/time.duration/time.duration.nonmember/op_times_rep.pass.cpp index c3e49963808..c3310323128 100644 --- a/libcxx/test/std/utilities/time/time.duration/time.duration.nonmember/op_times_rep.pass.cpp +++ b/libcxx/test/std/utilities/time/time.duration/time.duration.nonmember/op_times_rep.pass.cpp @@ -24,6 +24,7 @@ #include <cassert> #include "test_macros.h" +#include "../../rep.h" int main(int, char**) { @@ -34,6 +35,7 @@ int main(int, char**) ns = 6 * ns; assert(ns.count() == 90); } + #if TEST_STD_VER >= 11 { constexpr std::chrono::nanoseconds ns(3); @@ -44,5 +46,19 @@ int main(int, char**) } #endif +#if TEST_STD_VER >= 11 + { // This is related to PR#41130 + typedef std::chrono::nanoseconds Duration; + Duration d(5); + NotARep n; + ASSERT_SAME_TYPE(Duration, decltype(d * n)); + ASSERT_SAME_TYPE(Duration, decltype(n * d)); + d = d * n; + assert(d.count() == 5); + d = n * d; + assert(d.count() == 5); + } +#endif + return 0; } |