[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

Noel Grandin noel.grandin at collabora.co.uk
Mon Dec 5 05:54:00 UTC 2016


 compilerplugins/clang/passstuffbyref.cxx      |   50 +++++++++++++++++++-------
 compilerplugins/clang/test/passstuffbyref.cxx |   28 ++++++++++++++
 solenv/CompilerTest_compilerplugins_clang.mk  |    1 
 3 files changed, 67 insertions(+), 12 deletions(-)

New commits:
commit 8cf59c674326d93de049ffe2c1d73d7f32e70d37
Author: Noel Grandin <noel.grandin at collabora.co.uk>
Date:   Fri Dec 2 17:03:37 2016 +0200

    make passstuffbyref plugin ignore std::move'd params
    
    request from vmiklos
    
    Change-Id: If263beb0623d725e406003bb1660df10fe4b4e35
    Reviewed-on: https://gerrit.libreoffice.org/31555
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>

diff --git a/compilerplugins/clang/passstuffbyref.cxx b/compilerplugins/clang/passstuffbyref.cxx
index ad6c100..8695ae6 100644
--- a/compilerplugins/clang/passstuffbyref.cxx
+++ b/compilerplugins/clang/passstuffbyref.cxx
@@ -185,24 +185,50 @@ void PassStuffByRef::checkParams(const FunctionDecl * functionDecl) {
     if (!functionDecl->doesThisDeclarationHaveABody()) {
         return;
     }
+    auto cxxConstructorDecl = dyn_cast<CXXConstructorDecl>(functionDecl);
     unsigned n = functionDecl->getNumParams();
     for (unsigned i = 0; i != n; ++i) {
         const ParmVarDecl * pvDecl = functionDecl->getParamDecl(i);
         auto const t = pvDecl->getType();
-        if (isFat(t)) {
-            report(
-                DiagnosticsEngine::Warning,
-                ("passing %0 by value, rather pass by const lvalue reference"),
-                pvDecl->getLocation())
-                << t << pvDecl->getSourceRange();
-            auto can = functionDecl->getCanonicalDecl();
-            if (can->getLocation() != functionDecl->getLocation()) {
-                report(
-                    DiagnosticsEngine::Note, "function is declared here:",
-                    can->getLocation())
-                    << can->getSourceRange();
+        if (!isFat(t)) {
+            continue;
+        }
+        // Ignore cases where the parameter is std::move'd.
+        // This is a fairly simple check, might need some more complexity if the parameter is std::move'd
+        // somewhere else in the constructor.
+        bool bFoundMove = false;
+        if (cxxConstructorDecl) {
+            for (CXXCtorInitializer const * cxxCtorInitializer : cxxConstructorDecl->inits()) {
+                if (cxxCtorInitializer->isMemberInitializer())
+                {
+                    auto cxxConstructExpr = dyn_cast<CXXConstructExpr>(cxxCtorInitializer->getInit());
+                    if (cxxConstructExpr && cxxConstructExpr->getNumArgs() == 1)
+                    {
+                        if (auto callExpr = dyn_cast<CallExpr>(cxxConstructExpr->getArg(0))) {
+                            if (loplugin::DeclCheck(callExpr->getCalleeDecl()).Function("move").StdNamespace()) {
+                                bFoundMove = true;
+                                break;
+                            }
+                        }
+                    }
+                }
             }
         }
+        if (bFoundMove) {
+            continue;
+        }
+        report(
+            DiagnosticsEngine::Warning,
+            ("passing %0 by value, rather pass by const lvalue reference"),
+            pvDecl->getLocation())
+            << t << pvDecl->getSourceRange();
+        auto can = functionDecl->getCanonicalDecl();
+        if (can->getLocation() != functionDecl->getLocation()) {
+            report(
+                DiagnosticsEngine::Note, "function is declared here:",
+                can->getLocation())
+                << can->getSourceRange();
+        }
     }
     // ignore stuff that forms part of the stable URE interface
     if (isInUnoIncludeFile(functionDecl)) {
diff --git a/compilerplugins/clang/test/passstuffbyref.cxx b/compilerplugins/clang/test/passstuffbyref.cxx
new file mode 100644
index 0000000..d19b139
--- /dev/null
+++ b/compilerplugins/clang/test/passstuffbyref.cxx
@@ -0,0 +1,28 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <rtl/ustring.hxx>
+
+struct S {
+    OUString mv;
+
+    // request from vmiklos: make sure we ignore cases where the passed in parameter is std::move'd
+    S(OUString v)
+      : mv(std::move(v)) {}
+};
+
+
+void f() // expected-error {{Unreferenced externally visible function definition [loplugin:unreffun]}}
+{
+    S* s;
+    OUString v;
+    s = new S(v);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk b/solenv/CompilerTest_compilerplugins_clang.mk
index 8bae924..dc3a67e 100644
--- a/solenv/CompilerTest_compilerplugins_clang.mk
+++ b/solenv/CompilerTest_compilerplugins_clang.mk
@@ -12,6 +12,7 @@ $(eval $(call gb_CompilerTest_CompilerTest,compilerplugins_clang))
 $(eval $(call gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
     compilerplugins/clang/test/datamembershadow \
     compilerplugins/clang/test/finalprotected \
+    compilerplugins/clang/test/passstuffbyref \
     compilerplugins/clang/test/oslendian-1 \
     compilerplugins/clang/test/oslendian-2 \
     compilerplugins/clang/test/oslendian-3 \


More information about the Libreoffice-commits mailing list