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
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: 1670772adc0ebe647aa8cda20e0b7dada3cf3e85
diff --git a/include/math.h b/include/math.h
index 6f9a76b..9558321 100644
--- a/include/math.h
+++ b/include/math.h
@@ -297,6 +297,9 @@
 #pragma GCC system_header
 #endif
 
+#define _LIBCPP_STDLIB_INCLUDE_NEXT
+#include <stdlib.h>
+
 #include_next <math.h>
 
 #ifdef __cplusplus
@@ -754,20 +757,61 @@
 
 // abs
 
+#undef abs
+#undef labs
+#ifndef _LIBCPP_HAS_NO_LONG_LONG
+#undef llabs
+#endif
+
+// MSVCRT already has the correct prototype in <stdlib.h> if __cplusplus is defined
+#if !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_AIX)
+inline _LIBCPP_INLINE_VISIBILITY long abs(long __x) _NOEXCEPT {
+  return ::labs(__x);
+}
+#ifndef _LIBCPP_HAS_NO_LONG_LONG
+inline _LIBCPP_INLINE_VISIBILITY long long abs(long long __x) _NOEXCEPT {
+  return ::llabs(__x);
+}
+#endif // _LIBCPP_HAS_NO_LONG_LONG
+#endif // !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_AIX)
+
+
 #if !(defined(_AIX) || defined(__sun__))
-inline _LIBCPP_INLINE_VISIBILITY
-float
-abs(float __lcpp_x) _NOEXCEPT {return ::fabsf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY float abs(float __lcpp_x) _NOEXCEPT {
+  return ::fabsf(__lcpp_x);
+}
 
-inline _LIBCPP_INLINE_VISIBILITY
-double
-abs(double __lcpp_x) _NOEXCEPT {return ::fabs(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY double abs(double __lcpp_x) _NOEXCEPT {
+  return ::fabs(__lcpp_x);
+}
 
-inline _LIBCPP_INLINE_VISIBILITY
-long double
-abs(long double __lcpp_x) _NOEXCEPT {return ::fabsl(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double
+abs(long double __lcpp_x) _NOEXCEPT {
+  return ::fabsl(__lcpp_x);
+}
 #endif // !(defined(_AIX) || defined(__sun__))
 
+// div
+
+#undef div
+#undef ldiv
+#ifndef _LIBCPP_HAS_NO_LONG_LONG
+#undef lldiv
+#endif
+
+// MSVCRT already has the correct prototype in <stdlib.h> if __cplusplus is defined
+#if !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_AIX)
+inline _LIBCPP_INLINE_VISIBILITY ldiv_t div(long __x, long __y) _NOEXCEPT {
+  return ::ldiv(__x, __y);
+}
+#ifndef _LIBCPP_HAS_NO_LONG_LONG
+inline _LIBCPP_INLINE_VISIBILITY lldiv_t div(long long __x,
+                                             long long __y) _NOEXCEPT {
+  return ::lldiv(__x, __y);
+}
+#endif // _LIBCPP_HAS_NO_LONG_LONG
+#endif // _LIBCPP_MSVCRT / __sun__ / _AIX
+
 // acos
 
 #if !(defined(_AIX) || defined(__sun__))