[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