[libcxx-commits] [libcxx] [libc++] Fix acceptance of convertible-to-{float, double, long double} in std::isnan() and std::isinf() (PR #98952)
Robin Caloudis via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Jul 16 11:59:37 PDT 2024
https://github.com/robincaloudis updated https://github.com/llvm/llvm-project/pull/98952
>From 0f97ac1a6bbc4736c369e90e3a1195c838dcacfb Mon Sep 17 00:00:00 2001
From: Robin Caloudis <robin.caloudis at gmx.de>
Date: Mon, 15 Jul 2024 22:04:22 +0200
Subject: [PATCH 1/5] Test convertibles in std::isinf()
---
.../test/std/numerics/c.math/isinf.pass.cpp | 21 +++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/libcxx/test/std/numerics/c.math/isinf.pass.cpp b/libcxx/test/std/numerics/c.math/isinf.pass.cpp
index e935b53187fe6..99aab191c4977 100644
--- a/libcxx/test/std/numerics/c.math/isinf.pass.cpp
+++ b/libcxx/test/std/numerics/c.math/isinf.pass.cpp
@@ -62,9 +62,30 @@ struct TestInt {
}
};
+struct ConvertibleFloat {
+ int value;
+ ConvertibleFloat(int v) : value(v) {}
+ operator float() const { return static_cast<float>(value); }
+};
+
+struct ConvertibleDouble {
+ int value;
+ ConvertibleDouble(int v) : value(v) {}
+ operator double() const { return static_cast<double>(value); }
+};
+
+struct ConvertibleLongDouble {
+ int value;
+ ConvertibleLongDouble(int v) : value(v) {}
+ operator long double() const { return static_cast<long double>(value); }
+};
+
int main(int, char**) {
types::for_each(types::floating_point_types(), TestFloat());
types::for_each(types::integral_types(), TestInt());
+ assert(!std::isinf(ConvertibleFloat(0)));
+ assert(!std::isinf(ConvertibleDouble(0)));
+ assert(!std::isinf(ConvertibleLongDouble(0)));
return 0;
}
>From 41b2677b4fd8e7ba9ad7e9dc0d0118b6353867d3 Mon Sep 17 00:00:00 2001
From: Robin Caloudis <robin.caloudis at gmx.de>
Date: Mon, 15 Jul 2024 22:05:02 +0200
Subject: [PATCH 2/5] Remove preprocessor directive
---
libcxx/include/__math/traits.h | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/libcxx/include/__math/traits.h b/libcxx/include/__math/traits.h
index a448266797557..fc713b1021be2 100644
--- a/libcxx/include/__math/traits.h
+++ b/libcxx/include/__math/traits.h
@@ -67,20 +67,17 @@ _LIBCPP_NODISCARD _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf
return false;
}
-#ifdef _LIBCPP_PREFERRED_OVERLOAD
_LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(float __x) _NOEXCEPT {
return __builtin_isinf(__x);
}
-_LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _LIBCPP_PREFERRED_OVERLOAD bool
-isinf(double __x) _NOEXCEPT {
+_LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(double __x) _NOEXCEPT {
return __builtin_isinf(__x);
}
_LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(long double __x) _NOEXCEPT {
return __builtin_isinf(__x);
}
-#endif
// isnan
>From 4edaeb508132a38aaac2484facca630fa36fbd55 Mon Sep 17 00:00:00 2001
From: Robin Caloudis <robin.caloudis at gmx.de>
Date: Mon, 15 Jul 2024 22:05:20 +0200
Subject: [PATCH 3/5] Test convertibles in std::isnan()
---
.../test/std/numerics/c.math/isnan.pass.cpp | 21 +++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/libcxx/test/std/numerics/c.math/isnan.pass.cpp b/libcxx/test/std/numerics/c.math/isnan.pass.cpp
index fffb124645862..374aa08a600d6 100644
--- a/libcxx/test/std/numerics/c.math/isnan.pass.cpp
+++ b/libcxx/test/std/numerics/c.math/isnan.pass.cpp
@@ -62,9 +62,30 @@ struct TestInt {
}
};
+struct ConvertibleFloat {
+ int value;
+ ConvertibleFloat(int v) : value(v) {}
+ operator float() const { return static_cast<float>(value); }
+};
+
+struct ConvertibleDouble {
+ int value;
+ ConvertibleDouble(int v) : value(v) {}
+ operator double() const { return static_cast<double>(value); }
+};
+
+struct ConvertibleLongDouble {
+ int value;
+ ConvertibleLongDouble(int v) : value(v) {}
+ operator long double() const { return static_cast<long double>(value); }
+};
+
int main(int, char**) {
types::for_each(types::floating_point_types(), TestFloat());
types::for_each(types::integral_types(), TestInt());
+ assert(!std::isnan(ConvertibleFloat(0)));
+ assert(!std::isnan(ConvertibleDouble(0)));
+ assert(!std::isnan(ConvertibleLongDouble(0)));
return 0;
}
>From 903a82a687416cc18b5b6de6d942e66d9196979a Mon Sep 17 00:00:00 2001
From: Robin Caloudis <robin.caloudis at gmx.de>
Date: Tue, 16 Jul 2024 20:58:15 +0200
Subject: [PATCH 4/5] Remove preprocessor directive in std::isnan()
---
libcxx/include/__math/traits.h | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/libcxx/include/__math/traits.h b/libcxx/include/__math/traits.h
index fc713b1021be2..d58c5c5637967 100644
--- a/libcxx/include/__math/traits.h
+++ b/libcxx/include/__math/traits.h
@@ -91,20 +91,17 @@ _LIBCPP_NODISCARD _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan
return false;
}
-#ifdef _LIBCPP_PREFERRED_OVERLOAD
_LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(float __x) _NOEXCEPT {
return __builtin_isnan(__x);
}
-_LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _LIBCPP_PREFERRED_OVERLOAD bool
-isnan(double __x) _NOEXCEPT {
+_LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(double __x) _NOEXCEPT {
return __builtin_isnan(__x);
}
_LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(long double __x) _NOEXCEPT {
return __builtin_isnan(__x);
}
-#endif
// isnormal
>From f7b9ecad13baec5bcad5c7835fe336a661568887 Mon Sep 17 00:00:00 2001
From: Robin Caloudis <robin.caloudis at gmx.de>
Date: Tue, 16 Jul 2024 20:58:37 +0200
Subject: [PATCH 5/5] Extract template and leave comment
---
.../test/std/numerics/c.math/isinf.pass.cpp | 29 +++++++------------
.../test/std/numerics/c.math/isnan.pass.cpp | 29 +++++++------------
2 files changed, 20 insertions(+), 38 deletions(-)
diff --git a/libcxx/test/std/numerics/c.math/isinf.pass.cpp b/libcxx/test/std/numerics/c.math/isinf.pass.cpp
index 99aab191c4977..e5169e8056c2e 100644
--- a/libcxx/test/std/numerics/c.math/isinf.pass.cpp
+++ b/libcxx/test/std/numerics/c.math/isinf.pass.cpp
@@ -62,30 +62,21 @@ struct TestInt {
}
};
-struct ConvertibleFloat {
- int value;
- ConvertibleFloat(int v) : value(v) {}
- operator float() const { return static_cast<float>(value); }
-};
-
-struct ConvertibleDouble {
- int value;
- ConvertibleDouble(int v) : value(v) {}
- operator double() const { return static_cast<double>(value); }
-};
-
-struct ConvertibleLongDouble {
- int value;
- ConvertibleLongDouble(int v) : value(v) {}
- operator long double() const { return static_cast<long double>(value); }
+template <typename T>
+struct ConvertibleTo {
+ operator T() const { return T(); }
};
int main(int, char**) {
types::for_each(types::floating_point_types(), TestFloat());
types::for_each(types::integral_types(), TestInt());
- assert(!std::isinf(ConvertibleFloat(0)));
- assert(!std::isinf(ConvertibleDouble(0)));
- assert(!std::isinf(ConvertibleLongDouble(0)));
+
+ // Make sure we can call `std::isinf` with convertible types
+ {
+ assert(!std::isinf(ConvertibleTo<float>()));
+ assert(!std::isinf(ConvertibleTo<double>()));
+ assert(!std::isinf(ConvertibleTo<long double>()));
+ }
return 0;
}
diff --git a/libcxx/test/std/numerics/c.math/isnan.pass.cpp b/libcxx/test/std/numerics/c.math/isnan.pass.cpp
index 374aa08a600d6..e4ccab1243e56 100644
--- a/libcxx/test/std/numerics/c.math/isnan.pass.cpp
+++ b/libcxx/test/std/numerics/c.math/isnan.pass.cpp
@@ -62,30 +62,21 @@ struct TestInt {
}
};
-struct ConvertibleFloat {
- int value;
- ConvertibleFloat(int v) : value(v) {}
- operator float() const { return static_cast<float>(value); }
-};
-
-struct ConvertibleDouble {
- int value;
- ConvertibleDouble(int v) : value(v) {}
- operator double() const { return static_cast<double>(value); }
-};
-
-struct ConvertibleLongDouble {
- int value;
- ConvertibleLongDouble(int v) : value(v) {}
- operator long double() const { return static_cast<long double>(value); }
+template <typename T>
+struct ConvertibleTo {
+ operator T() const { return T(); }
};
int main(int, char**) {
types::for_each(types::floating_point_types(), TestFloat());
types::for_each(types::integral_types(), TestInt());
- assert(!std::isnan(ConvertibleFloat(0)));
- assert(!std::isnan(ConvertibleDouble(0)));
- assert(!std::isnan(ConvertibleLongDouble(0)));
+
+ // Make sure we can call `std::isnan` with convertible types
+ {
+ assert(!std::isnan(ConvertibleTo<float>()));
+ assert(!std::isnan(ConvertibleTo<double>()));
+ assert(!std::isnan(ConvertibleTo<long double>()));
+ }
return 0;
}
More information about the libcxx-commits
mailing list