summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2021-06-16 15:59:24 +0200
committerStephan Bergmann <sbergman@redhat.com>2021-06-17 14:16:59 +0200
commit21da7d80aa1ee0f9661dcde37bc4629d5eb9d50e (patch)
tree72f89372b9a24fbab862646c0751f0d137807ef8 /compilerplugins
parent12ad78492e06cfece2b166ed67630f30a439b452 (diff)
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@redhat.com>
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/redundantcast.cxx27
-rw-r--r--compilerplugins/clang/test/redundantcast.cxx2
2 files changed, 29 insertions, 0 deletions
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());