Index: include/__config =================================================================== --- include/__config +++ include/__config @@ -803,6 +803,19 @@ #define _LIBCPP_CONSTEXPR_AFTER_CXX14 #endif +// Whether to assume a C99 compatible C library in C++03/98 modes. By default, +// libc++ provides many C++11 operations in C++03/98 modes as extensions, some +// of these extensions rely on the underlying C library providing C99 operations +// even in C++03/98 modes. This flag forbids libc++ from making this assumption, +// which means disabling those C++11 extensions in C++03/98 modes. Not providing +// those extensions is better than trying to provide them and failing to compile +// because the underlying C library is not C99 compatible. +#if __cplusplus < 201103L && defined(_LIBCPP_STRICT_C99_COMPATIBILITY) +# define _LIBCPP_USE_C99 0 +#else +# define _LIBCPP_USE_C99 1 +#endif + #ifdef _LIBCPP_HAS_NO_RVALUE_REFERENCES # define _LIBCPP_EXPLICIT_MOVE(x) _VSTD::move(x) #else Index: include/math.h =================================================================== --- include/math.h +++ include/math.h @@ -946,7 +946,7 @@ // acosh -#ifndef _LIBCPP_MSVCRT +#if !defined(_LIBCPP_MSVCRT) && _LIBCPP_USE_C99 inline _LIBCPP_INLINE_VISIBILITY float acosh(float __lcpp_x) _NOEXCEPT {return acoshf(__lcpp_x);} inline _LIBCPP_INLINE_VISIBILITY long double acosh(long double __lcpp_x) _NOEXCEPT {return acoshl(__lcpp_x);} @@ -958,7 +958,7 @@ // asinh -#ifndef _LIBCPP_MSVCRT +#if !defined(_LIBCPP_MSVCRT) && _LIBCPP_USE_C99 inline _LIBCPP_INLINE_VISIBILITY float asinh(float __lcpp_x) _NOEXCEPT {return asinhf(__lcpp_x);} inline _LIBCPP_INLINE_VISIBILITY long double asinh(long double __lcpp_x) _NOEXCEPT {return asinhl(__lcpp_x);} @@ -970,7 +970,7 @@ // atanh -#ifndef _LIBCPP_MSVCRT +#if !defined(_LIBCPP_MSVCRT) && _LIBCPP_USE_C99 inline _LIBCPP_INLINE_VISIBILITY float atanh(float __lcpp_x) _NOEXCEPT {return atanhf(__lcpp_x);} inline _LIBCPP_INLINE_VISIBILITY long double atanh(long double __lcpp_x) _NOEXCEPT {return atanhl(__lcpp_x);} @@ -982,7 +982,7 @@ // cbrt -#ifndef _LIBCPP_MSVCRT +#if !defined(_LIBCPP_MSVCRT) && _LIBCPP_USE_C99 inline _LIBCPP_INLINE_VISIBILITY float cbrt(float __lcpp_x) _NOEXCEPT {return cbrtf(__lcpp_x);} inline _LIBCPP_INLINE_VISIBILITY long double cbrt(long double __lcpp_x) _NOEXCEPT {return cbrtl(__lcpp_x);} @@ -994,7 +994,7 @@ // copysign -#if !defined(_VC_CRT_MAJOR_VERSION) || (_VC_CRT_MAJOR_VERSION < 12) +#if _LIBCPP_USE_C99 && (!defined(_VC_CRT_MAJOR_VERSION) || (_VC_CRT_MAJOR_VERSION < 12)) inline _LIBCPP_INLINE_VISIBILITY float copysign(float __lcpp_x, float __lcpp_y) _NOEXCEPT { return copysignf(__lcpp_x, __lcpp_y); @@ -1005,6 +1005,7 @@ } #endif +#if _LIBCPP_USE_C99 template inline _LIBCPP_INLINE_VISIBILITY typename std::__lazy_enable_if @@ -1020,9 +1021,9 @@ std::is_same<_A2, __result_type>::value)), ""); return copysign((__result_type)__lcpp_x, (__result_type)__lcpp_y); } +#endif -#ifndef _LIBCPP_MSVCRT - +#if !defined(_LIBCPP_MSVCRT) && _LIBCPP_USE_C99 // erf inline _LIBCPP_INLINE_VISIBILITY float erf(float __lcpp_x) _NOEXCEPT {return erff(__lcpp_x);} 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 @@ -750,6 +750,8 @@ assert(isunordered(-1.0, 0.F) == false); } +#if _LIBCPP_USE_C99 + void test_acosh() { static_assert((std::is_same::value), ""); @@ -1455,6 +1457,8 @@ assert(trunc(1) == 1); } +#endif + int main() { test_abs(); @@ -1492,6 +1496,7 @@ test_islessgreater(); test_isnan(); test_isunordered(); +#if _LIBCPP_USE_C99 test_acosh(); test_asinh(); test_atanh(); @@ -1527,4 +1532,5 @@ test_scalbn(); test_tgamma(); test_trunc(); +#endif } 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 @@ -752,6 +752,8 @@ assert(std::isunordered(-1.0, 0.F) == false); } +#if _LIBCPP_USE_C99 + void test_acosh() { static_assert((std::is_same::value), ""); @@ -1479,6 +1481,8 @@ assert(std::trunc(1) == 1); } +#endif + int main() { test_abs(); @@ -1516,6 +1520,7 @@ test_islessgreater(); test_isnan(); test_isunordered(); +#if _LIBCPP_USE_C99 test_acosh(); test_asinh(); test_atanh(); @@ -1551,4 +1556,5 @@ test_scalbn(); test_tgamma(); test_trunc(); +#endif } Index: test/std/numerics/complex.number/cmplx.over/proj.pass.cpp =================================================================== --- test/std/numerics/complex.number/cmplx.over/proj.pass.cpp +++ test/std/numerics/complex.number/cmplx.over/proj.pass.cpp @@ -34,7 +34,9 @@ test(T x, typename std::enable_if::value>::type* = 0) { static_assert((std::is_same >::value), ""); +#if _LIBCPP_USE_C99 assert(std::proj(x) == proj(std::complex(x, 0))); +#endif } template @@ -43,7 +45,9 @@ !std::is_floating_point::value>::type* = 0) { static_assert((std::is_same >::value), ""); +#if _LIBCPP_USE_C99 assert(std::proj(x) == proj(std::complex(x, 0))); +#endif } template