[Libreoffice-commits] core.git: 2 commits - compilerplugins/clang cui/source include/salhelper

Stephan Bergmann sbergman at redhat.com
Thu Feb 5 07:55:03 PST 2015


 compilerplugins/clang/passstuffbyref.cxx |   82 ++++++++++++++++++++-----------
 cui/source/options/optaboutconfig.cxx    |    2 
 include/salhelper/refobj.hxx             |    4 +
 3 files changed, 59 insertions(+), 29 deletions(-)

New commits:
commit 0a1c6d4554cdab448249e1c574af6a90d5e46e6e
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Thu Feb 5 16:53:30 2015 +0100

    Extend loplugin:passstuffbyref to handle lambdas
    
    ...even if it is known to be dangerous
    
    Change-Id: Ied96284e33b966bf072d0961054479ec7f891dea

diff --git a/compilerplugins/clang/passstuffbyref.cxx b/compilerplugins/clang/passstuffbyref.cxx
index 51e324a..5617650 100644
--- a/compilerplugins/clang/passstuffbyref.cxx
+++ b/compilerplugins/clang/passstuffbyref.cxx
@@ -16,6 +16,12 @@
 // It's not very efficient, because we generally end up copying it twice - once into the parameter and
 // again into the destination.
 // They should rather be passed by reference.
+//
+// Generally recommending lambda capture by-ref rather than by-copy is even more
+// problematic than with function parameters, as a lambda instance can easily
+// outlive a referrenced variable.  So once lambdas start to get used in more
+// sophisticated ways than passing them into standard algorithms, this plugin's
+// advice, at least for explicit captures, will need to be revisited.
 
 namespace {
 
@@ -28,6 +34,11 @@ public:
     virtual void run() override { TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); }
 
     bool VisitFunctionDecl(const FunctionDecl * decl);
+
+    bool VisitLambdaExpr(const LambdaExpr * expr);
+
+private:
+    bool isFat(QualType type, std::string * name);
 };
 
 bool PassStuffByRef::VisitFunctionDecl(const FunctionDecl * functionDecl) {
@@ -49,41 +60,58 @@ bool PassStuffByRef::VisitFunctionDecl(const FunctionDecl * functionDecl) {
     unsigned n = functionDecl->getNumParams();
     for (unsigned i = 0; i != n; ++i) {
         const ParmVarDecl * pvDecl = functionDecl->getParamDecl(i);
-        QualType t1 { pvDecl->getType() };
-        if (!t1->isClassType()) {
-            continue;
-        }
-        string typeName = t1.getUnqualifiedType().getCanonicalType().getAsString();
-
-        bool bFound = false;
-        if (typeName == "class rtl::OUString" ||
-            typeName == "class rtl::OString" ||
-            typeName.find("class com::sun::star::uno::Sequence") == 0) {
-            bFound = true;
-        }
-
-        if (!bFound && !t1->isIncompleteType()) {
-            const clang::Type* type = t1.getTypePtrOrNull();
-            if (type != nullptr) {
-                clang::CharUnits size =  compiler.getASTContext().getTypeSizeInChars(type);
-                if (size.getQuantity() > 64) {
-                    bFound = true;
-                }
-            }
-        }
-
-        if (bFound) {
+        std::string name;
+        if (isFat(pvDecl->getType(), &name)) {
             report(
                 DiagnosticsEngine::Warning,
-                "passing " + typeName + " by value, rather pass by reference .e.g. 'const " + typeName + "&'",
-                pvDecl->getSourceRange().getBegin())
-              << pvDecl->getSourceRange();
+                ("passing '%0' by value, rather pass by reference, e.g., '%0"
+                 " const &'"),
+                pvDecl->getLocation())
+                << name << pvDecl->getSourceRange();
         }
+    }
+    return true;
+}
 
+bool PassStuffByRef::VisitLambdaExpr(const LambdaExpr * expr) {
+    if (ignoreLocation(expr)) {
+        return true;
+    }
+    for (auto const & i: expr->captures()) {
+        if (i.getCaptureKind() == LambdaCaptureKind::LCK_ByCopy) {
+            std::string name;
+            if (isFat(i.getCapturedVar()->getType(), &name)) {
+                report(
+                    DiagnosticsEngine::Warning,
+                    ("%0 capture of '%1' variable by copy, rather use capture"
+                     " by reference---UNLESS THE LAMBDA OUTLIVES THE VARIABLE"),
+                    i.getLocation())
+                    << (i.isImplicit() ? "implicit" : "explicit") << name
+                    << expr->getSourceRange();
+            }
+        }
     }
     return true;
 }
 
+bool PassStuffByRef::isFat(QualType type, std::string * name) {
+    if (!type->isClassType()) {
+        return false;
+    }
+    *name = type.getUnqualifiedType().getCanonicalType().getAsString();
+    if (*name == "class rtl::OUString" || *name == "class rtl::OString"
+        || name->find("class com::sun::star::uno::Sequence") == 0)
+    {
+        return true;
+    }
+    if (type->isIncompleteType()) {
+        return false;
+    }
+    Type const * t2 = type.getTypePtrOrNull();
+    return t2 != nullptr
+        && compiler.getASTContext().getTypeSizeInChars(t2).getQuantity() > 64;
+}
+
 loplugin::Plugin::Registration< PassStuffByRef > X("passstuffbyref");
 
 }
diff --git a/cui/source/options/optaboutconfig.cxx b/cui/source/options/optaboutconfig.cxx
index 3b2b0f9..7841205 100644
--- a/cui/source/options/optaboutconfig.cxx
+++ b/cui/source/options/optaboutconfig.cxx
@@ -670,7 +670,7 @@ IMPL_LINK_NOARG( CuiAboutConfigTabPage, StandardHdl_Impl )
         m_pPrefBox->SetEntryText( sDialogValue,  pEntry, 3 );
         //update m_prefBoxEntries
         SvTreeListEntries::iterator it = std::find_if(m_prefBoxEntries.begin(), m_prefBoxEntries.end(),
-          [sPropertyPath, sPropertyName](SvTreeListEntry &entry) -> bool
+          [&sPropertyPath, &sPropertyName](SvTreeListEntry &entry) -> bool
           {
               return static_cast< SvLBoxString* >( entry.GetItem(1) )->GetText().equals( sPropertyPath ) &&
                       static_cast< SvLBoxString* >( entry.GetItem(2) )->GetText().equals( sPropertyName );
commit 846d340d6a75110a901ae4922a261ca83a8a4dfa
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Thu Feb 5 16:45:45 2015 +0100

    Deprecate salhelper::SimpleReferenceObject
    
    Change-Id: I0721c0b620a7de994d71752034daeeb4d00659f7

diff --git a/include/salhelper/refobj.hxx b/include/salhelper/refobj.hxx
index f918784..32ca6e1 100644
--- a/include/salhelper/refobj.hxx
+++ b/include/salhelper/refobj.hxx
@@ -28,8 +28,10 @@
 namespace salhelper
 {
 
+/** A base implementation for reference-counted objects.
 
-
+    @deprecated use salhelper::SimpleReferenceObject instead
+*/
 class ReferenceObject
 {
     /** Representation.


More information about the Libreoffice-commits mailing list