aboutsummaryrefslogtreecommitdiff
path: root/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp
diff options
context:
space:
mode:
authorRoman Lebedev <lebedev.ri@gmail.com>2018-11-14 09:01:08 +0000
committerRoman Lebedev <lebedev.ri@gmail.com>2018-11-14 09:01:08 +0000
commit2634bd599567842385e11d1fd70f5486c166f935 (patch)
treec13cfe7924c2bba879b708b6e08d87342629610b /clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp
parent789cc8170d15c208308c28a24d9f8978ead18a9a (diff)
downloadllvm-2634bd599567842385e11d1fd70f5486c166f935.zip
llvm-2634bd599567842385e11d1fd70f5486c166f935.tar.gz
llvm-2634bd599567842385e11d1fd70f5486c166f935.tar.bz2
[clang-tidy] Avoid C arrays check
Summary: [[ https://bugs.llvm.org/show_bug.cgi?id=39224 | PR39224 ]] As discussed, we can't always do the transform automatically due to that array-to-pointer decay of C array. In order to detect whether we can do said transform, we'd need to be able to see all usages of said array, which is, i would say, rather impossible if e.g. it is in the header. Thus right now no fixit exists. Exceptions: `extern "C"` code. References: * [[ https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#es27-use-stdarray-or-stack_array-for-arrays-on-the-stack | CPPCG ES.27: Use std::array or stack_array for arrays on the stack ]] * [[ https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#slcon1-prefer-using-stl-array-or-vector-instead-of-a-c-array | CPPCG SL.con.1: Prefer using STL array or vector instead of a C array ]] * HICPP `4.1.1 Ensure that a function argument does not undergo an array-to-pointer conversion` * MISRA `5-2-12 An identifier with array type passed as a function argument shall not decay to a pointer` Reviewers: aaron.ballman, JonasToth, alexfh, hokein, xazax.hun Reviewed By: JonasToth Subscribers: Eugene.Zelenko, mgorny, rnkovacs, cfe-commits Tags: #clang-tools-extra Differential Revision: https://reviews.llvm.org/D53771 llvm-svn: 346835
Diffstat (limited to 'clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp')
-rw-r--r--clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp69
1 files changed, 69 insertions, 0 deletions
diff --git a/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp b/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp
new file mode 100644
index 0000000..dd19483
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp
@@ -0,0 +1,69 @@
+//===--- AvoidCArraysCheck.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 "AvoidCArraysCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace {
+
+AST_MATCHER(clang::TypeLoc, hasValidBeginLoc) {
+ return Node.getBeginLoc().isValid();
+}
+
+AST_MATCHER_P(clang::TypeLoc, hasType,
+ clang::ast_matchers::internal::Matcher<clang::Type>,
+ InnerMatcher) {
+ const clang::Type *TypeNode = Node.getTypePtr();
+ return TypeNode != nullptr &&
+ InnerMatcher.matches(*TypeNode, Finder, Builder);
+}
+
+AST_MATCHER(clang::RecordDecl, isExternCContext) {
+ return Node.isExternCContext();
+}
+
+} // namespace
+
+namespace clang {
+namespace tidy {
+namespace modernize {
+
+void AvoidCArraysCheck::registerMatchers(MatchFinder *Finder) {
+ // std::array<> is avaliable since C++11.
+ if (!getLangOpts().CPlusPlus11)
+ return;
+
+ Finder->addMatcher(
+ typeLoc(hasValidBeginLoc(), hasType(arrayType()),
+ unless(anyOf(hasParent(varDecl(isExternC())),
+ hasParent(fieldDecl(
+ hasParent(recordDecl(isExternCContext())))),
+ hasAncestor(functionDecl(isExternC())))))
+ .bind("typeloc"),
+ this);
+}
+
+void AvoidCArraysCheck::check(const MatchFinder::MatchResult &Result) {
+ const auto *ArrayType = Result.Nodes.getNodeAs<TypeLoc>("typeloc");
+
+ static constexpr llvm::StringLiteral UseArray = llvm::StringLiteral(
+ "do not declare C-style arrays, use std::array<> instead");
+ static constexpr llvm::StringLiteral UseVector = llvm::StringLiteral(
+ "do not declare C VLA arrays, use std::vector<> instead");
+
+ diag(ArrayType->getBeginLoc(),
+ ArrayType->getTypePtr()->isVariableArrayType() ? UseVector : UseArray);
+}
+
+} // namespace modernize
+} // namespace tidy
+} // namespace clang