diff options
author | Roman Lebedev <lebedev.ri@gmail.com> | 2018-11-14 09:01:08 +0000 |
---|---|---|
committer | Roman Lebedev <lebedev.ri@gmail.com> | 2018-11-14 09:01:08 +0000 |
commit | 2634bd599567842385e11d1fd70f5486c166f935 (patch) | |
tree | c13cfe7924c2bba879b708b6e08d87342629610b /clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp | |
parent | 789cc8170d15c208308c28a24d9f8978ead18a9a (diff) | |
download | llvm-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.cpp | 69 |
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 |