[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