[libcxx-commits] [libcxx] [libc++][cmath] Adding `[[nodicard]]` (PR #171763)
Hristo Hristov via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Dec 11 19:20:33 PST 2025
================
@@ -6,162 +6,477 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03
-
// We don't control the implementation of the math.h functions on windows
// UNSUPPORTED: windows
+// Check that functions are marked `[[nodiscard]]`.
// Check that functions from `<cmath>` that Clang marks with the `[[gnu::const]]` attribute are declared
// `[[nodiscard]]`.
-// clang-format off
-
#include <cmath>
+
#include "test_macros.h"
void test() {
- // These tests rely on Clang's behaviour of adding `[[gnu::const]]` to the double overload of most of the functions
- // below.
- // Without that attribute being added implicitly, this test can't be checked consistently because its result depends
- // on whether we're getting libc++'s own `std::foo(double)` or the underlying C library's `foo(double)`.
-#ifdef TEST_COMPILER_CLANG
- std::ceil(0.); // 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::floor(0.); // 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::copysign(0., 0.); // 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::fmin(0., 0.); // 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::rint(0.); // 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::trunc(0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}}
+ // Some tests rely on Clang's behaviour of adding `[[gnu::const]]` to the double overload of most of the functions
+ // below. Without that attribute being added implicitly, this test can't be checked consistently because its result
+ // depends on whether we're getting libc++'s own `std::foo(double)` or the underlying C library's `foo(double)`, e.g.
+ // std::fabs(double).
+
+ // Functions
+
+ std::fabs(0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::fabs(0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::fabs(0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::fabs(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ // Floating point manipulation functions
+
+ std::copysign(0.F, 0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::copysign(0.L, 0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::copysign(0U, 0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ // Error functions
+
+ std::erf(0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::erf(0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::erf(0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::erf(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::erfc(0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::erfc(0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::erfc(0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::erfc(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ // Exponential functions
+
+ std::exp(0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::exp(0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::exp(0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::exp(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ // Floating point manipulation functions
+
+ std::frexp(0.F, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::frexp(0., 0); /// expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::frexp(0.L, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::frexp(0U, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::ldexp(0.F, 2); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ldexp(0., 2); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::ldexp(0.L, 2); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ldexp(0U, 2); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ // Exponential functions
+
+ std::exp2(0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::exp2(0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::exp2(0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::exp2(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::expm1(0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::expm1(0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::expm1(0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::expm1(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ // Floating point manipulation functions
+
+ std::scalbln(0.F, 0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::scalbln(0., 0.L); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::scalbln(0.L, 0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::scalbln(0U, 0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::scalbn(0.F, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::scalbn(0., 0); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::scalbn(0.L, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::scalbn(0U, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ // Power functions
+
+ std::pow(0.F, 0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::pow(0., 0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::pow(0.L, 0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::pow(0U, 0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ // Basic operations
+
+ std::fdim(0.F, 0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::fdim(0., 0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::fdim(0.L, 0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::fdim(0U, 0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::fma(0.F, 0.F, 0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::fma(0., 0., 0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::fma(0.L, 0.L, 0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::fma(0U, 0U, 0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ // Error functions
+
+ std::lgamma(0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::lgamma(0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::lgamma(0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::lgamma(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::tgamma(0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::tgamma(0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::tgamma(0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::tgamma(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ // Hyperbolic functions
+
+ std::cosh(0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::cosh(0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::cosh(0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::cosh(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::sinh(0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::sinh(0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::sinh(0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::sinh(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::tanh(0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::tanh(0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::tanh(0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::tanh(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ // Power functions
+
+ std::hypot(0.F, 0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::hypot(0., 0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::hypot(0.L, 0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::hypot(0U, 0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+#if TEST_STD_VER >= 17
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::hypot(0.F, 0.F, 0.F);
+ // // expected-warning-re at +1 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::hypot(0., 0., 0.);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::hypot(0.L, 0.L, 0.L);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::hypot(0U, 0U, 0U);
+#endif // _LIBCPP_STD_VER >= 17
+
+ // Hyperbolic functions
+
+ std::acosh(0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::acosh(0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::acosh(0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::acosh(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::asinh(0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::asinh(0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::asinh(0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::asinh(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::atanh(0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::atanh(0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::atanh(0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::atanh(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ // Trigonometric functions
+
+ std::acos(0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::acos(0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::acos(0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::acos(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::asin(0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::asin(0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::asin(0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::asin(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::atan(0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::atan(0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::atan(0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::atan(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::atan2(0.F, 0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::atan2(0., 0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::atan2(0.L, 0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::atan2(0U, 0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ // Exponential functions
+
+ std::log(0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::log(0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::log(0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::log(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::log10(0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::log10(0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::log10(0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::log10(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::ilogb(0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ilogb(0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::ilogb(0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ilogb(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::log1p(0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::log1p(0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::log1p(0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::log1p(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::log2(0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::log2(0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::log2(0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::log2(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::logb(0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::logb(0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::logb(0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::logb(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ // Basic operations
+
+ std::fmax(0.F, 0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::fmax(0., 0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::fmax(0.L, 0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::fmax(0U, 0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::fmin(0.F, 0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::fmin(0., 0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::fmin(0.L, 0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::fmin(0U, 0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::fmod(0.F, 0.F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::fmod(0., 0.); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::fmod(0.L, 0.L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::fmod(0U, 0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::modf(0.F, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::modf(0., 0); // expected-warning-re 0-1 {{ignoring return value of function declared with {{.*}} attribute}}
+ std::modf(0.L, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
----------------
Zingam wrote:
OK
I am not sure if my current solution for the double overloads is correct: "expected-warning-re 0-1".
https://github.com/llvm/llvm-project/pull/171763
More information about the libcxx-commits
mailing list