[libcxx-commits] [libcxx] [libc++][ratio] Avoids accepting unrelated types. (PR #80491)
Mark de Wever via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Feb 10 08:27:16 PST 2024
https://github.com/mordante updated https://github.com/llvm/llvm-project/pull/80491
>From e982e810b0dc05fe936c459f93a0cbeda1f8f7fe Mon Sep 17 00:00:00 2001
From: Mark de Wever <koraq at xs4all.nl>
Date: Fri, 2 Feb 2024 21:43:30 +0100
Subject: [PATCH 1/2] [libc++][ratio] Avoids accepting unrelated types.
The arithemtic and comparison operations are ill-formed when R1 or R2 is
not a std::ratio.
Fixes: https://github.com/llvm/llvm-project/issues/63753
---
libcxx/include/ratio | 42 ++++++++--
.../R1_R2_requirement.verify.cpp | 50 ++++++++++++
.../R1_R2_requirement.verify.cpp | 65 ++++++++++++++++
.../R1_R2_requirement_v.verify.cpp | 77 +++++++++++++++++++
4 files changed, 228 insertions(+), 6 deletions(-)
create mode 100644 libcxx/test/std/utilities/ratio/ratio.arithmetic/R1_R2_requirement.verify.cpp
create mode 100644 libcxx/test/std/utilities/ratio/ratio.comparison/R1_R2_requirement.verify.cpp
create mode 100644 libcxx/test/std/utilities/ratio/ratio.comparison/R1_R2_requirement_v.verify.cpp
diff --git a/libcxx/include/ratio b/libcxx/include/ratio
index 3b11a2aa5bf6e7..de656f38e01de6 100644
--- a/libcxx/include/ratio
+++ b/libcxx/include/ratio
@@ -289,6 +289,9 @@ private:
static const intmax_t __gcd_n1_d2 = __static_gcd<_R1::num, _R2::den>::value;
static const intmax_t __gcd_d1_n2 = __static_gcd<_R1::den, _R2::num>::value;
+ static_assert(__is_ratio<_R1>::value, "[ratio.general]/2 requires R1 to be a specialisation of the ratio template");
+ static_assert(__is_ratio<_R2>::value, "[ratio.general]/2 requires R2 to be a specialisation of the ratio template");
+
public:
typedef typename ratio< __ll_mul<_R1::num / __gcd_n1_d2, _R2::num / __gcd_d1_n2>::value,
__ll_mul<_R2::den / __gcd_n1_d2, _R1::den / __gcd_d1_n2>::value >::type type;
@@ -312,6 +315,9 @@ private:
static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value;
static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value;
+ static_assert(__is_ratio<_R1>::value, "[ratio.general]/2 requires R1 to be a specialisation of the ratio template");
+ static_assert(__is_ratio<_R2>::value, "[ratio.general]/2 requires R2 to be a specialisation of the ratio template");
+
public:
typedef typename ratio< __ll_mul<_R1::num / __gcd_n1_n2, _R2::den / __gcd_d1_d2>::value,
__ll_mul<_R2::num / __gcd_n1_n2, _R1::den / __gcd_d1_d2>::value >::type type;
@@ -335,6 +341,9 @@ private:
static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value;
static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value;
+ static_assert(__is_ratio<_R1>::value, "[ratio.general]/2 requires R1 to be a specialisation of the ratio template");
+ static_assert(__is_ratio<_R2>::value, "[ratio.general]/2 requires R2 to be a specialisation of the ratio template");
+
public:
typedef typename ratio_multiply<
ratio<__gcd_n1_n2, _R1::den / __gcd_d1_d2>,
@@ -361,6 +370,9 @@ private:
static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value;
static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value;
+ static_assert(__is_ratio<_R1>::value, "[ratio.general]/2 requires R1 to be a specialisation of the ratio template");
+ static_assert(__is_ratio<_R2>::value, "[ratio.general]/2 requires R2 to be a specialisation of the ratio template");
+
public:
typedef typename ratio_multiply<
ratio<__gcd_n1_n2, _R1::den / __gcd_d1_d2>,
@@ -384,10 +396,16 @@ struct _LIBCPP_TEMPLATE_VIS ratio_subtract : public __ratio_subtract<_R1, _R2>::
// ratio_equal
template <class _R1, class _R2>
-struct _LIBCPP_TEMPLATE_VIS ratio_equal : _BoolConstant<(_R1::num == _R2::num && _R1::den == _R2::den)> {};
+struct _LIBCPP_TEMPLATE_VIS ratio_equal : _BoolConstant<(_R1::num == _R2::num && _R1::den == _R2::den)> {
+ static_assert(__is_ratio<_R1>::value, "[ratio.general]/2 requires R1 to be a specialisation of the ratio template");
+ static_assert(__is_ratio<_R2>::value, "[ratio.general]/2 requires R2 to be a specialisation of the ratio template");
+};
template <class _R1, class _R2>
-struct _LIBCPP_TEMPLATE_VIS ratio_not_equal : _BoolConstant<!ratio_equal<_R1, _R2>::value> {};
+struct _LIBCPP_TEMPLATE_VIS ratio_not_equal : _BoolConstant<!ratio_equal<_R1, _R2>::value> {
+ static_assert(__is_ratio<_R1>::value, "[ratio.general]/2 requires R1 to be a specialisation of the ratio template");
+ static_assert(__is_ratio<_R2>::value, "[ratio.general]/2 requires R2 to be a specialisation of the ratio template");
+};
// ratio_less
@@ -441,16 +459,28 @@ struct __ratio_less<_R1, _R2, -1LL, -1LL> {
};
template <class _R1, class _R2>
-struct _LIBCPP_TEMPLATE_VIS ratio_less : _BoolConstant<__ratio_less<_R1, _R2>::value> {};
+struct _LIBCPP_TEMPLATE_VIS ratio_less : _BoolConstant<__ratio_less<_R1, _R2>::value> {
+ static_assert(__is_ratio<_R1>::value, "[ratio.general]/2 requires R1 to be a specialisation of the ratio template");
+ static_assert(__is_ratio<_R2>::value, "[ratio.general]/2 requires R2 to be a specialisation of the ratio template");
+};
template <class _R1, class _R2>
-struct _LIBCPP_TEMPLATE_VIS ratio_less_equal : _BoolConstant<!ratio_less<_R2, _R1>::value> {};
+struct _LIBCPP_TEMPLATE_VIS ratio_less_equal : _BoolConstant<!ratio_less<_R2, _R1>::value> {
+ static_assert(__is_ratio<_R1>::value, "[ratio.general]/2 requires R1 to be a specialisation of the ratio template");
+ static_assert(__is_ratio<_R2>::value, "[ratio.general]/2 requires R2 to be a specialisation of the ratio template");
+};
template <class _R1, class _R2>
-struct _LIBCPP_TEMPLATE_VIS ratio_greater : _BoolConstant<ratio_less<_R2, _R1>::value> {};
+struct _LIBCPP_TEMPLATE_VIS ratio_greater : _BoolConstant<ratio_less<_R2, _R1>::value> {
+ static_assert(__is_ratio<_R1>::value, "[ratio.general]/2 requires R1 to be a specialisation of the ratio template");
+ static_assert(__is_ratio<_R2>::value, "[ratio.general]/2 requires R2 to be a specialisation of the ratio template");
+};
template <class _R1, class _R2>
-struct _LIBCPP_TEMPLATE_VIS ratio_greater_equal : _BoolConstant<!ratio_less<_R1, _R2>::value> {};
+struct _LIBCPP_TEMPLATE_VIS ratio_greater_equal : _BoolConstant<!ratio_less<_R1, _R2>::value> {
+ static_assert(__is_ratio<_R1>::value, "[ratio.general]/2 requires R1 to be a specialisation of the ratio template");
+ static_assert(__is_ratio<_R2>::value, "[ratio.general]/2 requires R2 to be a specialisation of the ratio template");
+};
template <class _R1, class _R2>
struct __ratio_gcd {
diff --git a/libcxx/test/std/utilities/ratio/ratio.arithmetic/R1_R2_requirement.verify.cpp b/libcxx/test/std/utilities/ratio/ratio.arithmetic/R1_R2_requirement.verify.cpp
new file mode 100644
index 00000000000000..93e9b1903d9407
--- /dev/null
+++ b/libcxx/test/std/utilities/ratio/ratio.arithmetic/R1_R2_requirement.verify.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <ratio>
+//
+// [ratio.general]/2
+// Throughout subclause [ratio], the names of template parameters are
+// used to express type requirements. If a template parameter is named
+// R1 or R2, and the template argument is not a specialization of the
+// ratio template, the program is ill-formed.
+//
+// test ratio_multiply
+
+#include <ratio>
+
+struct R {
+ static const int num = 1;
+ static const int den = 1;
+};
+
+using r = std::ratio<1, 1>;
+
+namespace add {
+using r_r = std::ratio_add<r, r>::type;
+using R_r = std::ratio_add<R, r>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+using r_R = std::ratio_add<r, R>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
+} // namespace add
+
+namespace subtract {
+using r_r = std::ratio_subtract<r, r>::type;
+using R_r = std::ratio_subtract<R, r>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+using r_R = std::ratio_subtract<r, R>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
+} // namespace subtract
+
+namespace multiply {
+using r_r = std::ratio_multiply<r, r>::type;
+using R_r = std::ratio_multiply<R, r>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+using r_R = std::ratio_multiply<r, R>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
+} // namespace multiply
+
+namespace divide {
+using r_r = std::ratio_divide<r, r>::type;
+using R_r = std::ratio_divide<R, r>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+using r_R = std::ratio_divide<r, R>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
+} // namespace divide
diff --git a/libcxx/test/std/utilities/ratio/ratio.comparison/R1_R2_requirement.verify.cpp b/libcxx/test/std/utilities/ratio/ratio.comparison/R1_R2_requirement.verify.cpp
new file mode 100644
index 00000000000000..4371dd99c09fab
--- /dev/null
+++ b/libcxx/test/std/utilities/ratio/ratio.comparison/R1_R2_requirement.verify.cpp
@@ -0,0 +1,65 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <ratio>
+//
+// [ratio.general]/2
+// Throughout subclause [ratio], the names of template parameters are
+// used to express type requirements. If a template parameter is named
+// R1 or R2, and the template argument is not a specialization of the
+// ratio template, the program is ill-formed.
+//
+// Since std::ratio_xxx_v uses the same instantiations only one error
+// will be generated. These values are tested in a separate test.
+
+#include <ratio>
+
+struct R {
+ static const int num = 1;
+ static const int den = 1;
+};
+
+using r = std::ratio<1, 1>;
+
+namespace equal {
+using r_r = std::ratio_equal<r, r>::type;
+using R_r = std::ratio_equal<R, r>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+using r_R = std::ratio_equal<r, R>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
+} // namespace equal
+
+namespace not_equal {
+using r_r = std::ratio_not_equal<r, r>::type;
+using R_r = std::ratio_not_equal<R, r>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+using r_R = std::ratio_not_equal<r, R>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
+} // namespace not_equal
+
+namespace less {
+using r_r = std::ratio_less<r, r>::type;
+using R_r = std::ratio_less<R, r>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+using r_R = std::ratio_less<r, R>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
+} // namespace less
+
+namespace less_equal {
+using r_r = std::ratio_less_equal<r, r>::type;
+using R_r = std::ratio_less_equal<R, r>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+using r_R = std::ratio_less_equal<r, R>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
+} // namespace less_equal
+
+namespace greater {
+using r_r = std::ratio_greater<r, r>::type;
+using R_r = std::ratio_greater<R, r>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+using r_R = std::ratio_greater<r, R>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
+} // namespace greater
+
+namespace greater_equal {
+using r_r = std::ratio_greater_equal<r, r>::type;
+using R_r =
+ std::ratio_greater_equal<R, r>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+using r_R =
+ std::ratio_greater_equal<r, R>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
+} // namespace greater_equal
diff --git a/libcxx/test/std/utilities/ratio/ratio.comparison/R1_R2_requirement_v.verify.cpp b/libcxx/test/std/utilities/ratio/ratio.comparison/R1_R2_requirement_v.verify.cpp
new file mode 100644
index 00000000000000..d30318249c6614
--- /dev/null
+++ b/libcxx/test/std/utilities/ratio/ratio.comparison/R1_R2_requirement_v.verify.cpp
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++17
+
+// <ratio>
+//
+// [ratio.general]/2
+// Throughout subclause [ratio], the names of template parameters are
+// used to express type requirements. If a template parameter is named
+// R1 or R2, and the template argument is not a specialization of the
+// ratio template, the program is ill-formed.
+//
+// Since std::ratio_xxx uses the same instantiations only one error
+// will be generated. These types are tested in a separate test.
+
+#include <ratio>
+
+struct R {
+ constexpr static int num = 1;
+ constexpr static int den = 1;
+};
+
+using r = std::ratio<1, 1>;
+
+namespace equal {
+constexpr bool r_r_v = std::ratio_equal_v<r, r>;
+constexpr bool R_r_v =
+ std::ratio_equal_v<R, r>; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+constexpr bool r_R_v =
+ std::ratio_equal_v<r, R>; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
+} // namespace equal
+
+namespace not_equal {
+constexpr bool r_r_v = std::ratio_not_equal_v<r, r>;
+constexpr bool R_r_v =
+ std::ratio_not_equal_v<R, r>; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+constexpr bool r_R_v =
+ std::ratio_not_equal_v<r, R>; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
+} // namespace not_equal
+
+namespace less {
+constexpr bool r_r_v = std::ratio_less_v<r, r>;
+constexpr bool R_r_v =
+ std::ratio_less_v<R, r>; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+constexpr bool r_R_v =
+ std::ratio_less_v<r, R>; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
+} // namespace less
+
+namespace less_equal {
+constexpr bool r_r_v = std::ratio_less_equal_v<r, r>;
+constexpr bool R_r_v =
+ std::ratio_less_equal_v<R, r>; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+constexpr bool r_R_v =
+ std::ratio_less_equal_v<r, R>; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
+} // namespace less_equal
+
+namespace greater {
+constexpr bool r_r_v = std::ratio_greater_v<r, r>;
+constexpr bool R_r_v =
+ std::ratio_greater_v<R, r>; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+constexpr bool r_R_v =
+ std::ratio_greater_v<r, R>; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
+} // namespace greater
+
+namespace greater_equal {
+constexpr bool r_r_v = std::ratio_greater_equal_v<r, r>;
+constexpr bool R_r_v =
+ std::ratio_greater_equal_v<R, r>; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+constexpr bool r_R_v =
+ std::ratio_greater_equal_v<r, R>; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
+} // namespace greater_equal
>From 1c18400202f32c0fd93e8f724cf4f9e04e1d49ea Mon Sep 17 00:00:00 2001
From: Mark de Wever <koraq at xs4all.nl>
Date: Sat, 10 Feb 2024 14:42:44 +0100
Subject: [PATCH 2/2] address review comments.
---
.../R1_R2_requirement.verify.cpp | 38 ++++----
.../R1_R2_requirement.verify.cpp | 64 ++++++++------
.../R1_R2_requirement_v.verify.cpp | 86 +++++++++----------
3 files changed, 101 insertions(+), 87 deletions(-)
diff --git a/libcxx/test/std/utilities/ratio/ratio.arithmetic/R1_R2_requirement.verify.cpp b/libcxx/test/std/utilities/ratio/ratio.arithmetic/R1_R2_requirement.verify.cpp
index 93e9b1903d9407..9fc91e1f2ce2ef 100644
--- a/libcxx/test/std/utilities/ratio/ratio.arithmetic/R1_R2_requirement.verify.cpp
+++ b/libcxx/test/std/utilities/ratio/ratio.arithmetic/R1_R2_requirement.verify.cpp
@@ -13,38 +13,44 @@
// used to express type requirements. If a template parameter is named
// R1 or R2, and the template argument is not a specialization of the
// ratio template, the program is ill-formed.
-//
-// test ratio_multiply
#include <ratio>
-struct R {
+struct invalid {
static const int num = 1;
static const int den = 1;
};
-using r = std::ratio<1, 1>;
+using valid = std::ratio<1, 1>;
namespace add {
-using r_r = std::ratio_add<r, r>::type;
-using R_r = std::ratio_add<R, r>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
-using r_R = std::ratio_add<r, R>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
+using valid_valid = std::ratio_add<valid, valid>::type;
+using invalid_valid =
+ std::ratio_add<invalid, valid>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+using valid_invalid =
+ std::ratio_add<valid, invalid>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
} // namespace add
namespace subtract {
-using r_r = std::ratio_subtract<r, r>::type;
-using R_r = std::ratio_subtract<R, r>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
-using r_R = std::ratio_subtract<r, R>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
+using valid_valid = std::ratio_subtract<valid, valid>::type;
+using invalid_valid =
+ std::ratio_subtract<invalid, valid>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+using valid_invalid =
+ std::ratio_subtract<valid, invalid>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
} // namespace subtract
namespace multiply {
-using r_r = std::ratio_multiply<r, r>::type;
-using R_r = std::ratio_multiply<R, r>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
-using r_R = std::ratio_multiply<r, R>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
+using valid_valid = std::ratio_multiply<valid, valid>::type;
+using invalid_valid =
+ std::ratio_multiply<invalid, valid>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+using valid_invalid =
+ std::ratio_multiply<valid, invalid>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
} // namespace multiply
namespace divide {
-using r_r = std::ratio_divide<r, r>::type;
-using R_r = std::ratio_divide<R, r>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
-using r_R = std::ratio_divide<r, R>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
+using valid_valid = std::ratio_divide<valid, valid>::type;
+using invalid_valid =
+ std::ratio_divide<invalid, valid>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+using valid_invalid =
+ std::ratio_divide<valid, invalid>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
} // namespace divide
diff --git a/libcxx/test/std/utilities/ratio/ratio.comparison/R1_R2_requirement.verify.cpp b/libcxx/test/std/utilities/ratio/ratio.comparison/R1_R2_requirement.verify.cpp
index 4371dd99c09fab..03bb266b6074d6 100644
--- a/libcxx/test/std/utilities/ratio/ratio.comparison/R1_R2_requirement.verify.cpp
+++ b/libcxx/test/std/utilities/ratio/ratio.comparison/R1_R2_requirement.verify.cpp
@@ -14,52 +14,68 @@
// R1 or R2, and the template argument is not a specialization of the
// ratio template, the program is ill-formed.
//
-// Since std::ratio_xxx_v uses the same instantiations only one error
-// will be generated. These values are tested in a separate test.
+// Since all std::ratio_xxx_v variables use the same instantiation, only one
+// error will be generated. These values are tested in a separate test.
#include <ratio>
-struct R {
+struct invalid {
static const int num = 1;
static const int den = 1;
};
-using r = std::ratio<1, 1>;
+using valid = std::ratio<1, 1>;
namespace equal {
-using r_r = std::ratio_equal<r, r>::type;
-using R_r = std::ratio_equal<R, r>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
-using r_R = std::ratio_equal<r, R>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
+using valid_valid = std::ratio_equal<valid, valid>::type;
+using invalid_valid =
+ std::ratio_equal<invalid, valid>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+using valid_invalid =
+ std::ratio_equal<valid, invalid>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
} // namespace equal
namespace not_equal {
-using r_r = std::ratio_not_equal<r, r>::type;
-using R_r = std::ratio_not_equal<R, r>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
-using r_R = std::ratio_not_equal<r, R>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
+using valid_valid = std::ratio_not_equal<valid, valid>::type;
+using invalid_valid =
+ std::ratio_not_equal<invalid,
+ valid>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+using valid_invalid =
+ std::ratio_not_equal<valid,
+ invalid>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
} // namespace not_equal
namespace less {
-using r_r = std::ratio_less<r, r>::type;
-using R_r = std::ratio_less<R, r>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
-using r_R = std::ratio_less<r, R>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
+using valid_valid = std::ratio_less<valid, valid>::type;
+using invalid_valid =
+ std::ratio_less<invalid, valid>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+using valid_invalid =
+ std::ratio_less<valid, invalid>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
} // namespace less
namespace less_equal {
-using r_r = std::ratio_less_equal<r, r>::type;
-using R_r = std::ratio_less_equal<R, r>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
-using r_R = std::ratio_less_equal<r, R>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
+using valid_valid = std::ratio_less_equal<valid, valid>::type;
+using invalid_valid =
+ std::ratio_less_equal<invalid,
+ valid>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+using valid_invalid =
+ std::ratio_less_equal<valid,
+ invalid>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
} // namespace less_equal
namespace greater {
-using r_r = std::ratio_greater<r, r>::type;
-using R_r = std::ratio_greater<R, r>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
-using r_R = std::ratio_greater<r, R>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
+using valid_valid = std::ratio_greater<valid, valid>::type;
+using invalid_valid =
+ std::ratio_greater<invalid, valid>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+using valid_invalid =
+ std::ratio_greater<valid, invalid>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
} // namespace greater
namespace greater_equal {
-using r_r = std::ratio_greater_equal<r, r>::type;
-using R_r =
- std::ratio_greater_equal<R, r>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
-using r_R =
- std::ratio_greater_equal<r, R>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
+using valid_valid = std::ratio_greater_equal<valid, valid>::type;
+using invalid_valid =
+ std::ratio_greater_equal<invalid,
+ valid>::type; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+using valid_invalid =
+ std::ratio_greater_equal<valid,
+ invalid>::type; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
} // namespace greater_equal
diff --git a/libcxx/test/std/utilities/ratio/ratio.comparison/R1_R2_requirement_v.verify.cpp b/libcxx/test/std/utilities/ratio/ratio.comparison/R1_R2_requirement_v.verify.cpp
index d30318249c6614..fbcf358894cf47 100644
--- a/libcxx/test/std/utilities/ratio/ratio.comparison/R1_R2_requirement_v.verify.cpp
+++ b/libcxx/test/std/utilities/ratio/ratio.comparison/R1_R2_requirement_v.verify.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++17
+// UNSUPPORTED: c++03, c++11, c++14
// <ratio>
//
@@ -16,62 +16,54 @@
// R1 or R2, and the template argument is not a specialization of the
// ratio template, the program is ill-formed.
//
-// Since std::ratio_xxx uses the same instantiations only one error
-// will be generated. These types are tested in a separate test.
+// Since all std::ratio_xxx_v variables use the same instantiation, only one
+// error will be generated. These values are tested in a separate test.
#include <ratio>
-struct R {
+struct invalid {
constexpr static int num = 1;
constexpr static int den = 1;
};
-using r = std::ratio<1, 1>;
+using valid = std::ratio<1, 1>;
-namespace equal {
-constexpr bool r_r_v = std::ratio_equal_v<r, r>;
-constexpr bool R_r_v =
- std::ratio_equal_v<R, r>; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
-constexpr bool r_R_v =
- std::ratio_equal_v<r, R>; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
-} // namespace equal
+void test() {
+ // equal
+ (void)std::ratio_equal_v<valid, valid>;
+ (void)std::ratio_equal_v<invalid, valid>; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+ (void)std::ratio_equal_v<valid, invalid>; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
-namespace not_equal {
-constexpr bool r_r_v = std::ratio_not_equal_v<r, r>;
-constexpr bool R_r_v =
- std::ratio_not_equal_v<R, r>; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
-constexpr bool r_R_v =
- std::ratio_not_equal_v<r, R>; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
-} // namespace not_equal
+ // not_equal
+ (void)std::ratio_not_equal_v<valid, valid>;
+ (void)std::ratio_not_equal_v<invalid,
+ valid>; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+ (void)std::ratio_not_equal_v<valid,
+ invalid>; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
-namespace less {
-constexpr bool r_r_v = std::ratio_less_v<r, r>;
-constexpr bool R_r_v =
- std::ratio_less_v<R, r>; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
-constexpr bool r_R_v =
- std::ratio_less_v<r, R>; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
-} // namespace less
+ // less
+ (void)std::ratio_less_v<valid, valid>;
+ (void)std::ratio_less_v<invalid, valid>; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+ (void)std::ratio_less_v<valid, invalid>; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
-namespace less_equal {
-constexpr bool r_r_v = std::ratio_less_equal_v<r, r>;
-constexpr bool R_r_v =
- std::ratio_less_equal_v<R, r>; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
-constexpr bool r_R_v =
- std::ratio_less_equal_v<r, R>; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
-} // namespace less_equal
+ // less_equal
+ (void)std::ratio_less_equal_v<valid, valid>;
+ (void)std::ratio_less_equal_v<invalid,
+ valid>; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+ (void)std::ratio_less_equal_v<valid,
+ invalid>; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
-namespace greater {
-constexpr bool r_r_v = std::ratio_greater_v<r, r>;
-constexpr bool R_r_v =
- std::ratio_greater_v<R, r>; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
-constexpr bool r_R_v =
- std::ratio_greater_v<r, R>; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
-} // namespace greater
+ // greater
+ (void)std::ratio_greater_v<valid, valid>;
+ (void)std::ratio_greater_v<invalid, valid>; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+ (void)std::ratio_greater_v<valid, invalid>; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
-namespace greater_equal {
-constexpr bool r_r_v = std::ratio_greater_equal_v<r, r>;
-constexpr bool R_r_v =
- std::ratio_greater_equal_v<R, r>; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
-constexpr bool r_R_v =
- std::ratio_greater_equal_v<r, R>; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
-} // namespace greater_equal
+ // greater_equal
+ (void)std::ratio_greater_equal_v<valid, valid>;
+
+ (void)std::ratio_greater_equal_v<invalid,
+ valid>; // expected-error@*:* {{R1 to be a specialisation of the ratio template}}
+
+ (void)std::ratio_greater_equal_v<valid,
+ invalid>; // expected-error@*:* {{R2 to be a specialisation of the ratio template}}
+}
More information about the libcxx-commits
mailing list