diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2016-01-11 13:14:38 +0100 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2016-01-11 13:17:10 +0100 |
commit | 67ec72a381d939a56fdd5e472a413bab92f4ad80 (patch) | |
tree | 52a400689146d02b2ebaca15bc7cc56737846488 /compilerplugins | |
parent | 608dee4f5fbf10ba4c0f8c971f4f93b23be006fa (diff) |
New loplugin:privatebase
...to flag places that implicitly derive a class privately instead of publicly,
where accidental private derivation can cause unexpected failure of
dynamic_cast, cf. 63b67ab5cab8cf7576a68cabe5fb1a42c6ad800c "Use public
derivation, and remove then-unnecessary downcasts."
Change-Id: I4bcd5c79c7e27380c820e2dd072fa4c4e8980078
Diffstat (limited to 'compilerplugins')
-rw-r--r-- | compilerplugins/clang/privatebase.cxx | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/compilerplugins/clang/privatebase.cxx b/compilerplugins/clang/privatebase.cxx new file mode 100644 index 000000000000..8084ee34104b --- /dev/null +++ b/compilerplugins/clang/privatebase.cxx @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "plugin.hxx" + +namespace { + +class PrivateBase: + public RecursiveASTVisitor<PrivateBase>, public loplugin::Plugin +{ +public: + explicit PrivateBase(InstantiationData const & data): Plugin(data) {} + + void run() override; + + bool VisitCXXRecordDecl(CXXRecordDecl const * decl); +}; + +void PrivateBase::run() { + if (compiler.getLangOpts().CPlusPlus) { + TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); + } +} + +bool PrivateBase::VisitCXXRecordDecl(CXXRecordDecl const * decl) { + if (ignoreLocation(decl) || !decl->isThisDeclarationADefinition() + || decl->getTagKind() != TTK_Class) + { + return true; + } + for (auto const & i: decl->bases()) { + if (i.getAccessSpecifierAsWritten() == AS_none) { + report( + DiagnosticsEngine::Warning, + "base class is private by default; explicitly give an access" + " specifier", + i.getLocStart()) + << i.getSourceRange(); + } + } + return true; +} + +loplugin::Plugin::Registration<PrivateBase> X("privatebase"); + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |