Index: clang-tidy/cppcoreguidelines/CMakeLists.txt =================================================================== --- clang-tidy/cppcoreguidelines/CMakeLists.txt +++ clang-tidy/cppcoreguidelines/CMakeLists.txt @@ -28,6 +28,7 @@ clangLex clangTidy clangTidyMiscModule + clangTidyModernizeModule clangTidyReadabilityModule clangTidyUtils clangTooling Index: clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp =================================================================== --- clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp +++ clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp @@ -12,6 +12,7 @@ #include "../ClangTidyModuleRegistry.h" #include "../misc/NonPrivateMemberVariablesInClassesCheck.h" #include "../misc/UnconventionalAssignOperatorCheck.h" +#include "../modernize/AvoidCArraysCheck.h" #include "../readability/MagicNumbersCheck.h" #include "AvoidGotoCheck.h" #include "InterfacesGlobalInitCheck.h" @@ -80,6 +81,8 @@ CheckFactories.registerCheck("cppcoreguidelines-slicing"); CheckFactories.registerCheck( "cppcoreguidelines-c-copy-assignment-signature"); + CheckFactories.registerCheck( + "cppcoreguidelines-avoid-c-arrays"); } ClangTidyOptions getModuleOptions() override { Index: clang-tidy/hicpp/HICPPTidyModule.cpp =================================================================== --- clang-tidy/hicpp/HICPPTidyModule.cpp +++ clang-tidy/hicpp/HICPPTidyModule.cpp @@ -22,6 +22,7 @@ #include "../misc/NewDeleteOverloadsCheck.h" #include "../misc/StaticAssertCheck.h" #include "../bugprone/UndelegatedConstructorCheck.h" +#include "../modernize/AvoidCArraysCheck.h" #include "../modernize/DeprecatedHeadersCheck.h" #include "../modernize/UseAutoCheck.h" #include "../modernize/UseEmplaceCheck.h" @@ -50,6 +51,8 @@ void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { CheckFactories.registerCheck( "hicpp-avoid-goto"); + CheckFactories.registerCheck( + "hicpp-avoid-c-arrays"); CheckFactories.registerCheck( "hicpp-braces-around-statements"); CheckFactories.registerCheck( Index: clang-tidy/modernize/AvoidCArraysCheck.h =================================================================== --- /dev/null +++ clang-tidy/modernize/AvoidCArraysCheck.h @@ -0,0 +1,35 @@ +//===--- AvoidCArraysCheck.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_MODERNIZE_AVOIDCARRAYSCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_AVOIDCARRAYSCHECK_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { +namespace modernize { + +/// Find C-style array types and recommend to use std::array<>. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/modernize-avoid-c-arrays.html +class AvoidCArraysCheck : public ClangTidyCheck { +public: + AvoidCArraysCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; +}; + +} // namespace modernize +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_AVOIDCARRAYSCHECK_H Index: clang-tidy/modernize/AvoidCArraysCheck.cpp =================================================================== --- /dev/null +++ clang-tidy/modernize/AvoidCArraysCheck.cpp @@ -0,0 +1,57 @@ +//===--- 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, + InnerMatcher) { + const clang::Type *TypeNode = Node.getTypePtr(); + return (TypeNode != nullptr && + InnerMatcher.matches(*TypeNode, Finder, Builder)); +} + +} // 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())), + hasAncestor(functionDecl(isExternC()))))) + .bind("typeloc"), + this); +} + +void AvoidCArraysCheck::check(const MatchFinder::MatchResult &Result) { + const auto *ArrayType = Result.Nodes.getNodeAs("typeloc"); + diag(ArrayType->getBeginLoc(), + "do not declare C-style arrays, use std::array<> instead"); +} + +} // namespace modernize +} // namespace tidy +} // namespace clang Index: clang-tidy/modernize/CMakeLists.txt =================================================================== --- clang-tidy/modernize/CMakeLists.txt +++ clang-tidy/modernize/CMakeLists.txt @@ -2,6 +2,7 @@ add_clang_library(clangTidyModernizeModule AvoidBindCheck.cpp + AvoidCArraysCheck.cpp ConcatNestedNamespacesCheck.cpp DeprecatedHeadersCheck.cpp DeprecatedIosBaseAliasesCheck.cpp Index: clang-tidy/modernize/ModernizeTidyModule.cpp =================================================================== --- clang-tidy/modernize/ModernizeTidyModule.cpp +++ clang-tidy/modernize/ModernizeTidyModule.cpp @@ -11,6 +11,7 @@ #include "../ClangTidyModule.h" #include "../ClangTidyModuleRegistry.h" #include "AvoidBindCheck.h" +#include "AvoidCArraysCheck.h" #include "ConcatNestedNamespacesCheck.h" #include "DeprecatedHeadersCheck.h" #include "DeprecatedIosBaseAliasesCheck.h" @@ -48,6 +49,7 @@ public: void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { CheckFactories.registerCheck("modernize-avoid-bind"); + CheckFactories.registerCheck("modernize-avoid-c-arrays"); CheckFactories.registerCheck( "modernize-concat-nested-namespaces"); CheckFactories.registerCheck( Index: docs/ReleaseNotes.rst =================================================================== --- docs/ReleaseNotes.rst +++ docs/ReleaseNotes.rst @@ -123,6 +123,11 @@ but also have logic (non-static member functions), and diagnoses all member variables that have any other scope other than ``private``. +- New :doc:`modernize-avoid-c-arrays + ` check. + + Finds C-style array types and recommend to use ``std::array<>``. + - New :doc:`modernize-concat-nested-namespaces ` check. @@ -154,12 +159,22 @@ ` added. +- New alias :doc:`cppcoreguidelines-avoid-c-arrays + ` + to :doc:`modernize-avoid-c-arrays + ` added. + - New alias :doc:`cppcoreguidelines-non-private-member-variables-in-classes ` to :doc:`misc-non-private-member-variables-in-classes ` added. +- New alias :doc:`hicpp-avoid-c-arrays + ` + to :doc:`modernize-avoid-c-arrays + ` added. + - New alias :doc:`hicpp-uppercase-literal-suffix ` to :doc:`readability-uppercase-literal-suffix Index: docs/clang-tidy/checks/cppcoreguidelines-avoid-c-arrays.rst =================================================================== --- /dev/null +++ docs/clang-tidy/checks/cppcoreguidelines-avoid-c-arrays.rst @@ -0,0 +1,10 @@ +.. title:: clang-tidy - cppcoreguidelines-avoid-c-arrays +.. meta:: + :http-equiv=refresh: 5;URL=modernize-avoid-c-arrays.html + +cppcoreguidelines-avoid-c-arrays +================================ + +The cppcoreguidelines-avoid-c-arrays check is an alias, please see +`modernize-avoid-c-arrays `_ +for more information. Index: docs/clang-tidy/checks/hicpp-avoid-c-arrays.rst =================================================================== --- /dev/null +++ docs/clang-tidy/checks/hicpp-avoid-c-arrays.rst @@ -0,0 +1,10 @@ +.. title:: clang-tidy - hicpp-avoid-c-arrays +.. meta:: + :http-equiv=refresh: 5;URL=modernize-avoid-c-arrays.html + +hicpp-avoid-c-arrays +==================== + +The hicpp-avoid-c-arrays check is an alias, please see +`modernize-avoid-c-arrays `_ +for more information. Index: docs/clang-tidy/checks/list.rst =================================================================== --- docs/clang-tidy/checks/list.rst +++ docs/clang-tidy/checks/list.rst @@ -87,6 +87,7 @@ cert-msc51-cpp cert-oop11-cpp (redirects to performance-move-constructor-init) cppcoreguidelines-avoid-goto + cppcoreguidelines-avoid-c-arrays (redirects to modernize-avoid-c-arrays) cppcoreguidelines-avoid-magic-numbers (redirects to readability-magic-numbers) cppcoreguidelines-c-copy-assignment-signature (redirects to misc-unconventional-assign-operator) cppcoreguidelines-interfaces-global-init @@ -131,6 +132,7 @@ google-runtime-int google-runtime-operator google-runtime-references + hicpp-avoid-c-arrays (redirects to modernize-avoid-c-arrays) hicpp-avoid-goto hicpp-braces-around-statements (redirects to readability-braces-around-statements) hicpp-deprecated-headers (redirects to modernize-deprecated-headers) @@ -178,6 +180,7 @@ misc-unused-parameters misc-unused-using-decls modernize-avoid-bind + modernize-avoid-c-arrays modernize-concat-nested-namespaces modernize-deprecated-headers modernize-deprecated-ios-base-aliases Index: docs/clang-tidy/checks/modernize-avoid-c-arrays.rst =================================================================== --- /dev/null +++ docs/clang-tidy/checks/modernize-avoid-c-arrays.rst @@ -0,0 +1,57 @@ +.. title:: clang-tidy - modernize-avoid-c-arrays + +modernize-avoid-c-arrays +======================== + +`cppcoreguidelines-avoid-c-arrays` redirects here as an alias for this check. + +`hicpp-avoid-c-arrays` redirects here as an alias for this check. + +Finds C-style array types and recommend to use ``std::array<>``. +All types of C arrays are diagnosed. + +However, no fix-its are provided. Such transform would need to be able to +observe *all* the uses of said declaration in order to decide whether it is +safe to transform or not, and that is impossible in case of headers. + +.. code:: c++ + + int a[] = {1, 2}; // warning: do not declare C-style arrays, use std::array<> instead + + int b[1]; // warning: do not declare C-style arrays, use std::array<> instead + + void foo() { + int c[b[0]]; // warning: do not declare C-style arrays, use std::array<> instead + } + + template + class array { + T d[Size]; // warning: do not declare C-style arrays, use std::array<> instead + + int e[1]; // warning: do not declare C-style arrays, use std::array<> instead + }; + + array d; // warning: do not declare C-style arrays, use std::array<> instead + + using k = int[4]; // warning: do not declare C-style arrays, use std::array<> instead + + +However, the ``extern "C"`` code is ignored, since it is common to share +such headers between C code, and C++ code. + +.. code:: c++ + + // Some header + extern "C" { + + int f[] = {1, 2}; // not diagnosed + + int j[1]; // not diagnosed + + inline void bar() { + { + int j[j[0]]; // not diagnosed + } + } + + } Index: test/clang-tidy/modernize-avoid-c-arrays.cpp =================================================================== --- /dev/null +++ test/clang-tidy/modernize-avoid-c-arrays.cpp @@ -0,0 +1,59 @@ +// RUN: %check_clang_tidy %s modernize-avoid-c-arrays %t + +int a[] = {1, 2}; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: do not declare C-style arrays, use std::array<> instead + +int b[1]; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: do not declare C-style arrays, use std::array<> instead + +void foo() { + int c[b[0]]; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead +} + +template +class array { + T d[Size]; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead + + int e[1]; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead +}; + +array d; +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not declare C-style arrays, use std::array<> instead + +using k = int[4]; +// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: do not declare C-style arrays, use std::array<> instead + +array dk; + +template +class unique_ptr { + T *d; + + int e[1]; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead +}; + +unique_ptr d2; +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not declare C-style arrays, use std::array<> instead + +using k2 = int[]; +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not declare C-style arrays, use std::array<> instead + +unique_ptr dk2; + +// Some header +extern "C" { + +int f[] = {1, 2}; + +int j[1]; + +inline void bar() { + { + int j[j[0]]; + } +} +}