summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compilerplugins/clang/test/unusedfields.cxx18
-rw-r--r--compilerplugins/clang/unusedfields.cxx13
-rw-r--r--solenv/CompilerTest_compilerplugins_clang.mk4
3 files changed, 28 insertions, 7 deletions
diff --git a/compilerplugins/clang/test/unusedfields.cxx b/compilerplugins/clang/test/unusedfields.cxx
index 71489b018843..21e59fcbbdd1 100644
--- a/compilerplugins/clang/test/unusedfields.cxx
+++ b/compilerplugins/clang/test/unusedfields.cxx
@@ -116,16 +116,19 @@ struct ReadOnlyAnalysis
// expected-error@-2 {{read m_f3 [loplugin:unusedfields]}}
// expected-error@-3 {{read m_f4 [loplugin:unusedfields]}}
// expected-error@-4 {{read m_f5 [loplugin:unusedfields]}}
-// expected-error@-5 {{write m_f2 [loplugin:unusedfields]}}
-// expected-error@-6 {{write m_f3 [loplugin:unusedfields]}}
-// expected-error@-7 {{write m_f4 [loplugin:unusedfields]}}
-// expected-error@-8 {{write m_f5 [loplugin:unusedfields]}}
+// expected-error@-5 {{read m_f6 [loplugin:unusedfields]}}
+// expected-error@-6 {{write m_f2 [loplugin:unusedfields]}}
+// expected-error@-7 {{write m_f3 [loplugin:unusedfields]}}
+// expected-error@-8 {{write m_f4 [loplugin:unusedfields]}}
+// expected-error@-9 {{write m_f5 [loplugin:unusedfields]}}
+// expected-error@-10 {{write m_f6 [loplugin:unusedfields]}}
{
int m_f1;
int m_f2;
int m_f3;
std::vector<int> m_f4;
int m_f5;
+ int m_f6;
// check that we dont see a write of m_f1
ReadOnlyAnalysis() : m_f1(0) {}
@@ -141,6 +144,13 @@ struct ReadOnlyAnalysis
// check that we see a write when we pass by non-const ref
void method5() { ReadOnly1 a(m_f5); }
+
+ // check that we see a write when we pass by non-const ref
+ void method6()
+ {
+ int& r = m_f6;
+ r = 1;
+ }
};
struct ReadOnlyAnalysis2
diff --git a/compilerplugins/clang/unusedfields.cxx b/compilerplugins/clang/unusedfields.cxx
index 69ea4be9c8b2..af2be7ba6076 100644
--- a/compilerplugins/clang/unusedfields.cxx
+++ b/compilerplugins/clang/unusedfields.cxx
@@ -611,6 +611,19 @@ void UnusedFields::checkReadOnly(const FieldDecl* fieldDecl, const Expr* memberE
{
if (!parent)
{
+ // check if we have an expression like
+ // int& r = m_field;
+ auto parentsRange = compiler.getASTContext().getParents(*child);
+ if (parentsRange.begin() != parentsRange.end())
+ {
+ auto varDecl = dyn_cast_or_null<VarDecl>(parentsRange.begin()->get<Decl>());
+ // The isImplicit() call is to avoid triggering when we see the vardecl which is part of a for-range statement,
+ // which is of type 'T&&' and also an l-value-ref ?
+ if (varDecl && !varDecl->isImplicit() && loplugin::TypeCheck(varDecl->getType()).LvalueReference().NonConst())
+ {
+ bPotentiallyWrittenTo = true;
+ }
+ }
break;
}
if (isa<CXXReinterpretCastExpr>(parent))
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk b/solenv/CompilerTest_compilerplugins_clang.mk
index 8df1c2b495f7..10fa577d908a 100644
--- a/solenv/CompilerTest_compilerplugins_clang.mk
+++ b/solenv/CompilerTest_compilerplugins_clang.mk
@@ -38,13 +38,11 @@ $(eval $(call gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
compilerplugins/clang/test/unnecessaryoverride-dtor \
compilerplugins/clang/test/unnecessaryparen \
compilerplugins/clang/test/unoany \
+ compilerplugins/clang/test/unusedfields \
compilerplugins/clang/test/useuniqueptr \
compilerplugins/clang/test/vclwidgets \
))
-# FIXME Fails with clang-3.8.
-# compilerplugins/clang/test/unusedfields \
-
$(eval $(call gb_CompilerTest_use_externals,compilerplugins_clang, \
boost_headers \
cppunit \