Diff - 21da7d80aa1ee0f9661dcde37bc4629d5eb9d50e^! - core (original) (raw)

Adapt o3tl::temporary to C++23 P2266R1

With the recent implemenation of <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2266r1.html> "P2266R1: Simpler implicit move" in Clang 13 trunk as <https://github.com/llvm/llvm-project/commit/bf20631782183cd19e0bb7219e908c2bbb01a75f> "[clang] Implement P2266 Simpler implicit move", a --with-latest-c++ build started to fail with

In file included from sal/rtl/random.cxx:25: include/o3tl/temporary.hxx:21:62: error: non-const lvalue reference to type 'double' cannot bind to a temporary of type 'double' template constexpr T& temporary(T&& x) { return x; } ^ sal/rtl/random.cxx:97:37: note: in instantiation of function template specialization 'o3tl::temporary' requested here return std::modf(random, &o3tl::temporary(double())); ^

etc. (And fixing that by adding the recommended static_cast then triggered a false loplugin:redundantcast warning.)

Change-Id: I222429e9872afdedf77a07014c0a2e9e06c60b50 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117335 Tested-by: Jenkins Reviewed-by: Stephan Bergmann sbergman@redhat.com

diff --git a/compilerplugins/clang/redundantcast.cxx b/compilerplugins/clang/redundantcast.cxx index 088349f..2756680 100644 --- a/compilerplugins/clang/redundantcast.cxx +++ b/compilerplugins/clang/redundantcast.cxx

@@ -109,6 +109,14 @@ expr->isSemanticForm() ? expr : expr->getSemanticForm(), queue); }

bool TraverseReturnStmt(ReturnStmt * stmt) {
    auto const saved = returnExpr_;
    returnExpr_ = stmt->getRetValue();
    auto const ret = FilteringRewritePlugin::TraverseReturnStmt(stmt);
    returnExpr_ = saved;
    return ret;
}

bool VisitImplicitCastExpr(ImplicitCastExpr const * expr);

bool VisitCXXStaticCastExpr(CXXStaticCastExpr const * expr);

@@ -154,6 +162,8 @@ return compiler.getSourceManager().isMacroBodyExpansion(loc) && ignoreLocation(compiler.getSourceManager().getSpellingLoc(loc)); }

Expr const * returnExpr_ = nullptr;

};

bool RedundantCast::VisitImplicitCastExpr(const ImplicitCastExpr * expr) { @@ -502,6 +512,23 @@ { return true; } // For http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2266r1.html "P2266R1: Simpler // implicit move" (as implemented with <https://github.com/llvm/llvm-project/commit/ // bf20631782183cd19e0bb7219e908c2bbb01a75f> "[clang] Implement P2266 Simpler implicit move" // towards Clang 13), don't warn about a static_cast in a return statement like // // return static_cast<int &>(x); // // that needs an lvalue but where in a return statement like // // return x; // // the expression would now be an xvalue: if (k3 == VK_LValue && k1 == VK_LValue && returnExpr_ != nullptr && expr == returnExpr_->IgnoreParens()) { return true; } // Don't warn if a static_cast on a pointer to function or member function is used to // disambiguate an overloaded function: if (fnptr) {

diff --git a/compilerplugins/clang/test/redundantcast.cxx b/compilerplugins/clang/test/redundantcast.cxx index 97f4e6f..2a3721b 100644 --- a/compilerplugins/clang/test/redundantcast.cxx +++ b/compilerplugins/clang/test/redundantcast.cxx

@@ -286,6 +286,8 @@ (void) static_cast<S const &&>(csr()); }

int & testReturnStaticCast(int && x) { return static_cast<int &>(x); }

void testFunctionalCast() { (void) int(nir()); // expected-error {{redundant functional cast from 'int' to 'int' [loplugin:redundantcast]}} (void) S(nsr());

diff --git a/include/o3tl/temporary.hxx b/include/o3tl/temporary.hxx index 7b6c9a1..50d006e 100644 --- a/include/o3tl/temporary.hxx +++ b/include/o3tl/temporary.hxx

@@ -18,7 +18,7 @@ // and some call site doesn't need the value beyond the call itself (e.g., in a call like // std::modf(x, &o3tl::temporary(double())) to obtain the fractional part of x, ignoring the // integral part). template constexpr T& temporary(T&& x) { return x; } template constexpr T& temporary(T&& x) { return static_cast<T&>(x); } template constexpr T& temporary(T&) = delete; }