[libcxx-commits] [libcxx] d0846b4 - Recommit [libc++] Move abs and div into stdlib.h to fix header cycle.

Raphael Isemann via libcxx-commits libcxx-commits at lists.llvm.org
Tue Apr 28 06:43:01 PDT 2020


Author: Eric Fiselier
Date: 2020-04-28T15:42:36+02:00
New Revision: d0846b432c3040bb04484f30239858d6cff9fc0d

URL: https://github.com/llvm/llvm-project/commit/d0846b432c3040bb04484f30239858d6cff9fc0d
DIFF: https://github.com/llvm/llvm-project/commit/d0846b432c3040bb04484f30239858d6cff9fc0d.diff

LOG: Recommit [libc++] Move abs and div into stdlib.h to fix header cycle.

This relands this commit as it broke the LLDB bot the first time it landed.
See also the discussion on https://reviews.llvm.org/rG82b47b2978405f802a33b00d046e6f18ef6a47be

Since D74892 this code should now also work on macOS.

Original description:

libc++ is careful to not fracture overload sets. When one overload
is visible to a user, all of them should be. Anything less causes
subtle bugs and ODR violations.

Previously, in order to support ::abs and ::div being supplied by
both <cmath> and <cstdlib> we had to do awful things that make
<math.h> and <stdlib.h> have header cycles and be non-modular.
This really breaks with modules.

Specifically the problem was that in C++ ::abs introduces overloads
for floating point numbers, these overloads forward to ::fabs,
which are defined in math.h. Therefore ::abs needed to be in math.h
too. But this required stdlib.h to include math.h and math.h to
include stdlib.h.

To avoid these problems the definitions have been moved to stddef.h
(which math includes), and the floating point overloads of ::abs
have been changed to call __builtin_fabs, which both Clang and GCC
support.

Added: 
    

Modified: 
    libcxx/include/math.h
    libcxx/include/stdlib.h

Removed: 
    


################################################################################
diff  --git a/libcxx/include/math.h b/libcxx/include/math.h
index c9b4733e9c44..1603d5748e2d 100644
--- a/libcxx/include/math.h
+++ b/libcxx/include/math.h
@@ -297,9 +297,6 @@ long double    truncl(long double x);
 #pragma GCC system_header
 #endif
 
-#define _LIBCPP_STDLIB_INCLUDE_NEXT
-#include <stdlib.h>
-
 #include_next <math.h>
 
 #ifdef __cplusplus
@@ -308,6 +305,7 @@ long double    truncl(long double x);
 // back to C++ linkage before including these C++ headers.
 extern "C++" {
 
+#include <stdlib.h>
 #include <type_traits>
 #include <limits>
 
@@ -760,61 +758,12 @@ isunordered(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
 #endif  // isunordered
 
 // 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 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);
-}
-#endif // !(defined(_AIX) || defined(__sun__))
+//
+// handled in stdlib.h
 
 // 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
+//
+// handled in stdlib.h
 
 // acos
 

diff  --git a/libcxx/include/stdlib.h b/libcxx/include/stdlib.h
index 1d6827587037..812ea1024edf 100644
--- a/libcxx/include/stdlib.h
+++ b/libcxx/include/stdlib.h
@@ -7,16 +7,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-#if defined(__need_malloc_and_calloc) || defined(_LIBCPP_STDLIB_INCLUDE_NEXT)
+#if defined(__need_malloc_and_calloc)
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
 #endif
 
-#if defined(_LIBCPP_STDLIB_INCLUDE_NEXT)
-#undef _LIBCPP_STDLIB_INCLUDE_NEXT
-#endif
-
 #include_next <stdlib.h>
 
 #elif !defined(_LIBCPP_STDLIB_H)
@@ -97,7 +93,63 @@ void *aligned_alloc(size_t alignment, size_t size);                       // C11
 #include_next <stdlib.h>
 
 #ifdef __cplusplus
-#include <math.h>
+extern "C++" {
+// 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 __builtin_labs(__x);
+}
+#ifndef _LIBCPP_HAS_NO_LONG_LONG
+inline _LIBCPP_INLINE_VISIBILITY long long abs(long long __x) _NOEXCEPT {
+  return __builtin_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 __builtin_fabsf(__lcpp_x); // Use builtins to prevent needing math.h
+}
+
+inline _LIBCPP_INLINE_VISIBILITY double abs(double __lcpp_x) _NOEXCEPT {
+  return __builtin_fabs(__lcpp_x);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY long double
+abs(long double __lcpp_x) _NOEXCEPT {
+  return __builtin_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
+} // extern "C++"
 #endif  // __cplusplus
 
 #endif  // _LIBCPP_STDLIB_H


        


More information about the libcxx-commits mailing list