summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clang-tidy/cppcoreguidelines
diff options
context:
space:
mode:
authorAlexander Kornienko <alexfh@google.com>2016-04-08 09:51:06 +0000
committerAlexander Kornienko <alexfh@google.com>2016-04-08 09:51:06 +0000
commit477e5d8d3160367e03edc1343900e87267b22fac (patch)
treef5e5a05f82971dca8c0310439c0ffe5470c706fa /clang-tools-extra/clang-tidy/cppcoreguidelines
parentad659c3400d03fe1797c5b00eb825d4b6b745686 (diff)
downloadbcm5719-llvm-477e5d8d3160367e03edc1343900e87267b22fac.tar.gz
bcm5719-llvm-477e5d8d3160367e03edc1343900e87267b22fac.zip
[clang-tidy] cppcoreguidelines-interfaces-global-init
Summary: This check flags initializers of globals that access extern objects, and therefore can lead to order-of-initialization problems (this recommandation is part of CPP core guidelines). Note that this only checks half of the guideline for now (it does not enforce using constexpr functions). Reviewers: aaron.ballman, alexfh Subscribers: aaron.ballman, etienneb, Eugene.Zelenko, cfe-commits Patch by Clement Courbet! Differential Revision: http://reviews.llvm.org/D18649 llvm-svn: 265774
Diffstat (limited to 'clang-tools-extra/clang-tidy/cppcoreguidelines')
-rw-r--r--clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt1
-rw-r--r--clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp3
-rw-r--r--clang-tools-extra/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.cpp59
-rw-r--r--clang-tools-extra/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.h35
4 files changed, 98 insertions, 0 deletions
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt b/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
index ea97ebe2dee..65c40ed5861 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
@@ -2,6 +2,7 @@ set(LLVM_LINK_COMPONENTS support)
add_clang_library(clangTidyCppCoreGuidelinesModule
CppCoreGuidelinesTidyModule.cpp
+ InterfacesGlobalInitCheck.cpp
ProBoundsArrayToPointerDecayCheck.cpp
ProBoundsConstantArrayIndexCheck.cpp
ProBoundsPointerArithmeticCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
index 70fa0f493a5..27fda49a4e5 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
@@ -11,6 +11,7 @@
#include "../ClangTidyModule.h"
#include "../ClangTidyModuleRegistry.h"
#include "../misc/AssignOperatorSignatureCheck.h"
+#include "InterfacesGlobalInitCheck.h"
#include "ProBoundsArrayToPointerDecayCheck.h"
#include "ProBoundsConstantArrayIndexCheck.h"
#include "ProBoundsPointerArithmeticCheck.h"
@@ -30,6 +31,8 @@ namespace cppcoreguidelines {
class CppCoreGuidelinesModule : public ClangTidyModule {
public:
void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
+ CheckFactories.registerCheck<InterfacesGlobalInitCheck>(
+ "cppcoreguidelines-interfaces-global-init");
CheckFactories.registerCheck<ProBoundsArrayToPointerDecayCheck>(
"cppcoreguidelines-pro-bounds-array-to-pointer-decay");
CheckFactories.registerCheck<ProBoundsConstantArrayIndexCheck>(
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.cpp
new file mode 100644
index 00000000000..f601b2443d7
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.cpp
@@ -0,0 +1,59 @@
+//===--- InterfacesGlobalInitCheck.cpp - clang-tidy------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "InterfacesGlobalInitCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace cppcoreguidelines {
+
+void InterfacesGlobalInitCheck::registerMatchers(MatchFinder *Finder) {
+ const auto IsGlobal =
+ allOf(hasGlobalStorage(),
+ hasDeclContext(anyOf(translationUnitDecl(), // Global scope.
+ namespaceDecl(), // Namespace scope.
+ recordDecl())), // Class scope.
+ unless(isConstexpr()));
+
+ const auto ReferencesUndefinedGlobalVar = declRefExpr(hasDeclaration(
+ varDecl(IsGlobal, unless(isDefinition())).bind("referencee")));
+
+ Finder->addMatcher(
+ varDecl(IsGlobal, isDefinition(),
+ hasInitializer(expr(hasDescendant(ReferencesUndefinedGlobalVar))))
+ .bind("var"),
+ this);
+}
+
+void InterfacesGlobalInitCheck::check(const MatchFinder::MatchResult &Result) {
+ const auto *const Var = Result.Nodes.getNodeAs<VarDecl>("var");
+ // For now assume that people who write macros know what they're doing.
+ if (Var->getLocation().isMacroID())
+ return;
+ const auto *const Referencee = Result.Nodes.getNodeAs<VarDecl>("referencee");
+ // If the variable has been defined, we're good.
+ const auto *const ReferenceeDef = Referencee->getDefinition();
+ if (ReferenceeDef != nullptr &&
+ Result.SourceManager->isBeforeInTranslationUnit(
+ ReferenceeDef->getLocation(), Var->getLocation())) {
+ return;
+ }
+ diag(Var->getLocation(),
+ "initializing non-local variable with non-const expression depending on "
+ "uninitialized non-local variable %0")
+ << Referencee;
+}
+
+} // namespace cppcoreguidelines
+} // namespace tidy
+} // namespace clang
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.h
new file mode 100644
index 00000000000..13712d11e11
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.h
@@ -0,0 +1,35 @@
+//===--- InterfacesGlobalInitCheck.h - clang-tidy----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_INTERFACES_GLOBAL_INIT_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_INTERFACES_GLOBAL_INIT_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace cppcoreguidelines {
+
+/// Flags possible initialization order issues of static variables.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines-interfaces-global-init.html
+class InterfacesGlobalInitCheck : public ClangTidyCheck {
+public:
+ InterfacesGlobalInitCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace cppcoreguidelines
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_INTERFACES_GLOBAL_INIT_H
OpenPOWER on IntegriCloud