summaryrefslogtreecommitdiffstats
path: root/compilerplugins
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2018-07-27 12:30:30 +0200
committerStephan Bergmann <sbergman@redhat.com>2018-07-28 00:18:41 +0200
commit446f1720577db659525e773211e2a1a3a19bb460 (patch)
tree3c8bed7d0a822b0c46897f72803bf0b64cdad22a /compilerplugins
parent-Werror=deprecated-copy (GCC trunk towards GCC 9) (diff)
downloadcore-446f1720577db659525e773211e2a1a3a19bb460.tar.gz
core-446f1720577db659525e773211e2a1a3a19bb460.zip
Prevent loplugin:unreffun on explicitly defaulted special members
...as started to appear (with sufficiently recent Clang versions only, it appears) after c5fcb476ac8eab18152a7f6d0487daa56231fcf8 "toolkit: avoid -Werror=deprecated-copy (GCC trunk towards GCC 9)": > [CXX] toolkit/source/controls/spinningprogress.cxx > toolkit/source/controls/spinningprogress.cxx:38:5: error: Unreferenced externally invisible function definition [loplugin:unreffun] > SpinningProgressControlModel(SpinningProgressControlModel &&) = default; > ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Change-Id: Id78cd2d801e9760dde9e0a594e2b62ec20840204 Reviewed-on: https://gerrit.libreoffice.org/58180 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/unreffun.cxx21
1 files changed, 21 insertions, 0 deletions
diff --git a/compilerplugins/clang/unreffun.cxx b/compilerplugins/clang/unreffun.cxx
index bfd48b328300..629e369dadc7 100644
--- a/compilerplugins/clang/unreffun.cxx
+++ b/compilerplugins/clang/unreffun.cxx
@@ -51,6 +51,19 @@ Decl const * getPreviousNonFriendDecl(Decl const * decl) {
}
}
+bool isSpecialMemberFunction(FunctionDecl const * decl) {
+ if (auto const ctor = dyn_cast<CXXConstructorDecl>(decl)) {
+ return ctor->isDefaultConstructor() || ctor->isCopyOrMoveConstructor();
+ }
+ if (isa<CXXDestructorDecl>(decl)) {
+ return true;
+ }
+ if (auto const meth = dyn_cast<CXXMethodDecl>(decl)) {
+ return meth->isCopyAssignmentOperator() || meth->isMoveAssignmentOperator();
+ }
+ return false;
+}
+
class UnrefFun: public RecursiveASTVisitor<UnrefFun>, public loplugin::Plugin {
public:
explicit UnrefFun(loplugin::InstantiationData const & data): Plugin(data) {}
@@ -141,6 +154,14 @@ bool UnrefFun::VisitFunctionDecl(FunctionDecl const * decl) {
{
return true;
}
+ if (canon->isExplicitlyDefaulted() && isSpecialMemberFunction(canon)) {
+ // If a special member function is explicitly defaulted on the first declaration, assume
+ // that its presence is always due to some interface design consideration, not to explicitly
+ // request a definition that might be worth to flag as unused (and C++20 may extend
+ // defaultability beyond special member functions to comparison operators, therefore
+ // explicitly check here for special member functions only):
+ return true;
+ }
LinkageInfo info(canon->getLinkageAndVisibility());
if (info.getLinkage() == ExternalLinkage
&& hasCLanguageLinkageType(canon) && canon->isDefined()