[Libreoffice-commits] core.git: compilerplugins/clang include/o3tl

Stephan Bergmann (via logerrit) logerrit at kemper.freedesktop.org
Thu Jun 17 12:17:42 UTC 2021


 compilerplugins/clang/redundantcast.cxx      |   27 +++++++++++++++++++++++++++
 compilerplugins/clang/test/redundantcast.cxx |    2 ++
 include/o3tl/temporary.hxx                   |    2 +-
 3 files changed, 30 insertions(+), 1 deletion(-)

New commits:
commit 21da7d80aa1ee0f9661dcde37bc4629d5eb9d50e
Author:     Stephan Bergmann <sbergman at redhat.com>
AuthorDate: Wed Jun 16 15:59:24 2021 +0200
Commit:     Stephan Bergmann <sbergman at redhat.com>
CommitDate: Thu Jun 17 14:16:59 2021 +0200

    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 <typename T> constexpr T& temporary(T&& x) { return x; }
    >                                                              ^
    > sal/rtl/random.cxx:97:37: note: in instantiation of function template specialization 'o3tl::temporary<double>' 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 at redhat.com>

diff --git a/compilerplugins/clang/redundantcast.cxx b/compilerplugins/clang/redundantcast.cxx
index 088349fa1d9c..27566809494c 100644
--- a/compilerplugins/clang/redundantcast.cxx
+++ b/compilerplugins/clang/redundantcast.cxx
@@ -109,6 +109,14 @@ public:
                 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 @@ private:
         return compiler.getSourceManager().isMacroBodyExpansion(loc)
             && ignoreLocation(compiler.getSourceManager().getSpellingLoc(loc));
     }
+
+    Expr const * returnExpr_ = nullptr;
 };
 
 bool RedundantCast::VisitImplicitCastExpr(const ImplicitCastExpr * expr) {
@@ -502,6 +512,23 @@ bool RedundantCast::VisitCXXStaticCastExpr(CXXStaticCastExpr const * expr) {
     {
         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 97f4e6f73777..2a3721bb0c2e 100644
--- a/compilerplugins/clang/test/redundantcast.cxx
+++ b/compilerplugins/clang/test/redundantcast.cxx
@@ -286,6 +286,8 @@ void testStaticCast() {
     (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 7b6c9a1f9fc7..50d006e26d0e 100644
--- a/include/o3tl/temporary.hxx
+++ b/include/o3tl/temporary.hxx
@@ -18,7 +18,7 @@ namespace o3tl
 // 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 <typename T> constexpr T& temporary(T&& x) { return x; }
+template <typename T> constexpr T& temporary(T&& x) { return static_cast<T&>(x); }
 template <typename T> constexpr T& temporary(T&) = delete;
 }
 


More information about the Libreoffice-commits mailing list