summaryrefslogtreecommitdiffstats
path: root/compilerplugins
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2021-09-30 09:40:29 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2021-09-30 11:24:33 +0200
commit3b8e53f66ffd4d631a850fe76250124dc4a195c3 (patch)
tree2613882a4876f0a66324b7e29e61c46b3ec451b0 /compilerplugins
parentloplugin:includeform (clang-cl) (diff)
downloadcore-3b8e53f66ffd4d631a850fe76250124dc4a195c3.tar.gz
core-3b8e53f66ffd4d631a850fe76250124dc4a195c3.zip
loplugin:constparams improve handling of pointer params
Change-Id: I4c0002e72703eded435bfe4985f5b0121bf8524b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122843 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/constparams.cxx27
-rw-r--r--compilerplugins/clang/test/constparams.cxx22
2 files changed, 47 insertions, 2 deletions
diff --git a/compilerplugins/clang/constparams.cxx b/compilerplugins/clang/constparams.cxx
index c72ccc9dd488..17cd941f8f22 100644
--- a/compilerplugins/clang/constparams.cxx
+++ b/compilerplugins/clang/constparams.cxx
@@ -60,6 +60,8 @@ public:
|| loplugin::hasPathnamePrefix(fn, SRCDIR "/pyuno/source/module/pyuno_struct.cxx")
|| loplugin::hasPathnamePrefix(fn, SRCDIR "/pyuno/source/module/pyuno.cxx")
|| loplugin::hasPathnamePrefix(fn, SRCDIR "/sw/source/filter/ascii/ascatr.cxx")
+ // TODO this plugin doesn't handle it well when we take the address of a poiner
+ || loplugin::hasPathnamePrefix(fn, SRCDIR "/svl/source/misc/sharedstringpool.cxx")
)
return;
@@ -96,6 +98,7 @@ public:
bool TraverseCXXMethodDecl(CXXMethodDecl * f);
bool TraverseCXXConstructorDecl(CXXConstructorDecl * f);
bool VisitDeclRefExpr(const DeclRefExpr *);
+ bool VisitLambdaExpr(const LambdaExpr*);
private:
bool CheckTraverseFunctionDecl(FunctionDecl *);
@@ -159,6 +162,8 @@ bool ConstParams::CheckTraverseFunctionDecl(FunctionDecl * functionDecl)
if (functionDecl->isMain()) {
return false;
}
+ if (functionDecl->getTemplatedKind() != FunctionDecl::TK_NonTemplate)
+ return false;
// ignore the macros from include/tools/link.hxx
auto canonicalDecl = functionDecl->getCanonicalDecl();
@@ -189,6 +194,7 @@ bool ConstParams::CheckTraverseFunctionDecl(FunctionDecl * functionDecl)
|| name.startswith("Read_F_")
// UNO component entry points
|| name.endswith("component_getFactory")
+ || name.endswith("_get_implementation")
// callback for some external code?
|| name == "ScAddInAsyncCallBack"
// used as function pointers
@@ -256,6 +262,23 @@ bool ConstParams::VisitDeclRefExpr( const DeclRefExpr* declRefExpr )
return true;
}
+bool ConstParams::VisitLambdaExpr(const LambdaExpr* lambdaExpr)
+{
+ if (ignoreLocation(lambdaExpr))
+ return true;
+ for (auto captureIt = lambdaExpr->capture_begin(); captureIt != lambdaExpr->capture_end();
+ ++captureIt)
+ {
+ const LambdaCapture& capture = *captureIt;
+ if (capture.capturesVariable())
+ {
+ if (auto varDecl = dyn_cast<ParmVarDecl>(capture.getCapturedVar()))
+ interestingParamSet.erase(varDecl);
+ }
+ }
+ return true;
+}
+
// Walk up from a statement that contains a DeclRefExpr, checking if the usage means that the
// related ParamVarDecl can be const.
bool ConstParams::checkIfCanBeConst(const Stmt* stmt, const ParmVarDecl* parmVarDecl)
@@ -308,11 +331,11 @@ bool ConstParams::checkIfCanBeConst(const Stmt* stmt, const ParmVarDecl* parmVar
if (auto unaryOperator = dyn_cast<UnaryOperator>(parent)) {
UnaryOperator::Opcode op = unaryOperator->getOpcode();
- if (op == UO_AddrOf || op == UO_PreInc || op == UO_PostInc
+ if (op == UO_PreInc || op == UO_PostInc
|| op == UO_PreDec || op == UO_PostDec) {
return false;
}
- if (op == UO_Deref) {
+ if (op == UO_Deref || op == UO_AddrOf) {
return checkIfCanBeConst(parent, parmVarDecl);
}
return true;
diff --git a/compilerplugins/clang/test/constparams.cxx b/compilerplugins/clang/test/constparams.cxx
index 60d0148c1d69..e6b22ca91529 100644
--- a/compilerplugins/clang/test/constparams.cxx
+++ b/compilerplugins/clang/test/constparams.cxx
@@ -48,4 +48,26 @@ void f4(std::string * p) {
*p = std::string("xxx");
}
+
+namespace test5
+{
+struct Rectangle {};
+
+struct Foo
+{
+ void CallConst(const Rectangle*);
+ void CallNonConst(Rectangle*);
+ // expected-error@+1 {{this parameter can be const test5::Foo::ImplInvalidateParentFrameRegion [loplugin:constparams]}}
+ void ImplInvalidateParentFrameRegion( Rectangle& rRegion )
+ {
+ CallConst( &rRegion );
+ }
+ // no warning expected
+ void ImplInvalidateParentFrameRegion2( Rectangle& rRegion )
+ {
+ CallNonConst( &rRegion );
+ }
+};
+
+}
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */