Index: include/math.h =================================================================== --- include/math.h +++ include/math.h @@ -297,6 +297,9 @@ #pragma GCC system_header #endif +#define _LIBCPP_STDLIB_INCLUDE_NEXT +#include + #include_next #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 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 + +// div + +#undef div +#undef ldiv +#ifndef _LIBCPP_HAS_NO_LONG_LONG +#undef lldiv +#endif + +// MSVCRT already has the correct prototype in 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 + #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 __builtin_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 __builtin_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 __builtin_fabsl(__lcpp_x); +} #endif // !(defined(_AIX) || defined(__sun__)) +#endif + // acos #if !(defined(_AIX) || defined(__sun__)) Index: include/stdlib.h =================================================================== --- include/stdlib.h +++ include/stdlib.h @@ -7,12 +7,16 @@ // //===----------------------------------------------------------------------===// -#if defined(__need_malloc_and_calloc) +#if defined(__need_malloc_and_calloc) || defined(_LIBCPP_STDLIB_INCLUDE_NEXT) #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 #elif !defined(_LIBCPP_STDLIB_H) @@ -93,33 +97,7 @@ #include_next #ifdef __cplusplus - -extern "C++" { - -#undef abs -#undef div -#undef labs -#undef ldiv -#ifndef _LIBCPP_HAS_NO_LONG_LONG -#undef llabs -#undef lldiv -#endif - -// MSVCRT already has the correct prototype in 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 - -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++" - +#include #endif // __cplusplus #endif // _LIBCPP_STDLIB_H Index: test/std/depr/depr.c.headers/math_h.pass.cpp =================================================================== --- test/std/depr/depr.c.headers/math_h.pass.cpp +++ test/std/depr/depr.c.headers/math_h.pass.cpp @@ -97,13 +97,45 @@ Ambiguous tgamma(Ambiguous){ return Ambiguous(); } Ambiguous trunc(Ambiguous){ return Ambiguous(); } +template ()))> +std::true_type has_abs_imp(int); +template +std::false_type has_abs_imp(...); + +template +struct has_abs : decltype(has_abs_imp(0)) {}; + void test_abs() { - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - assert(abs(-1.) == 1); +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wabsolute-value" +#endif + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert( + (std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + + static_assert((std::is_same::value), + ""); + + static_assert(!has_abs::value, ""); + static_assert(!has_abs::value, ""); + static_assert(!has_abs::value, ""); + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + + assert(abs(-1.) == 1); } void test_acos() Index: test/std/depr/depr.c.headers/stdlib_h.pass.cpp =================================================================== --- test/std/depr/depr.c.headers/stdlib_h.pass.cpp +++ test/std/depr/depr.c.headers/stdlib_h.pass.cpp @@ -10,6 +10,7 @@ #include #include +#include #include "test_macros.h" @@ -63,6 +64,52 @@ #error RAND_MAX not defined #endif +template ()))> +std::true_type has_abs_imp(int); +template +std::false_type has_abs_imp(...); + +template +struct has_abs : decltype(has_abs_imp(0)) {}; + +void test_abs() { +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wabsolute-value" +#endif + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert( + (std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + + static_assert(!has_abs::value, ""); + static_assert(!has_abs::value, ""); + static_assert(!has_abs::value, ""); + static_assert(!has_abs::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 @@ static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); - return 0; + test_abs(); + + return 0; } Index: test/std/language.support/support.runtime/cstdlib.pass.cpp =================================================================== --- test/std/language.support/support.runtime/cstdlib.pass.cpp +++ test/std/language.support/support.runtime/cstdlib.pass.cpp @@ -49,6 +49,52 @@ ((void) obj); }; +template ()))> +std::true_type has_abs_imp(int); +template +std::false_type has_abs_imp(...); + +template +struct has_abs : decltype(has_abs_imp(0)) {}; + +void test_abs() { +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wabsolute-value" +#endif + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert( + (std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + + static_assert(!has_abs::value, ""); + static_assert(!has_abs::value, ""); + static_assert(!has_abs::value, ""); + static_assert(!has_abs::value, ""); + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + + assert(std::abs(-1.) == 1); +} + int main(int, char**) { std::size_t s = 0; @@ -109,5 +155,7 @@ static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); - return 0; + test_abs(); + + return 0; } Index: test/std/numerics/c.math/cmath.pass.cpp =================================================================== --- test/std/numerics/c.math/cmath.pass.cpp +++ test/std/numerics/c.math/cmath.pass.cpp @@ -100,15 +100,54 @@ Ambiguous tgamma(Ambiguous){ return Ambiguous(); } Ambiguous trunc(Ambiguous){ return Ambiguous(); } -void test_abs() -{ - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - assert(std::abs(-1.) == 1); +template ()))> +std::true_type has_abs_imp(int); +template +std::false_type has_abs_imp(...); + +template +struct has_abs : decltype(has_abs_imp(0)) {}; + +void test_abs() { +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wabsolute-value" +#endif + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert( + (std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), + ""); + static_assert((std::is_same::value), ""); + + static_assert(!has_abs::value, ""); + static_assert(!has_abs::value, ""); + static_assert(!has_abs::value, ""); + static_assert(!has_abs::value, ""); + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + + assert(std::abs(-1.) == 1); } + void test_acos() { static_assert((std::is_same::value), ""); Index: www/cxx1z_status.html =================================================================== --- www/cxx1z_status.html +++ www/cxx1z_status.html @@ -281,7 +281,7 @@ 2492Clarify requirements for compKonaComplete 2495There is no such thing as an Exception Safety elementKonaComplete - 2192Validity and return type of std::abs(0u) is unclearJacksonville + 2192Validity and return type of std::abs(0u) is unclearJacksonvilleComplete 2276Missing requirement on std::promise::set_exceptionJacksonvilleComplete 2296std::addressof should be constexprJacksonvilleComplete (Clang Only) 2450(greater|less|greater_equal|less_equal)<void> do not yield a total order for pointersJacksonvilleComplete