[libcxx-commits] [libcxx] 633927d - [libc++] Add [[nodiscard]] extensions in <math.h>
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Jan 12 09:34:54 PST 2023
Author: Nikolas Klauser
Date: 2023-01-12T18:34:49+01:00
New Revision: 633927db844e47c87dd93198e2c2763dd10f668f
URL: https://github.com/llvm/llvm-project/commit/633927db844e47c87dd93198e2c2763dd10f668f
DIFF: https://github.com/llvm/llvm-project/commit/633927db844e47c87dd93198e2c2763dd10f668f.diff
LOG: [libc++] Add [[nodiscard]] extensions in <math.h>
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
Added:
libcxx/test/libcxx/diagnostics/math_nodiscard_extensions.verify.cpp
Modified:
libcxx/docs/UsingLibcxx.rst
libcxx/include/math.h
libcxx/include/stdlib.h
Removed:
################################################################################
diff --git a/libcxx/docs/UsingLibcxx.rst b/libcxx/docs/UsingLibcxx.rst
index 5cf608e0b3b13..6fac013bbd715 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 1636ec4b7050e..a23d1ff3ed378 100644
--- a/libcxx/include/math.h
+++ b/libcxx/include/math.h
@@ -367,29 +367,29 @@ extern "C++" {
// signbit
template <class _A1, std::__enable_if_t<std::is_floating_point<_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 __builtin_signbit(__x);
}
template <class _A1, std::__enable_if_t<std::is_integral<_A1>::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 <class _A1, std::__enable_if_t<std::is_integral<_A1>::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 <class _A1, std::__enable_if_t<std::is_floating_point<_A1>::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 <class _A1, std::__enable_if_t<std::is_integral<_A1>::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 <class _A1,
std::__enable_if_t<std::is_arithmetic<_A1>::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 <class _A1,
std::__enable_if_t<std::is_arithmetic<_A1>::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 <class _A1,
std::__enable_if_t<std::is_arithmetic<_A1>::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 <class _A1>
-_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 <class _A1, std::__enable_if_t<std::is_floating_point<_A1>::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 <class _A1, std::__enable_if_t<std::is_integral<_A1>::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 <class _A1, std::__enable_if_t<std::is_floating_point<_A1>::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 <class _A1, std::__enable_if_t<std::is_integral<_A1>::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 <class _A1,
class _A2,
std::__enable_if_t<std::is_arithmetic<_A1>::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 <class _A1,
class _A2,
std::__enable_if_t<std::is_arithmetic<_A1>::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 <class _A1,
class _A2,
std::__enable_if_t<std::is_arithmetic<_A1>::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 <class _A1,
class _A2,
std::__enable_if_t<std::is_arithmetic<_A1>::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 <class _A1,
class _A2,
std::__enable_if_t<std::is_arithmetic<_A1>::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 <class _A1,
class _A2,
std::__enable_if_t<std::is_arithmetic<_A1>::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 <class = int>
-_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 <class _A1>
-inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI
typename std::enable_if<std::is_integral<_A1>::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 <class = int>
-_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 <class _A1>
-inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI
typename std::enable_if<std::is_integral<_A1>::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 <class = int>
-_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 <class _A1>
-inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI
typename std::enable_if<std::is_integral<_A1>::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 <class = int>
-_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 <class _A1>
-inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI
typename std::enable_if<std::is_integral<_A1>::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 <class _A1, class _A2>
-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 <class = int>
-_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 <class _A1, class _A2>
-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 <class = int>
-_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 <class _A1, class _A2>
-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 <class = int>
-_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 <class _A1>
-inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI
typename std::enable_if<std::is_integral<_A1>::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 <class = int>
-_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 <class _A1>
-inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI
typename std::enable_if<std::is_integral<_A1>::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 <class = int>
-_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 <class _A1>
-inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI
typename std::enable_if<std::is_integral<_A1>::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 <class = int>
-_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 <class _A1>
-inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI
typename std::enable_if<std::is_integral<_A1>::value, double>::type
trunc(_A1 __x) _NOEXCEPT
{
diff --git a/libcxx/include/stdlib.h b/libcxx/include/stdlib.h
index 64581b67f245f..4dd3a9c14ab04 100644
--- a/libcxx/include/stdlib.h
+++ b/libcxx/include/stdlib.h
@@ -110,24 +110,24 @@ extern "C++" {
// MSVCRT already has the correct prototype in <stdlib.h> 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 0000000000000..a3db61baf5d0f
--- /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 <cmath>
+
+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}}
+}
More information about the libcxx-commits
mailing list