From 633927db844e47c87dd93198e2c2763dd10f668f Mon Sep 17 00:00:00 2001 From: Nikolas Klauser Date: Sun, 25 Dec 2022 20:13:39 +0100 Subject: [PATCH] [libc++] Add [[nodiscard]] extensions in There are quite a few functions marked `[[gnu::const]]` inside the compiler. This patch adds `[[nodiscard]]` to libc++-provided overloads of these functions to match the diagnostics produced. Reviewed By: ldionne, #libc Spies: libcxx-commits Differential Revision: https://reviews.llvm.org/D140855 --- libcxx/docs/UsingLibcxx.rst | 23 +++ libcxx/include/math.h | 136 +++++++++--------- libcxx/include/stdlib.h | 10 +- .../math_nodiscard_extensions.verify.cpp | 156 +++++++++++++++++++++ 4 files changed, 252 insertions(+), 73 deletions(-) create mode 100644 libcxx/test/libcxx/diagnostics/math_nodiscard_extensions.verify.cpp diff --git a/libcxx/docs/UsingLibcxx.rst b/libcxx/docs/UsingLibcxx.rst index 5cf608e..6fac013 100644 --- a/libcxx/docs/UsingLibcxx.rst +++ b/libcxx/docs/UsingLibcxx.rst @@ -455,6 +455,29 @@ which no dialect declares as such (See the second form described above). * ``identity::operator()`` * ``to_integer`` * ``to_underlying`` +* ``signbit`` +* ``fpclassify`` +* ``isfinite`` +* ``isinf`` +* ``isnan`` +* ``isnormal`` +* ``isgreater`` +* ``isgreaterequal`` +* ``isless`` +* ``islessequal`` +* ``islessgreater`` +* ``isunordered`` +* ``ceil`` +* ``fabs`` +* ``floor`` +* ``cbrt`` +* ``copysign`` +* ``fmax`` +* ``fmin`` +* ``nearbyint`` +* ``rint`` +* ``round`` +* ``trunc`` Extended integral type support ------------------------------ diff --git a/libcxx/include/math.h b/libcxx/include/math.h index 1636ec4..a23d1ff 100644 --- a/libcxx/include/math.h +++ b/libcxx/include/math.h @@ -367,29 +367,29 @@ extern "C++" { // signbit template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1 __x) _NOEXCEPT { return __builtin_signbit(__x); } template ::value && std::is_signed<_A1>::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1 __x) _NOEXCEPT { return __x < 0; } template ::value && !std::is_signed<_A1>::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1) _NOEXCEPT { return false; } // fpclassify template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI int fpclassify(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI int fpclassify(_A1 __x) _NOEXCEPT { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x); } template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI int fpclassify(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI int fpclassify(_A1 __x) _NOEXCEPT { return __x == 0 ? FP_ZERO : FP_NORMAL; } @@ -400,13 +400,13 @@ inline _LIBCPP_HIDE_FROM_ABI int fpclassify(_A1 __x) _NOEXCEPT { template ::value && std::numeric_limits<_A1>::has_infinity, int> = 0> -_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1 __x) _NOEXCEPT { return __builtin_isfinite((typename std::__promote<_A1>::type)__x); } template ::value && !std::numeric_limits<_A1>::has_infinity, int> = 0> -_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1) _NOEXCEPT { return true; } @@ -414,27 +414,27 @@ _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1) _NOEXCEPT template ::value && std::numeric_limits<_A1>::has_infinity, int> = 0> -_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(_A1 __x) _NOEXCEPT { return __builtin_isinf((typename std::__promote<_A1>::type)__x); } template -_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI +_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI typename std::enable_if< std::is_arithmetic<_A1>::value && !std::numeric_limits<_A1>::has_infinity, bool>::type isinf(_A1) _NOEXCEPT { return false; } # ifdef _LIBCPP_PREFERRED_OVERLOAD -inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(float __x) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(float __x) _NOEXCEPT { return __builtin_isinf(__x); } -inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _LIBCPP_PREFERRED_OVERLOAD bool isinf(double __x) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _LIBCPP_PREFERRED_OVERLOAD bool isinf(double __x) _NOEXCEPT { return __builtin_isinf(__x); } -inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(long double __x) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(long double __x) _NOEXCEPT { return __builtin_isinf(__x); } # endif @@ -442,25 +442,25 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(long doubl // isnan template ::value, int> = 0> -_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(_A1 __x) _NOEXCEPT { return __builtin_isnan(__x); } template ::value, int> = 0> -_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(_A1) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(_A1) _NOEXCEPT { return false; } # ifdef _LIBCPP_PREFERRED_OVERLOAD -inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(float __x) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(float __x) _NOEXCEPT { return __builtin_isnan(__x); } -inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _LIBCPP_PREFERRED_OVERLOAD bool isnan(double __x) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _LIBCPP_PREFERRED_OVERLOAD bool isnan(double __x) _NOEXCEPT { return __builtin_isnan(__x); } -inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(long double __x) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(long double __x) _NOEXCEPT { return __builtin_isnan(__x); } # endif @@ -468,12 +468,12 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(long doubl // isnormal template ::value, int> = 0> -_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnormal(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnormal(_A1 __x) _NOEXCEPT { return __builtin_isnormal(__x); } template ::value, int> = 0> -_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnormal(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnormal(_A1 __x) _NOEXCEPT { return __x != 0; } @@ -482,7 +482,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnormal(_A1 __x) _NOEX template ::value && std::is_arithmetic<_A2>::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI bool isgreater(_A1 __x, _A2 __y) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isgreater(_A1 __x, _A2 __y) _NOEXCEPT { typedef typename std::__promote<_A1, _A2>::type type; return __builtin_isgreater((type)__x, (type)__y); } @@ -492,7 +492,7 @@ inline _LIBCPP_HIDE_FROM_ABI bool isgreater(_A1 __x, _A2 __y) _NOEXCEPT { template ::value && std::is_arithmetic<_A2>::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI bool isgreaterequal(_A1 __x, _A2 __y) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isgreaterequal(_A1 __x, _A2 __y) _NOEXCEPT { typedef typename std::__promote<_A1, _A2>::type type; return __builtin_isgreaterequal((type)__x, (type)__y); } @@ -502,7 +502,7 @@ inline _LIBCPP_HIDE_FROM_ABI bool isgreaterequal(_A1 __x, _A2 __y) _NOEXCEPT { template ::value && std::is_arithmetic<_A2>::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI bool isless(_A1 __x, _A2 __y) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isless(_A1 __x, _A2 __y) _NOEXCEPT { typedef typename std::__promote<_A1, _A2>::type type; return __builtin_isless((type)__x, (type)__y); } @@ -512,7 +512,7 @@ inline _LIBCPP_HIDE_FROM_ABI bool isless(_A1 __x, _A2 __y) _NOEXCEPT { template ::value && std::is_arithmetic<_A2>::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI bool islessequal(_A1 __x, _A2 __y) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool islessequal(_A1 __x, _A2 __y) _NOEXCEPT { typedef typename std::__promote<_A1, _A2>::type type; return __builtin_islessequal((type)__x, (type)__y); } @@ -522,7 +522,7 @@ inline _LIBCPP_HIDE_FROM_ABI bool islessequal(_A1 __x, _A2 __y) _NOEXCEPT { template ::value && std::is_arithmetic<_A2>::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI bool islessgreater(_A1 __x, _A2 __y) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool islessgreater(_A1 __x, _A2 __y) _NOEXCEPT { typedef typename std::__promote<_A1, _A2>::type type; return __builtin_islessgreater((type)__x, (type)__y); } @@ -532,7 +532,7 @@ inline _LIBCPP_HIDE_FROM_ABI bool islessgreater(_A1 __x, _A2 __y) _NOEXCEPT { template ::value && std::is_arithmetic<_A2>::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI bool isunordered(_A1 __x, _A2 __y) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isunordered(_A1 __x, _A2 __y) _NOEXCEPT { typedef typename std::__promote<_A1, _A2>::type type; return __builtin_isunordered((type)__x, (type)__y); } @@ -638,18 +638,18 @@ atan2(_A1 __y, _A2 __x) _NOEXCEPT // ceil # if !defined(__sun__) -inline _LIBCPP_HIDE_FROM_ABI float ceil(float __x) _NOEXCEPT {return __builtin_ceilf(__x);} +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float ceil(float __x) _NOEXCEPT {return __builtin_ceilf(__x);} template -_LIBCPP_HIDE_FROM_ABI double ceil(double __x) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double ceil(double __x) _NOEXCEPT { return __builtin_ceil(__x); } -inline _LIBCPP_HIDE_FROM_ABI long double ceil(long double __x) _NOEXCEPT {return __builtin_ceill(__x);} +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double ceil(long double __x) _NOEXCEPT {return __builtin_ceill(__x);} # endif template -inline _LIBCPP_HIDE_FROM_ABI +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI typename std::enable_if::value, double>::type ceil(_A1 __x) _NOEXCEPT {return __builtin_ceil((double)__x);} @@ -710,36 +710,36 @@ exp(_A1 __x) _NOEXCEPT {return __builtin_exp((double)__x);} // fabs # if !defined(__sun__) -inline _LIBCPP_HIDE_FROM_ABI float fabs(float __x) _NOEXCEPT {return __builtin_fabsf(__x);} +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float fabs(float __x) _NOEXCEPT {return __builtin_fabsf(__x);} template -_LIBCPP_HIDE_FROM_ABI double fabs(double __x) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double fabs(double __x) _NOEXCEPT { return __builtin_fabs(__x); } -inline _LIBCPP_HIDE_FROM_ABI long double fabs(long double __x) _NOEXCEPT {return __builtin_fabsl(__x);} +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double fabs(long double __x) _NOEXCEPT {return __builtin_fabsl(__x);} # endif template -inline _LIBCPP_HIDE_FROM_ABI +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI typename std::enable_if::value, double>::type fabs(_A1 __x) _NOEXCEPT {return __builtin_fabs((double)__x);} // floor # if !defined(__sun__) -inline _LIBCPP_HIDE_FROM_ABI float floor(float __x) _NOEXCEPT {return __builtin_floorf(__x);} +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float floor(float __x) _NOEXCEPT {return __builtin_floorf(__x);} template -_LIBCPP_HIDE_FROM_ABI double floor(double __x) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double floor(double __x) _NOEXCEPT { return __builtin_floor(__x); } -inline _LIBCPP_HIDE_FROM_ABI long double floor(long double __x) _NOEXCEPT {return __builtin_floorl(__x);} +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double floor(long double __x) _NOEXCEPT {return __builtin_floorl(__x);} # endif template -inline _LIBCPP_HIDE_FROM_ABI +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI typename std::enable_if::value, double>::type floor(_A1 __x) _NOEXCEPT {return __builtin_floor((double)__x);} @@ -1027,32 +1027,32 @@ atanh(_A1 __x) _NOEXCEPT {return __builtin_atanh((double)__x);} // cbrt -inline _LIBCPP_HIDE_FROM_ABI float cbrt(float __x) _NOEXCEPT {return __builtin_cbrtf(__x);} +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float cbrt(float __x) _NOEXCEPT {return __builtin_cbrtf(__x);} template -_LIBCPP_HIDE_FROM_ABI double cbrt(double __x) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double cbrt(double __x) _NOEXCEPT { return __builtin_cbrt(__x); } -inline _LIBCPP_HIDE_FROM_ABI long double cbrt(long double __x) _NOEXCEPT {return __builtin_cbrtl(__x);} +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double cbrt(long double __x) _NOEXCEPT {return __builtin_cbrtl(__x);} template -inline _LIBCPP_HIDE_FROM_ABI +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI typename std::enable_if::value, double>::type cbrt(_A1 __x) _NOEXCEPT {return __builtin_cbrt((double)__x);} // copysign -inline _LIBCPP_HIDE_FROM_ABI float copysign(float __x, float __y) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float copysign(float __x, float __y) _NOEXCEPT { return ::__builtin_copysignf(__x, __y); } -inline _LIBCPP_HIDE_FROM_ABI long double copysign(long double __x, long double __y) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double copysign(long double __x, long double __y) _NOEXCEPT { return ::__builtin_copysignl(__x, __y); } template -inline _LIBCPP_HIDE_FROM_ABI +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI typename std::__enable_if_t < std::is_arithmetic<_A1>::value && @@ -1192,17 +1192,17 @@ fma(_A1 __x, _A2 __y, _A3 __z) _NOEXCEPT // fmax -inline _LIBCPP_HIDE_FROM_ABI float fmax(float __x, float __y) _NOEXCEPT {return __builtin_fmaxf(__x, __y);} +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float fmax(float __x, float __y) _NOEXCEPT {return __builtin_fmaxf(__x, __y);} template -_LIBCPP_HIDE_FROM_ABI double fmax(double __x, double __y) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double fmax(double __x, double __y) _NOEXCEPT { return __builtin_fmax(__x, __y); } -inline _LIBCPP_HIDE_FROM_ABI long double fmax(long double __x, long double __y) _NOEXCEPT {return __builtin_fmaxl(__x, __y);} +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double fmax(long double __x, long double __y) _NOEXCEPT {return __builtin_fmaxl(__x, __y);} template -inline _LIBCPP_HIDE_FROM_ABI +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI typename std::__enable_if_t < std::is_arithmetic<_A1>::value && @@ -1219,17 +1219,17 @@ fmax(_A1 __x, _A2 __y) _NOEXCEPT // fmin -inline _LIBCPP_HIDE_FROM_ABI float fmin(float __x, float __y) _NOEXCEPT {return __builtin_fminf(__x, __y);} +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float fmin(float __x, float __y) _NOEXCEPT {return __builtin_fminf(__x, __y);} template -_LIBCPP_HIDE_FROM_ABI double fmin(double __x, double __y) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double fmin(double __x, double __y) _NOEXCEPT { return __builtin_fmin(__x, __y); } -inline _LIBCPP_HIDE_FROM_ABI long double fmin(long double __x, long double __y) _NOEXCEPT {return __builtin_fminl(__x, __y);} +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double fmin(long double __x, long double __y) _NOEXCEPT {return __builtin_fminl(__x, __y);} template -inline _LIBCPP_HIDE_FROM_ABI +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI typename std::__enable_if_t < std::is_arithmetic<_A1>::value && @@ -1455,17 +1455,17 @@ lround(_A1 __x) _NOEXCEPT // nearbyint -inline _LIBCPP_HIDE_FROM_ABI float nearbyint(float __x) _NOEXCEPT {return __builtin_nearbyintf(__x);} +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float nearbyint(float __x) _NOEXCEPT {return __builtin_nearbyintf(__x);} template -_LIBCPP_HIDE_FROM_ABI double nearbyint(double __x) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double nearbyint(double __x) _NOEXCEPT { return __builtin_nearbyint(__x); } -inline _LIBCPP_HIDE_FROM_ABI long double nearbyint(long double __x) _NOEXCEPT {return __builtin_nearbyintl(__x);} +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double nearbyint(long double __x) _NOEXCEPT {return __builtin_nearbyintl(__x);} template -inline _LIBCPP_HIDE_FROM_ABI +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI typename std::enable_if::value, double>::type nearbyint(_A1 __x) _NOEXCEPT {return __builtin_nearbyint((double)__x);} @@ -1568,23 +1568,23 @@ remquo(_A1 __x, _A2 __y, int* __z) _NOEXCEPT // rint -inline _LIBCPP_HIDE_FROM_ABI float rint(float __x) _NOEXCEPT +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float rint(float __x) _NOEXCEPT { return __builtin_rintf(__x); } template -_LIBCPP_HIDE_FROM_ABI double rint(double __x) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double rint(double __x) _NOEXCEPT { return __builtin_rint(__x); } -inline _LIBCPP_HIDE_FROM_ABI long double rint(long double __x) _NOEXCEPT +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double rint(long double __x) _NOEXCEPT { return __builtin_rintl(__x); } template -inline _LIBCPP_HIDE_FROM_ABI +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI typename std::enable_if::value, double>::type rint(_A1 __x) _NOEXCEPT { @@ -1593,23 +1593,23 @@ rint(_A1 __x) _NOEXCEPT // round -inline _LIBCPP_HIDE_FROM_ABI float round(float __x) _NOEXCEPT +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float round(float __x) _NOEXCEPT { return __builtin_round(__x); } template -_LIBCPP_HIDE_FROM_ABI double round(double __x) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double round(double __x) _NOEXCEPT { return __builtin_round(__x); } -inline _LIBCPP_HIDE_FROM_ABI long double round(long double __x) _NOEXCEPT +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double round(long double __x) _NOEXCEPT { return __builtin_roundl(__x); } template -inline _LIBCPP_HIDE_FROM_ABI +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI typename std::enable_if::value, double>::type round(_A1 __x) _NOEXCEPT { @@ -1666,23 +1666,23 @@ tgamma(_A1 __x) _NOEXCEPT {return __builtin_tgamma((double)__x);} // trunc -inline _LIBCPP_HIDE_FROM_ABI float trunc(float __x) _NOEXCEPT +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float trunc(float __x) _NOEXCEPT { return __builtin_trunc(__x); } template -_LIBCPP_HIDE_FROM_ABI double trunc(double __x) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double trunc(double __x) _NOEXCEPT { return __builtin_trunc(__x); } -inline _LIBCPP_HIDE_FROM_ABI long double trunc(long double __x) _NOEXCEPT +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double trunc(long double __x) _NOEXCEPT { return __builtin_truncl(__x); } template -inline _LIBCPP_HIDE_FROM_ABI +_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI typename std::enable_if::value, double>::type trunc(_A1 __x) _NOEXCEPT { diff --git a/libcxx/include/stdlib.h b/libcxx/include/stdlib.h index 64581b6..4dd3a9c 100644 --- a/libcxx/include/stdlib.h +++ b/libcxx/include/stdlib.h @@ -110,24 +110,24 @@ extern "C++" { // MSVCRT already has the correct prototype in if __cplusplus is defined #if !defined(_LIBCPP_MSVCRT) && !defined(__sun__) -inline _LIBCPP_INLINE_VISIBILITY long abs(long __x) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY long abs(long __x) _NOEXCEPT { return __builtin_labs(__x); } -inline _LIBCPP_INLINE_VISIBILITY long long abs(long long __x) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY long long abs(long long __x) _NOEXCEPT { return __builtin_llabs(__x); } #endif // !defined(_LIBCPP_MSVCRT) && !defined(__sun__) #if !defined(__sun__) -inline _LIBCPP_INLINE_VISIBILITY float abs(float __lcpp_x) _NOEXCEPT { +_LIBCPP_NODISCARD_EXT 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 { +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY double abs(double __lcpp_x) _NOEXCEPT { return __builtin_fabs(__lcpp_x); } -inline _LIBCPP_INLINE_VISIBILITY long double +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY long double abs(long double __lcpp_x) _NOEXCEPT { return __builtin_fabsl(__lcpp_x); } diff --git a/libcxx/test/libcxx/diagnostics/math_nodiscard_extensions.verify.cpp b/libcxx/test/libcxx/diagnostics/math_nodiscard_extensions.verify.cpp new file mode 100644 index 0000000..a3db61b --- /dev/null +++ b/libcxx/test/libcxx/diagnostics/math_nodiscard_extensions.verify.cpp @@ -0,0 +1,156 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03 + +// We don't control the implementation of the math.h functions on windows +// UNSUPPORTED: windows + +// check that const cmath functions are declared [[nodiscard]] + +#include + +void test() { + std::signbit(0.f); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::signbit(0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::signbit(0.l); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::signbit(0); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::signbit(0U); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + + std::fpclassify(0.f); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::fpclassify(0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::fpclassify(0.l); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::fpclassify(0); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::fpclassify(0U); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + + std::isfinite(0.f); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isfinite(0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isfinite(0.l); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isfinite(0); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isfinite(0U); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + + std::isinf(0.f); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isinf(0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isinf(0.l); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isinf(0); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isinf(0U); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + + std::isnan(0.f); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isnan(0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isnan(0.l); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isnan(0); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isnan(0U); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + + std::isnormal(0.f); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isnormal(0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isnormal(0.l); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isnormal(0); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isnormal(0U); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + + std::isgreater(0.f, 0.f); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isgreater(0., 0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isgreater(0.l, 0.l); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isgreater(0, 0); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isgreater(0U, 0U); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + + std::isgreaterequal(0.f, 0.f); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isgreaterequal(0., 0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isgreaterequal(0.l, 0.l); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isgreaterequal(0, 0); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isgreaterequal(0U, 0U); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + + std::isless(0.f, 0.f); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isless(0., 0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isless(0.l, 0.l); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isless(0, 0); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isless(0U, 0U); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + + std::islessequal(0.f, 0.f); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::islessequal(0., 0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::islessequal(0.l, 0.l); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::islessequal(0, 0); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::islessequal(0U, 0U); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + + std::islessgreater(0.f, 0.f); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::islessgreater(0., 0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::islessgreater(0.l, 0.l); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::islessgreater(0, 0); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::islessgreater(0U, 0U); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + + std::isunordered(0.f, 0.f); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isunordered(0., 0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isunordered(0.l, 0.l); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isunordered(0, 0); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::isunordered(0U, 0U); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + + std::ceil(0.f); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::ceil(0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::ceil(0.l); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::ceil(0); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::ceil(0U); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + + std::fabs(0.f); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::fabs(0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::fabs(0.l); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::fabs(0); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::fabs(0U); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + + std::floor(0.f); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::floor(0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::floor(0.l); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::floor(0); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::floor(0U); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + + std::cbrt(0.f); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::cbrt(0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::cbrt(0.l); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::cbrt(0); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::cbrt(0U); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + + std::copysign(0.f, 0.f); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::copysign(0., 0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::copysign(0.l, 0.l); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::copysign(0, 0); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::copysign(0U, 0U); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + + std::fmax(0.f, 0.f); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::fmax(0., 0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::fmax(0.l, 0.l); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::fmax(0, 0); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::fmax(0U, 0U); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + + std::fmin(0.f, 0.f); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::fmin(0., 0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::fmin(0.l, 0.l); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::fmin(0, 0); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::fmin(0U, 0U); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + + std::nearbyint(0.f); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::nearbyint(0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::nearbyint(0.l); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::nearbyint(0); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::nearbyint(0U); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + + std::rint(0.f); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::rint(0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::rint(0.l); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::rint(0); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::rint(0U); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + + std::round(0.f); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::round(0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::round(0.l); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::round(0); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::round(0U); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + + std::trunc(0.f); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::trunc(0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::trunc(0.l); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::trunc(0); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} + std::trunc(0U); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}} +} -- 2.7.4