summaryrefslogtreecommitdiffstats
path: root/libcxx/test/std/depr/depr.c.headers
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2019-04-23 18:01:58 +0000
committerEric Fiselier <eric@efcs.ca>2019-04-23 18:01:58 +0000
commit1670772adc0ebe647aa8cda20e0b7dada3cf3e85 (patch)
treebc4e351667cbe843abdc4ada4345e055df5a430a /libcxx/test/std/depr/depr.c.headers
parentf945429fed52bc7c182d5b38469a41ab5eea03a2 (diff)
downloadbcm5719-llvm-1670772adc0ebe647aa8cda20e0b7dada3cf3e85.tar.gz
bcm5719-llvm-1670772adc0ebe647aa8cda20e0b7dada3cf3e85.zip
Fix implementation of ::abs and std::abs LWG 2192.
Summary: All overloads of `::abs` and `std::abs` must be present in both `<cmath>` and `<cstdlib>`. This is problematic to implement because C defines `fabs` in `math.h` and `labs` in `stdlib.h`. This introduces a circular dependency between the two headers. This patch implements that requirement by moving `abs` into `math.h` and making `stdlib.h` include `math.h`. In order to get the underlying C declarations from the "real" `stdlib.h` inside our `math.h` we need some trickery. Specifically we need to make `stdlib.h` include next itself. Suggestions for a cleaner implementation are welcome. Reviewers: mclow.lists, ldionne Reviewed By: ldionne Subscribers: krytarowski, fedor.sergeev, dexonsmith, jdoerfert, jsji, libcxx-commits Differential Revision: https://reviews.llvm.org/D60097 llvm-svn: 359020
Diffstat (limited to 'libcxx/test/std/depr/depr.c.headers')
-rw-r--r--libcxx/test/std/depr/depr.c.headers/math_h.pass.cpp42
-rw-r--r--libcxx/test/std/depr/depr.c.headers/stdlib_h.pass.cpp51
2 files changed, 87 insertions, 6 deletions
diff --git a/libcxx/test/std/depr/depr.c.headers/math_h.pass.cpp b/libcxx/test/std/depr/depr.c.headers/math_h.pass.cpp
index b0b6c0cb324..2077a072333 100644
--- a/libcxx/test/std/depr/depr.c.headers/math_h.pass.cpp
+++ b/libcxx/test/std/depr/depr.c.headers/math_h.pass.cpp
@@ -97,13 +97,45 @@ Ambiguous scalbn(Ambiguous, Ambiguous){ return Ambiguous(); }
Ambiguous tgamma(Ambiguous){ return Ambiguous(); }
Ambiguous trunc(Ambiguous){ return Ambiguous(); }
+template <class T, class = decltype(::abs(std::declval<T>()))>
+std::true_type has_abs_imp(int);
+template <class T>
+std::false_type has_abs_imp(...);
+
+template <class T>
+struct has_abs : decltype(has_abs_imp<T>(0)) {};
+
void test_abs()
{
- static_assert((std::is_same<decltype(abs((float)0)), float>::value), "");
- static_assert((std::is_same<decltype(abs((double)0)), double>::value), "");
- static_assert((std::is_same<decltype(abs((long double)0)), long double>::value), "");
- static_assert((std::is_same<decltype(abs(Ambiguous())), Ambiguous>::value), "");
- assert(abs(-1.) == 1);
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wabsolute-value"
+#endif
+ static_assert((std::is_same<decltype(abs((float)0)), float>::value), "");
+ static_assert((std::is_same<decltype(abs((double)0)), double>::value), "");
+ static_assert(
+ (std::is_same<decltype(abs((long double)0)), long double>::value), "");
+ static_assert((std::is_same<decltype(abs((int)0)), int>::value), "");
+ static_assert((std::is_same<decltype(abs((long)0)), long>::value), "");
+ static_assert((std::is_same<decltype(abs((long long)0)), long long>::value),
+ "");
+ static_assert((std::is_same<decltype(abs((unsigned char)0)), int>::value),
+ "");
+ static_assert((std::is_same<decltype(abs((unsigned short)0)), int>::value),
+ "");
+
+ static_assert((std::is_same<decltype(abs(Ambiguous())), Ambiguous>::value),
+ "");
+
+ static_assert(!has_abs<unsigned>::value, "");
+ static_assert(!has_abs<unsigned long>::value, "");
+ static_assert(!has_abs<unsigned long long>::value, "");
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+ assert(abs(-1.) == 1);
}
void test_acos()
diff --git a/libcxx/test/std/depr/depr.c.headers/stdlib_h.pass.cpp b/libcxx/test/std/depr/depr.c.headers/stdlib_h.pass.cpp
index 4c0218d6ef6..d1fde66da4c 100644
--- a/libcxx/test/std/depr/depr.c.headers/stdlib_h.pass.cpp
+++ b/libcxx/test/std/depr/depr.c.headers/stdlib_h.pass.cpp
@@ -10,6 +10,7 @@
#include <stdlib.h>
#include <type_traits>
+#include <cassert>
#include "test_macros.h"
@@ -63,6 +64,52 @@
#error RAND_MAX not defined
#endif
+template <class T, class = decltype(::abs(std::declval<T>()))>
+std::true_type has_abs_imp(int);
+template <class T>
+std::false_type has_abs_imp(...);
+
+template <class T>
+struct has_abs : decltype(has_abs_imp<T>(0)) {};
+
+void test_abs() {
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wabsolute-value"
+#endif
+ static_assert((std::is_same<decltype(abs((float)0)), float>::value), "");
+ static_assert((std::is_same<decltype(abs((double)0)), double>::value), "");
+ static_assert(
+ (std::is_same<decltype(abs((long double)0)), long double>::value), "");
+ static_assert((std::is_same<decltype(abs((int)0)), int>::value), "");
+ static_assert((std::is_same<decltype(abs((long)0)), long>::value), "");
+ static_assert((std::is_same<decltype(abs((long long)0)), long long>::value),
+ "");
+ static_assert((std::is_same<decltype(abs((unsigned char)0)), int>::value),
+ "");
+ static_assert((std::is_same<decltype(abs((unsigned short)0)), int>::value),
+ "");
+ static_assert((std::is_same<decltype(abs((signed char)0)), int>::value),
+ "");
+ static_assert((std::is_same<decltype(abs((short)0)), int>::value),
+ "");
+ static_assert((std::is_same<decltype(abs((unsigned char)0)), int>::value),
+ "");
+ static_assert((std::is_same<decltype(abs((char)0)), int>::value),
+ "");
+
+ static_assert(!has_abs<unsigned>::value, "");
+ static_assert(!has_abs<unsigned long>::value, "");
+ static_assert(!has_abs<unsigned long long>::value, "");
+ static_assert(!has_abs<size_t>::value, "");
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+ assert(abs(-1.) == 1);
+}
+
int main(int, char**)
{
size_t s = 0; ((void)s);
@@ -117,5 +164,7 @@ int main(int, char**)
static_assert((std::is_same<decltype(mbstowcs(pw,"",0)), size_t>::value), "");
static_assert((std::is_same<decltype(wcstombs(pc,pwc,0)), size_t>::value), "");
- return 0;
+ test_abs();
+
+ return 0;
}
OpenPOWER on IntegriCloud