summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clang-tidy/cppcoreguidelines
diff options
context:
space:
mode:
authorMatthias Gehre <M.Gehre@gmx.de>2015-10-12 20:46:53 +0000
committerMatthias Gehre <M.Gehre@gmx.de>2015-10-12 20:46:53 +0000
commita704d4bb27354a7ee54b8672808ebae9c13ba806 (patch)
treeef26f8682ed42ef1f8dca6930dda6725796bc22f /clang-tools-extra/clang-tidy/cppcoreguidelines
parent8ebfb60efa77062d12a3ecc804b8b52737b7ac1c (diff)
downloadbcm5719-llvm-a704d4bb27354a7ee54b8672808ebae9c13ba806.tar.gz
bcm5719-llvm-a704d4bb27354a7ee54b8672808ebae9c13ba806.zip
[clang-tidy] add check cppcoreguidelines-pro-type-static-cast-downcast
Summary: This check flags all usages of static_cast, where a base class is casted to a derived class. In those cases, a fixit is provided to convert the cast to a dynamic_cast. Use of these casts can violate type safety and cause the program to access a variable that is actually of type X to be accessed as if it were of an unrelated type Z. This rule is part of the "Type safety" profile of the C++ Core Guidelines, see https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-type2-dont-use-static_cast-downcasts-use-dynamic_cast-instead Depends on D13313 Reviewers: alexfh, sbenza, bkramer, aaron.ballman Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D13368 llvm-svn: 250098
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/ProTypeStaticCastDowncastCheck.cpp52
-rw-r--r--clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.h33
4 files changed, 89 insertions, 0 deletions
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt b/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
index 5a83b3fef08..d35b9a56f94 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
@@ -4,6 +4,7 @@ add_clang_library(clangTidyCppCoreGuidelinesModule
CppCoreGuidelinesTidyModule.cpp
ProTypeConstCastCheck.cpp
ProTypeReinterpretCastCheck.cpp
+ ProTypeStaticCastDowncastCheck.cpp
LINK_LIBS
clangAST
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
index 130eabe29f1..358bd6ec8fd 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
@@ -12,6 +12,7 @@
#include "../ClangTidyModuleRegistry.h"
#include "ProTypeConstCastCheck.h"
#include "ProTypeReinterpretCastCheck.h"
+#include "ProTypeStaticCastDowncastCheck.h"
namespace clang {
namespace tidy {
@@ -25,6 +26,8 @@ public:
"cppcoreguidelines-pro-type-const-cast");
CheckFactories.registerCheck<ProTypeReinterpretCastCheck>(
"cppcoreguidelines-pro-type-reinterpret-cast");
+ CheckFactories.registerCheck<ProTypeStaticCastDowncastCheck>(
+ "cppcoreguidelines-pro-type-static-cast-downcast");
}
};
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.cpp
new file mode 100644
index 00000000000..0033e4ed9d3
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.cpp
@@ -0,0 +1,52 @@
+//===--- ProTypeStaticCastDowncastCheck.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 "ProTypeStaticCastDowncastCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+
+void ProTypeStaticCastDowncastCheck::registerMatchers(MatchFinder *Finder) {
+ if (!getLangOpts().CPlusPlus)
+ return;
+
+ Finder->addMatcher(
+ cxxStaticCastExpr(unless(isInTemplateInstantiation())).bind("cast"),
+ this);
+}
+
+void ProTypeStaticCastDowncastCheck::check(const MatchFinder::MatchResult &Result) {
+ const auto *MatchedCast = Result.Nodes.getNodeAs<CXXStaticCastExpr>("cast");
+ if (MatchedCast->getCastKind() != CK_BaseToDerived)
+ return;
+
+ QualType SourceType = MatchedCast->getSubExpr()->getType();
+ const auto *SourceDecl = SourceType->getPointeeCXXRecordDecl();
+ if (!SourceDecl) // The cast is from object to reference
+ SourceDecl = SourceType->getAsCXXRecordDecl();
+ if (!SourceDecl)
+ return;
+
+ if (SourceDecl->isPolymorphic())
+ diag(MatchedCast->getOperatorLoc(),
+ "do not use static_cast to downcast from a base to a derived class; "
+ "use dynamic_cast instead")
+ << FixItHint::CreateReplacement(MatchedCast->getOperatorLoc(),
+ "dynamic_cast");
+ else
+ diag(MatchedCast->getOperatorLoc(),
+ "do not use static_cast to downcast from a base to a derived class");
+}
+
+} // namespace tidy
+} // namespace clang
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.h
new file mode 100644
index 00000000000..02de48ae957
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.h
@@ -0,0 +1,33 @@
+//===--- ProTypeStaticCastDowncastCheck.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_PRO_TYPE_STATIC_CAST_DOWNCAST_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_STATIC_CAST_DOWNCAST_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+
+/// Checks for usages of static_cast, where a base class is downcasted to a derived class.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines-pro-type-static-cast-downcast.html
+class ProTypeStaticCastDowncastCheck : public ClangTidyCheck {
+public:
+ ProTypeStaticCastDowncastCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_STATIC_CAST_DOWNCAST_H
OpenPOWER on IntegriCloud