diff --git a/clang-tools-extra/clang-tidy/CMakeLists.txt b/clang-tools-extra/clang-tidy/CMakeLists.txt index 02573534ccae..923976197ebe 100644 --- a/clang-tools-extra/clang-tidy/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/CMakeLists.txt @@ -1,119 +1,121 @@ set(LLVM_LINK_COMPONENTS FrontendOpenMP Support ) add_clang_library(clangTidy ClangTidy.cpp ClangTidyCheck.cpp ClangTidyModule.cpp ClangTidyDiagnosticConsumer.cpp ClangTidyOptions.cpp ClangTidyProfiling.cpp ExpandModularHeadersPPCallbacks.cpp GlobList.cpp DEPENDS ClangSACheckers omp_gen ) clang_target_link_libraries(clangTidy PRIVATE clangAnalysis clangAST clangASTMatchers clangBasic clangFormat clangFrontend clangLex clangRewrite clangSema clangSerialization clangTooling clangToolingCore ) if(CLANG_ENABLE_STATIC_ANALYZER) clang_target_link_libraries(clangTidy PRIVATE clangStaticAnalyzerCore clangStaticAnalyzerFrontend ) endif() # Checks. # If you add a check, also add it to ClangTidyForceLinker.h in this directory. add_subdirectory(android) add_subdirectory(abseil) +add_subdirectory(altera) add_subdirectory(boost) add_subdirectory(bugprone) add_subdirectory(cert) add_subdirectory(cppcoreguidelines) add_subdirectory(darwin) add_subdirectory(fuchsia) add_subdirectory(google) add_subdirectory(hicpp) add_subdirectory(linuxkernel) add_subdirectory(llvm) add_subdirectory(llvmlibc) add_subdirectory(misc) add_subdirectory(modernize) if(CLANG_ENABLE_STATIC_ANALYZER) add_subdirectory(mpi) endif() add_subdirectory(objc) add_subdirectory(openmp) add_subdirectory(performance) add_subdirectory(portability) add_subdirectory(readability) add_subdirectory(zircon) set(ALL_CLANG_TIDY_CHECKS clangTidyAndroidModule clangTidyAbseilModule + clangTidyAlteraModule clangTidyBoostModule clangTidyBugproneModule clangTidyCERTModule clangTidyCppCoreGuidelinesModule clangTidyDarwinModule clangTidyFuchsiaModule clangTidyGoogleModule clangTidyHICPPModule clangTidyLinuxKernelModule clangTidyLLVMModule clangTidyLLVMLibcModule clangTidyMiscModule clangTidyModernizeModule clangTidyObjCModule clangTidyOpenMPModule clangTidyPerformanceModule clangTidyPortabilityModule clangTidyReadabilityModule clangTidyZirconModule ) if(CLANG_ENABLE_STATIC_ANALYZER) list(APPEND ALL_CLANG_TIDY_CHECKS clangTidyMPIModule) endif() set(ALL_CLANG_TIDY_CHECKS ${ALL_CLANG_TIDY_CHECKS} PARENT_SCOPE) # Other subtargets. These may reference ALL_CLANG_TIDY_CHECKS # and must be below its definition. add_subdirectory(plugin) add_subdirectory(tool) add_subdirectory(utils) if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) install(DIRECTORY . DESTINATION include/clang-tidy COMPONENT clang-tidy-headers FILES_MATCHING PATTERN "*.h" ) add_custom_target(clang-tidy-headers) set_target_properties(clang-tidy-headers PROPERTIES FOLDER "Misc") if(NOT LLVM_ENABLE_IDE) add_llvm_install_targets(install-clang-tidy-headers DEPENDS clang-tidy-headers COMPONENT clang-tidy-headers) endif() endif() diff --git a/clang-tools-extra/clang-tidy/ClangTidyForceLinker.h b/clang-tools-extra/clang-tidy/ClangTidyForceLinker.h index 1d6bd2a4fd62..63e681f878db 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyForceLinker.h +++ b/clang-tools-extra/clang-tidy/ClangTidyForceLinker.h @@ -1,134 +1,139 @@ //===- ClangTidyForceLinker.h - clang-tidy --------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYFORCELINKER_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYFORCELINKER_H #include "clang/Config/config.h" #include "llvm/Support/Compiler.h" namespace clang { namespace tidy { // This anchor is used to force the linker to link the AbseilModule. extern volatile int AbseilModuleAnchorSource; static int LLVM_ATTRIBUTE_UNUSED AbseilModuleAnchorDestination = AbseilModuleAnchorSource; +// This anchor is used to force the linker to link the AlteraModule. +extern volatile int AlteraModuleAnchorSource; +static int LLVM_ATTRIBUTE_UNUSED AlteraModuleAnchorDestination = + AlteraModuleAnchorSource; + // This anchor is used to force the linker to link the AndroidModule. extern volatile int AndroidModuleAnchorSource; static int LLVM_ATTRIBUTE_UNUSED AndroidModuleAnchorDestination = AndroidModuleAnchorSource; // This anchor is used to force the linker to link the BoostModule. extern volatile int BoostModuleAnchorSource; static int LLVM_ATTRIBUTE_UNUSED BoostModuleAnchorDestination = BoostModuleAnchorSource; // This anchor is used to force the linker to link the BugproneModule. extern volatile int BugproneModuleAnchorSource; static int LLVM_ATTRIBUTE_UNUSED BugproneModuleAnchorDestination = BugproneModuleAnchorSource; // This anchor is used to force the linker to link the CERTModule. extern volatile int CERTModuleAnchorSource; static int LLVM_ATTRIBUTE_UNUSED CERTModuleAnchorDestination = CERTModuleAnchorSource; // This anchor is used to force the linker to link the CppCoreGuidelinesModule. extern volatile int CppCoreGuidelinesModuleAnchorSource; static int LLVM_ATTRIBUTE_UNUSED CppCoreGuidelinesModuleAnchorDestination = CppCoreGuidelinesModuleAnchorSource; // This anchor is used to force the linker to link the DarwinModule. extern volatile int DarwinModuleAnchorSource; static int LLVM_ATTRIBUTE_UNUSED DarwinModuleAnchorDestination = DarwinModuleAnchorSource; // This anchor is used to force the linker to link the FuchsiaModule. extern volatile int FuchsiaModuleAnchorSource; static int LLVM_ATTRIBUTE_UNUSED FuchsiaModuleAnchorDestination = FuchsiaModuleAnchorSource; // This anchor is used to force the linker to link the GoogleModule. extern volatile int GoogleModuleAnchorSource; static int LLVM_ATTRIBUTE_UNUSED GoogleModuleAnchorDestination = GoogleModuleAnchorSource; // This anchor is used to force the linker to link the HICPPModule. extern volatile int HICPPModuleAnchorSource; static int LLVM_ATTRIBUTE_UNUSED HICPPModuleAnchorDestination = HICPPModuleAnchorSource; // This anchor is used to force the linker to link the LinuxKernelModule. extern volatile int LinuxKernelModuleAnchorSource; static int LLVM_ATTRIBUTE_UNUSED LinuxKernelModuleAnchorDestination = LinuxKernelModuleAnchorSource; // This anchor is used to force the linker to link the LLVMModule. extern volatile int LLVMModuleAnchorSource; static int LLVM_ATTRIBUTE_UNUSED LLVMModuleAnchorDestination = LLVMModuleAnchorSource; // This anchor is used to force the linker to link the LLVMLibcModule. extern volatile int LLVMLibcModuleAnchorSource; static int LLVM_ATTRIBUTE_UNUSED LLVMLibcModuleAnchorDestination = LLVMLibcModuleAnchorSource; // This anchor is used to force the linker to link the MiscModule. extern volatile int MiscModuleAnchorSource; static int LLVM_ATTRIBUTE_UNUSED MiscModuleAnchorDestination = MiscModuleAnchorSource; // This anchor is used to force the linker to link the ModernizeModule. extern volatile int ModernizeModuleAnchorSource; static int LLVM_ATTRIBUTE_UNUSED ModernizeModuleAnchorDestination = ModernizeModuleAnchorSource; #if CLANG_ENABLE_STATIC_ANALYZER && \ !defined(CLANG_TIDY_DISABLE_STATIC_ANALYZER_CHECKS) // This anchor is used to force the linker to link the MPIModule. extern volatile int MPIModuleAnchorSource; static int LLVM_ATTRIBUTE_UNUSED MPIModuleAnchorDestination = MPIModuleAnchorSource; #endif // This anchor is used to force the linker to link the ObjCModule. extern volatile int ObjCModuleAnchorSource; static int LLVM_ATTRIBUTE_UNUSED ObjCModuleAnchorDestination = ObjCModuleAnchorSource; // This anchor is used to force the linker to link the OpenMPModule. extern volatile int OpenMPModuleAnchorSource; static int LLVM_ATTRIBUTE_UNUSED OpenMPModuleAnchorDestination = OpenMPModuleAnchorSource; // This anchor is used to force the linker to link the PerformanceModule. extern volatile int PerformanceModuleAnchorSource; static int LLVM_ATTRIBUTE_UNUSED PerformanceModuleAnchorDestination = PerformanceModuleAnchorSource; // This anchor is used to force the linker to link the PortabilityModule. extern volatile int PortabilityModuleAnchorSource; static int LLVM_ATTRIBUTE_UNUSED PortabilityModuleAnchorDestination = PortabilityModuleAnchorSource; // This anchor is used to force the linker to link the ReadabilityModule. extern volatile int ReadabilityModuleAnchorSource; static int LLVM_ATTRIBUTE_UNUSED ReadabilityModuleAnchorDestination = ReadabilityModuleAnchorSource; // This anchor is used to force the linker to link the ZirconModule. extern volatile int ZirconModuleAnchorSource; static int LLVM_ATTRIBUTE_UNUSED ZirconModuleAnchorDestination = ZirconModuleAnchorSource; } // namespace tidy } // namespace clang #endif diff --git a/clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp b/clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp new file mode 100644 index 000000000000..d91f67ac1485 --- /dev/null +++ b/clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp @@ -0,0 +1,39 @@ +//===--- AlteraTidyModule.cpp - clang-tidy --------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "../ClangTidy.h" +#include "../ClangTidyModule.h" +#include "../ClangTidyModuleRegistry.h" +#include "StructPackAlignCheck.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace altera { + +class AlteraModule : public ClangTidyModule { +public: + void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { + CheckFactories.registerCheck( + "altera-struct-pack-align"); + } +}; + +} // namespace altera + +// Register the AlteraTidyModule using this statically initialized variable. +static ClangTidyModuleRegistry::Add + X("altera-module", "Adds Altera FPGA OpenCL lint checks."); + +// This anchor is used to force the linker to link in the generated object file +// and thus register the AlteraModule. +volatile int AlteraModuleAnchorSource = 0; + +} // namespace tidy +} // namespace clang diff --git a/clang-tools-extra/clang-tidy/altera/CMakeLists.txt b/clang-tools-extra/clang-tidy/altera/CMakeLists.txt new file mode 100644 index 000000000000..45131c1809a2 --- /dev/null +++ b/clang-tools-extra/clang-tidy/altera/CMakeLists.txt @@ -0,0 +1,15 @@ +set(LLVM_LINK_COMPONENTS support) + +add_clang_library(clangTidyAlteraModule + AlteraTidyModule.cpp + StructPackAlignCheck.cpp + + LINK_LIBS + clangAnalysis + clangAST + clangASTMatchers + clangBasic + clangLex + clangTidy + clangTidyUtils + ) diff --git a/clang-tools-extra/clang-tidy/altera/StructPackAlignCheck.cpp b/clang-tools-extra/clang-tidy/altera/StructPackAlignCheck.cpp new file mode 100644 index 000000000000..9f28a22a9d03 --- /dev/null +++ b/clang-tools-extra/clang-tidy/altera/StructPackAlignCheck.cpp @@ -0,0 +1,144 @@ +//===--- StructPackAlignCheck.cpp - clang-tidy ----------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "StructPackAlignCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/RecordLayout.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include +#include + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace altera { + +void StructPackAlignCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(recordDecl(isStruct(), isDefinition(), + unless(isExpansionInSystemHeader())) + .bind("struct"), + this); +} + +CharUnits +StructPackAlignCheck::computeRecommendedAlignment(CharUnits MinByteSize) { + CharUnits NewAlign = CharUnits::fromQuantity(1); + if (!MinByteSize.isPowerOfTwo()) { + int MSB = (int)MinByteSize.getQuantity(); + for (; MSB > 0; MSB /= 2) { + NewAlign = NewAlign.alignTo( + CharUnits::fromQuantity(((int)NewAlign.getQuantity()) * 2)); + // Abort if the computed alignment meets the maximum configured alignment. + if (NewAlign.getQuantity() >= MaxConfiguredAlignment) + break; + } + } else { + NewAlign = MinByteSize; + } + return NewAlign; +} + +void StructPackAlignCheck::check(const MatchFinder::MatchResult &Result) { + const auto *Struct = Result.Nodes.getNodeAs("struct"); + + // Do not trigger on templated struct declarations because the packing and + // alignment requirements are unknown. + if (Struct->isTemplated()) + return; + + // Get sizing info for the struct. + llvm::SmallVector, 10> FieldSizes; + unsigned int TotalBitSize = 0; + for (const FieldDecl *StructField : Struct->fields()) { + // For each StructField, record how big it is (in bits). + // Would be good to use a pair of to advise a better + // packing order. + unsigned int StructFieldWidth = + (unsigned int)Result.Context + ->getTypeInfo(StructField->getType().getTypePtr()) + .Width; + FieldSizes.emplace_back(StructFieldWidth, StructField->getFieldIndex()); + // FIXME: Recommend a reorganization of the struct (sort by StructField + // size, largest to smallest). + TotalBitSize += StructFieldWidth; + } + + uint64_t CharSize = Result.Context->getCharWidth(); + CharUnits CurrSize = Result.Context->getASTRecordLayout(Struct).getSize(); + CharUnits MinByteSize = + CharUnits::fromQuantity(ceil((float)TotalBitSize / CharSize)); + CharUnits MaxAlign = CharUnits::fromQuantity( + ceil((float)Struct->getMaxAlignment() / CharSize)); + CharUnits CurrAlign = + Result.Context->getASTRecordLayout(Struct).getAlignment(); + CharUnits NewAlign = computeRecommendedAlignment(MinByteSize); + + bool IsPacked = Struct->hasAttr(); + bool NeedsPacking = (MinByteSize < CurrSize) && (MaxAlign != NewAlign) && + (CurrSize != NewAlign); + bool NeedsAlignment = CurrAlign.getQuantity() != NewAlign.getQuantity(); + + if (!NeedsAlignment && !NeedsPacking) + return; + + // If it's using much more space than it needs, suggest packing. + // (Do not suggest packing if it is currently explicitly aligned to what the + // minimum byte size would suggest as the new alignment.) + if (NeedsPacking && !IsPacked) { + diag(Struct->getLocation(), + "accessing fields in struct %0 is inefficient due to padding; only " + "needs %1 bytes but is using %2 bytes") + << Struct << (int)MinByteSize.getQuantity() + << (int)CurrSize.getQuantity() + << FixItHint::CreateInsertion(Struct->getEndLoc().getLocWithOffset(1), + " __attribute__((packed))"); + diag(Struct->getLocation(), + "use \"__attribute__((packed))\" to reduce the amount of padding " + "applied to struct %0", + DiagnosticIDs::Note) + << Struct; + } + + FixItHint FixIt; + AlignedAttr *Attribute = Struct->getAttr(); + std::string NewAlignQuantity = std::to_string((int)NewAlign.getQuantity()); + if (Attribute) { + std::ostringstream FixItString; + FixItString << "aligned(" << NewAlignQuantity << ")"; + FixIt = + FixItHint::CreateReplacement(Attribute->getRange(), FixItString.str()); + } else { + std::ostringstream FixItString; + FixItString << " __attribute__((aligned(" << NewAlignQuantity << ")))"; + FixIt = FixItHint::CreateInsertion(Struct->getEndLoc().getLocWithOffset(1), + FixItString.str()); + } + + // And suggest the minimum power-of-two alignment for the struct as a whole + // (with and without packing). + if (NeedsAlignment) { + diag(Struct->getLocation(), + "accessing fields in struct %0 is inefficient due to poor alignment; " + "currently aligned to %1 bytes, but recommended alignment is %2 bytes") + << Struct << (int)CurrAlign.getQuantity() << NewAlignQuantity << FixIt; + + diag(Struct->getLocation(), + "use \"__attribute__((aligned(%0)))\" to align struct %1 to %0 bytes", + DiagnosticIDs::Note) + << NewAlignQuantity << Struct; + } +} + +void StructPackAlignCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "MaxConfiguredAlignment", MaxConfiguredAlignment); +} + +} // namespace altera +} // namespace tidy +} // namespace clang diff --git a/clang-tools-extra/clang-tidy/altera/StructPackAlignCheck.h b/clang-tools-extra/clang-tidy/altera/StructPackAlignCheck.h new file mode 100644 index 000000000000..b903641247e3 --- /dev/null +++ b/clang-tools-extra/clang-tidy/altera/StructPackAlignCheck.h @@ -0,0 +1,41 @@ +//===--- StructPackAlignCheck.h - clang-tidy --------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ALTERA_STRUCTPACKALIGNCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ALTERA_STRUCTPACKALIGNCHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang { +namespace tidy { +namespace altera { + +/// Finds structs that are inefficiently packed or aligned, and recommends +/// packing and/or aligning of said structs as needed. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/altera-struct-pack-align.html +class StructPackAlignCheck : public ClangTidyCheck { +public: + StructPackAlignCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + MaxConfiguredAlignment(Options.get("MaxConfiguredAlignment", 128)) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + void storeOptions(ClangTidyOptions::OptionMap &Opts); + +private: + const unsigned MaxConfiguredAlignment; + CharUnits computeRecommendedAlignment(CharUnits MinByteSize); +}; + +} // namespace altera +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ALTERA_STRUCTPACKALIGNCHECK_H diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 781fef27c476..53c3894914e5 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -1,112 +1,133 @@ ==================================================== Extra Clang Tools 12.0.0 (In-Progress) Release Notes ==================================================== .. contents:: :local: :depth: 3 Written by the `LLVM Team `_ .. warning:: These are in-progress notes for the upcoming Extra Clang Tools 12 release. Release notes for previous releases can be found on `the Download Page `_. Introduction ============ This document contains the release notes for the Extra Clang Tools, part of the Clang release 12.0.0. Here we describe the status of the Extra Clang Tools in some detail, including major improvements from the previous release and new feature work. All LLVM releases may be downloaded from the `LLVM releases web site `_. For more information about Clang or LLVM, including information about the latest release, please see the `Clang Web Site `_ or the `LLVM Web Site `_. Note that if you are reading this file from a Git checkout or the main Clang web page, this document applies to the *next* release, not the current one. To see the release notes for a specific release, please see the `releases page `_. What's New in Extra Clang Tools 12.0.0? ======================================= Some of the major new features and improvements to Extra Clang Tools are listed here. Generic improvements to Extra Clang Tools as a whole or to its underlying infrastructure are described first, followed by tool-specific sections. Major New Features ------------------ ... Improvements to clangd ---------------------- The improvements are... Improvements to clang-doc ------------------------- The improvements are... Improvements to clang-query --------------------------- The improvements are... Improvements to clang-rename ---------------------------- The improvements are... Improvements to clang-tidy -------------------------- +New modules +^^^^^^^^^^^ + +- New :doc:`altera ` module. + + Includes checks related to OpenCL for FPGA coding guidelines, based on the + `Altera SDK for OpenCL: Best Practices Guide + `_. + +New checks +^^^^^^^^^^ + +- New :doc:`altera-struct-pack-align + ` check. + + Finds structs that are inefficiently packed or aligned, and recommends + packing and/or aligning of said structs as needed. + +- New :doc:`bugprone-misplaced-pointer-arithmetic-in-alloc + ` check. + - New :doc:`bugprone-redundant-branch-condition ` check. Finds condition variables in nested ``if`` statements that were also checked in the outer ``if`` statement and were not changed. - New :doc:`cppcoreguidelines-prefer-member-initializer ` check. Finds member initializations in the constructor body which can be placed into the initialization list instead. Changes in existing checks ^^^^^^^^^^^^^^^^^^^^^^^^^^ - Improved :doc:`readability-identifier-naming ` check. Added an option `GetConfigPerFile` to support including files which use different naming styles. Improvements to include-fixer ----------------------------- The improvements are... Improvements to clang-include-fixer ----------------------------------- The improvements are... Improvements to modularize -------------------------- The improvements are... Improvements to pp-trace ------------------------ The improvements are... Clang-tidy visual studio plugin ------------------------------- diff --git a/clang-tools-extra/docs/clang-tidy/checks/altera-struct-pack-align.rst b/clang-tools-extra/docs/clang-tidy/checks/altera-struct-pack-align.rst new file mode 100644 index 000000000000..b03a4fcf7fcf --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/altera-struct-pack-align.rst @@ -0,0 +1,54 @@ +.. title:: clang-tidy - altera-struct-pack-align + +altera-struct-pack-align +======================== + +Finds structs that are inefficiently packed or aligned, and recommends +packing and/or aligning of said structs as needed. + +Structs that are not packed take up more space than they should, and accessing +structs that are not well aligned is inefficient. + +Fix-its are provided to fix both of these issues by inserting and/or amending +relevant struct attributes. + +Based on the `Altera SDK for OpenCL: Best Practices Guide +`_. + +.. code-block:: c++ + + // The following struct is originally aligned to 4 bytes, and thus takes up + // 12 bytes of memory instead of 10. Packing the struct will make it use + // only 10 bytes of memory, and aligning it to 16 bytes will make it + // efficient to access. + struct example { + char a; // 1 byte + double b; // 8 bytes + char c; // 1 byte + }; + + // The following struct is arranged in such a way that packing is not needed. + // However, it is aligned to 4 bytes instead of 8, and thus needs to be + // explicitly aligned. + struct implicitly_packed_example { + char a; // 1 byte + char b; // 1 byte + char c; // 1 byte + char d; // 1 byte + int e; // 4 bytes + }; + + // The following struct is explicitly aligned and packed. + struct good_example { + char a; // 1 byte + double b; // 8 bytes + char c; // 1 byte + } __attribute__((packed)) __attribute__((aligned(16)); + + // Explicitly aligning a struct to the wrong value will result in a warning. + // The following example should be aligned to 16 bytes, not 32. + struct badly_aligned_example { + char a; // 1 byte + double b; // 8 bytes + char c; // 1 byte + } __attribute__((packed)) __attribute__((aligned(32))); diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index 91414ee8c90f..c569ce704d97 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -1,430 +1,431 @@ .. title:: clang-tidy - Clang-Tidy Checks Clang-Tidy Checks ================= .. toctree:: :glob: :hidden: * .. csv-table:: :header: "Name", "Offers fixes" `abseil-duration-addition `_, "Yes" `abseil-duration-comparison `_, "Yes" `abseil-duration-conversion-cast `_, "Yes" `abseil-duration-division `_, "Yes" `abseil-duration-factory-float `_, "Yes" `abseil-duration-factory-scale `_, "Yes" `abseil-duration-subtraction `_, "Yes" `abseil-duration-unnecessary-conversion `_, "Yes" `abseil-faster-strsplit-delimiter `_, "Yes" `abseil-no-internal-dependencies `_, `abseil-no-namespace `_, `abseil-redundant-strcat-calls `_, "Yes" `abseil-str-cat-append `_, "Yes" `abseil-string-find-startswith `_, "Yes" `abseil-string-find-str-contains `_, "Yes" `abseil-time-comparison `_, "Yes" `abseil-time-subtraction `_, "Yes" `abseil-upgrade-duration-conversions `_, "Yes" + `altera-struct-pack-align `_, `android-cloexec-accept `_, "Yes" `android-cloexec-accept4 `_, `android-cloexec-creat `_, "Yes" `android-cloexec-dup `_, "Yes" `android-cloexec-epoll-create `_, `android-cloexec-epoll-create1 `_, `android-cloexec-fopen `_, `android-cloexec-inotify-init `_, `android-cloexec-inotify-init1 `_, `android-cloexec-memfd-create `_, `android-cloexec-open `_, `android-cloexec-pipe `_, "Yes" `android-cloexec-pipe2 `_, `android-cloexec-socket `_, `android-comparison-in-temp-failure-retry `_, `boost-use-to-string `_, "Yes" `bugprone-argument-comment `_, "Yes" `bugprone-assert-side-effect `_, `bugprone-bad-signal-to-kill-thread `_, `bugprone-bool-pointer-implicit-conversion `_, "Yes" `bugprone-branch-clone `_, `bugprone-copy-constructor-init `_, "Yes" `bugprone-dangling-handle `_, `bugprone-dynamic-static-initializers `_, `bugprone-exception-escape `_, `bugprone-fold-init-type `_, `bugprone-forward-declaration-namespace `_, `bugprone-forwarding-reference-overload `_, `bugprone-inaccurate-erase `_, "Yes" `bugprone-incorrect-roundings `_, `bugprone-infinite-loop `_, `bugprone-integer-division `_, `bugprone-lambda-function-name `_, `bugprone-macro-parentheses `_, "Yes" `bugprone-macro-repeated-side-effects `_, `bugprone-misplaced-operator-in-strlen-in-alloc `_, "Yes" `bugprone-misplaced-pointer-arithmetic-in-alloc `_, "Yes" `bugprone-misplaced-widening-cast `_, `bugprone-move-forwarding-reference `_, "Yes" `bugprone-multiple-statement-macro `_, `bugprone-no-escape `_, `bugprone-not-null-terminated-result `_, "Yes" `bugprone-parent-virtual-call `_, "Yes" `bugprone-posix-return `_, "Yes" `bugprone-redundant-branch-condition `_, "Yes" `bugprone-reserved-identifier `_, "Yes" `bugprone-signed-char-misuse `_, `bugprone-sizeof-container `_, `bugprone-sizeof-expression `_, `bugprone-spuriously-wake-up-functions `_, `bugprone-string-constructor `_, "Yes" `bugprone-string-integer-assignment `_, "Yes" `bugprone-string-literal-with-embedded-nul `_, `bugprone-suspicious-enum-usage `_, `bugprone-suspicious-include `_, `bugprone-suspicious-memset-usage `_, "Yes" `bugprone-suspicious-missing-comma `_, `bugprone-suspicious-semicolon `_, "Yes" `bugprone-suspicious-string-compare `_, "Yes" `bugprone-swapped-arguments `_, "Yes" `bugprone-terminating-continue `_, "Yes" `bugprone-throw-keyword-missing `_, `bugprone-too-small-loop-variable `_, `bugprone-undefined-memory-manipulation `_, `bugprone-undelegated-constructor `_, `bugprone-unhandled-self-assignment `_, `bugprone-unused-raii `_, "Yes" `bugprone-unused-return-value `_, `bugprone-use-after-move `_, `bugprone-virtual-near-miss `_, "Yes" `cert-dcl21-cpp `_, `cert-dcl50-cpp `_, `cert-dcl58-cpp `_, `cert-env33-c `_, `cert-err34-c `_, `cert-err52-cpp `_, `cert-err58-cpp `_, `cert-err60-cpp `_, `cert-flp30-c `_, `cert-mem57-cpp `_, `cert-msc50-cpp `_, `cert-msc51-cpp `_, `cert-oop57-cpp `_, `cert-oop58-cpp `_, `clang-analyzer-core.DynamicTypePropagation `_, `clang-analyzer-core.uninitialized.CapturedBlockVariable `_, `clang-analyzer-cplusplus.InnerPointer `_, `clang-analyzer-nullability.NullableReturnedFromNonnull `_, `clang-analyzer-optin.osx.OSObjectCStyleCast `_, `clang-analyzer-optin.performance.GCDAntipattern `_, `clang-analyzer-optin.performance.Padding `_, `clang-analyzer-optin.portability.UnixAPI `_, `clang-analyzer-osx.MIG `_, `clang-analyzer-osx.NumberObjectConversion `_, `clang-analyzer-osx.OSObjectRetainCount `_, `clang-analyzer-osx.ObjCProperty `_, `clang-analyzer-osx.cocoa.AutoreleaseWrite `_, `clang-analyzer-osx.cocoa.Loops `_, `clang-analyzer-osx.cocoa.MissingSuperCall `_, `clang-analyzer-osx.cocoa.NonNilReturnValue `_, `clang-analyzer-osx.cocoa.RunLoopAutoreleaseLeak `_, `clang-analyzer-valist.CopyToSelf `_, `clang-analyzer-valist.Uninitialized `_, `clang-analyzer-valist.Unterminated `_, `cppcoreguidelines-avoid-goto `_, `cppcoreguidelines-avoid-non-const-global-variables `_, `cppcoreguidelines-init-variables `_, "Yes" `cppcoreguidelines-interfaces-global-init `_, `cppcoreguidelines-macro-usage `_, `cppcoreguidelines-narrowing-conversions `_, `cppcoreguidelines-no-malloc `_, `cppcoreguidelines-owning-memory `_, `cppcoreguidelines-prefer-member-initializer `_, `cppcoreguidelines-pro-bounds-array-to-pointer-decay `_, `cppcoreguidelines-pro-bounds-constant-array-index `_, "Yes" `cppcoreguidelines-pro-bounds-pointer-arithmetic `_, `cppcoreguidelines-pro-type-const-cast `_, `cppcoreguidelines-pro-type-cstyle-cast `_, "Yes" `cppcoreguidelines-pro-type-member-init `_, "Yes" `cppcoreguidelines-pro-type-reinterpret-cast `_, `cppcoreguidelines-pro-type-static-cast-downcast `_, "Yes" `cppcoreguidelines-pro-type-union-access `_, `cppcoreguidelines-pro-type-vararg `_, `cppcoreguidelines-slicing `_, `cppcoreguidelines-special-member-functions `_, `darwin-avoid-spinlock `_, `darwin-dispatch-once-nonstatic `_, "Yes" `fuchsia-default-arguments-calls `_, `fuchsia-default-arguments-declarations `_, "Yes" `fuchsia-multiple-inheritance `_, `fuchsia-overloaded-operator `_, `fuchsia-statically-constructed-objects `_, `fuchsia-trailing-return `_, `fuchsia-virtual-inheritance `_, `google-build-explicit-make-pair `_, `google-build-namespaces `_, `google-build-using-namespace `_, `google-default-arguments `_, `google-explicit-constructor `_, "Yes" `google-global-names-in-headers `_, `google-objc-avoid-nsobject-new `_, `google-objc-avoid-throwing-exception `_, `google-objc-function-naming `_, `google-objc-global-variable-declaration `_, `google-readability-avoid-underscore-in-googletest-name `_, `google-readability-casting `_, `google-readability-todo `_, `google-runtime-int `_, `google-runtime-operator `_, `google-runtime-references `_, `google-upgrade-googletest-case `_, "Yes" `hicpp-avoid-goto `_, `hicpp-exception-baseclass `_, `hicpp-multiway-paths-covered `_, `hicpp-no-assembler `_, `hicpp-signed-bitwise `_, `linuxkernel-must-use-errs `_, `llvm-header-guard `_, `llvm-include-order `_, "Yes" `llvm-namespace-comment `_, `llvm-prefer-isa-or-dyn-cast-in-conditionals `_, "Yes" `llvm-prefer-register-over-unsigned `_, "Yes" `llvm-twine-local `_, "Yes" `llvmlibc-callee-namespace `_, `llvmlibc-implementation-in-namespace `_, `llvmlibc-restrict-system-libc-headers `_, "Yes" `misc-definitions-in-headers `_, "Yes" `misc-misplaced-const `_, `misc-new-delete-overloads `_, `misc-no-recursion `_, `misc-non-copyable-objects `_, `misc-non-private-member-variables-in-classes `_, `misc-redundant-expression `_, "Yes" `misc-static-assert `_, "Yes" `misc-throw-by-value-catch-by-reference `_, `misc-unconventional-assign-operator `_, `misc-uniqueptr-reset-release `_, "Yes" `misc-unused-alias-decls `_, "Yes" `misc-unused-parameters `_, "Yes" `misc-unused-using-decls `_, "Yes" `modernize-avoid-bind `_, "Yes" `modernize-avoid-c-arrays `_, `modernize-concat-nested-namespaces `_, "Yes" `modernize-deprecated-headers `_, "Yes" `modernize-deprecated-ios-base-aliases `_, "Yes" `modernize-loop-convert `_, "Yes" `modernize-make-shared `_, "Yes" `modernize-make-unique `_, "Yes" `modernize-pass-by-value `_, "Yes" `modernize-raw-string-literal `_, "Yes" `modernize-redundant-void-arg `_, "Yes" `modernize-replace-auto-ptr `_, "Yes" `modernize-replace-disallow-copy-and-assign-macro `_, "Yes" `modernize-replace-random-shuffle `_, "Yes" `modernize-return-braced-init-list `_, "Yes" `modernize-shrink-to-fit `_, "Yes" `modernize-unary-static-assert `_, "Yes" `modernize-use-auto `_, "Yes" `modernize-use-bool-literals `_, "Yes" `modernize-use-default-member-init `_, "Yes" `modernize-use-emplace `_, "Yes" `modernize-use-equals-default `_, "Yes" `modernize-use-equals-delete `_, "Yes" `modernize-use-nodiscard `_, "Yes" `modernize-use-noexcept `_, "Yes" `modernize-use-nullptr `_, "Yes" `modernize-use-override `_, "Yes" `modernize-use-trailing-return-type `_, "Yes" `modernize-use-transparent-functors `_, "Yes" `modernize-use-uncaught-exceptions `_, "Yes" `modernize-use-using `_, "Yes" `mpi-buffer-deref `_, "Yes" `mpi-type-mismatch `_, "Yes" `objc-avoid-nserror-init `_, `objc-dealloc-in-category `_, `objc-forbidden-subclassing `_, `objc-missing-hash `_, `objc-nsinvocation-argument-lifetime `_, "Yes" `objc-property-declaration `_, "Yes" `objc-super-self `_, "Yes" `openmp-exception-escape `_, `openmp-use-default-none `_, `performance-faster-string-find `_, "Yes" `performance-for-range-copy `_, "Yes" `performance-implicit-conversion-in-loop `_, `performance-inefficient-algorithm `_, "Yes" `performance-inefficient-string-concatenation `_, `performance-inefficient-vector-operation `_, "Yes" `performance-move-const-arg `_, "Yes" `performance-move-constructor-init `_, "Yes" `performance-no-automatic-move `_, `performance-noexcept-move-constructor `_, "Yes" `performance-trivially-destructible `_, "Yes" `performance-type-promotion-in-math-fn `_, "Yes" `performance-unnecessary-copy-initialization `_, `performance-unnecessary-value-param `_, "Yes" `portability-restrict-system-includes `_, "Yes" `portability-simd-intrinsics `_, `readability-avoid-const-params-in-decls `_, `readability-braces-around-statements `_, "Yes" `readability-const-return-type `_, "Yes" `readability-container-size-empty `_, "Yes" `readability-convert-member-functions-to-static `_, `readability-delete-null-pointer `_, "Yes" `readability-deleted-default `_, `readability-else-after-return `_, "Yes" `readability-function-size `_, `readability-identifier-naming `_, "Yes" `readability-implicit-bool-conversion `_, "Yes" `readability-inconsistent-declaration-parameter-name `_, "Yes" `readability-isolate-declaration `_, "Yes" `readability-magic-numbers `_, `readability-make-member-function-const `_, "Yes" `readability-misleading-indentation `_, `readability-misplaced-array-index `_, "Yes" `readability-named-parameter `_, "Yes" `readability-non-const-parameter `_, "Yes" `readability-qualified-auto `_, "Yes" `readability-redundant-access-specifiers `_, "Yes" `readability-redundant-control-flow `_, "Yes" `readability-redundant-declaration `_, "Yes" `readability-redundant-function-ptr-dereference `_, "Yes" `readability-redundant-member-init `_, "Yes" `readability-redundant-preprocessor `_, `readability-redundant-smartptr-get `_, "Yes" `readability-redundant-string-cstr `_, "Yes" `readability-redundant-string-init `_, "Yes" `readability-simplify-boolean-expr `_, "Yes" `readability-simplify-subscript-expr `_, "Yes" `readability-static-accessed-through-instance `_, "Yes" `readability-static-definition-in-anonymous-namespace `_, "Yes" `readability-string-compare `_, "Yes" `readability-uniqueptr-delete-release `_, "Yes" `readability-uppercase-literal-suffix `_, "Yes" `readability-use-anyofallof `_, `zircon-temporary-objects `_, .. csv-table:: Aliases.. :header: "Name", "Redirect", "Offers fixes" `cert-con36-c `_, `bugprone-spuriously-wake-up-functions `_, `cert-con54-cpp `_, `bugprone-spuriously-wake-up-functions `_, `cert-dcl03-c `_, `misc-static-assert `_, "Yes" `cert-dcl16-c `_, `readability-uppercase-literal-suffix `_, "Yes" `cert-dcl37-c `_, `bugprone-reserved-identifier `_, "Yes" `cert-dcl51-cpp `_, `bugprone-reserved-identifier `_, "Yes" `cert-dcl54-cpp `_, `misc-new-delete-overloads `_, `cert-dcl59-cpp `_, `google-build-namespaces `_, `cert-err09-cpp `_, `misc-throw-by-value-catch-by-reference `_, `cert-err61-cpp `_, `misc-throw-by-value-catch-by-reference `_, `cert-fio38-c `_, `misc-non-copyable-objects `_, `cert-msc30-c `_, `cert-msc50-cpp `_, `cert-msc32-c `_, `cert-msc51-cpp `_, `cert-oop11-cpp `_, `performance-move-constructor-init `_, "Yes" `cert-oop54-cpp `_, `bugprone-unhandled-self-assignment `_, `cert-pos44-c `_, `bugprone-bad-signal-to-kill-thread `_, `cert-str34-c `_, `bugprone-signed-char-misuse `_, `clang-analyzer-core.CallAndMessage `_, `Clang Static Analyzer `_, `clang-analyzer-core.DivideZero `_, `Clang Static Analyzer `_, `clang-analyzer-core.NonNullParamChecker `_, `Clang Static Analyzer `_, `clang-analyzer-core.NullDereference `_, `Clang Static Analyzer `_, `clang-analyzer-core.StackAddressEscape `_, `Clang Static Analyzer `_, `clang-analyzer-core.UndefinedBinaryOperatorResult `_, `Clang Static Analyzer `_, `clang-analyzer-core.VLASize `_, `Clang Static Analyzer `_, `clang-analyzer-core.uninitialized.ArraySubscript `_, `Clang Static Analyzer `_, `clang-analyzer-core.uninitialized.Assign `_, `Clang Static Analyzer `_, `clang-analyzer-core.uninitialized.Branch `_, `Clang Static Analyzer `_, `clang-analyzer-core.uninitialized.UndefReturn `_, `Clang Static Analyzer `_, `clang-analyzer-cplusplus.Move `_, `Clang Static Analyzer `_, `clang-analyzer-cplusplus.NewDelete `_, `Clang Static Analyzer `_, `clang-analyzer-cplusplus.NewDeleteLeaks `_, `Clang Static Analyzer `_, `clang-analyzer-deadcode.DeadStores `_, `Clang Static Analyzer `_, `clang-analyzer-nullability.NullPassedToNonnull `_, `Clang Static Analyzer `_, `clang-analyzer-nullability.NullReturnedFromNonnull `_, `Clang Static Analyzer `_, `clang-analyzer-nullability.NullableDereferenced `_, `Clang Static Analyzer `_, `clang-analyzer-nullability.NullablePassedToNonnull `_, `Clang Static Analyzer `_, `clang-analyzer-optin.cplusplus.UninitializedObject `_, `Clang Static Analyzer `_, `clang-analyzer-optin.cplusplus.VirtualCall `_, `Clang Static Analyzer `_, `clang-analyzer-optin.mpi.MPI-Checker `_, `Clang Static Analyzer `_, `clang-analyzer-optin.osx.cocoa.localizability.EmptyLocalizationContextChecker `_, `Clang Static Analyzer `_, `clang-analyzer-optin.osx.cocoa.localizability.NonLocalizedStringChecker `_, `Clang Static Analyzer `_, `clang-analyzer-osx.API `_, `Clang Static Analyzer `_, `clang-analyzer-osx.SecKeychainAPI `_, `Clang Static Analyzer `_, `clang-analyzer-osx.cocoa.AtSync `_, `Clang Static Analyzer `_, `clang-analyzer-osx.cocoa.ClassRelease `_, `Clang Static Analyzer `_, `clang-analyzer-osx.cocoa.Dealloc `_, `Clang Static Analyzer `_, `clang-analyzer-osx.cocoa.IncompatibleMethodTypes `_, `Clang Static Analyzer `_, `clang-analyzer-osx.cocoa.NSAutoreleasePool `_, `Clang Static Analyzer `_, `clang-analyzer-osx.cocoa.NSError `_, `Clang Static Analyzer `_, `clang-analyzer-osx.cocoa.NilArg `_, `Clang Static Analyzer `_, `clang-analyzer-osx.cocoa.ObjCGenerics `_, `Clang Static Analyzer `_, `clang-analyzer-osx.cocoa.RetainCount `_, `Clang Static Analyzer `_, `clang-analyzer-osx.cocoa.SelfInit `_, `Clang Static Analyzer `_, `clang-analyzer-osx.cocoa.SuperDealloc `_, `Clang Static Analyzer `_, `clang-analyzer-osx.cocoa.UnusedIvars `_, `Clang Static Analyzer `_, `clang-analyzer-osx.cocoa.VariadicMethodTypes `_, `Clang Static Analyzer `_, `clang-analyzer-osx.coreFoundation.CFError `_, `Clang Static Analyzer `_, `clang-analyzer-osx.coreFoundation.CFNumber `_, `Clang Static Analyzer `_, `clang-analyzer-osx.coreFoundation.CFRetainRelease `_, `Clang Static Analyzer `_, `clang-analyzer-osx.coreFoundation.containers.OutOfBounds `_, `Clang Static Analyzer `_, `clang-analyzer-osx.coreFoundation.containers.PointerSizedValues `_, `Clang Static Analyzer `_, `clang-analyzer-security.FloatLoopCounter `_, `Clang Static Analyzer `_, `clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling `_, `Clang Static Analyzer `_, `clang-analyzer-security.insecureAPI.UncheckedReturn `_, `Clang Static Analyzer `_, `clang-analyzer-security.insecureAPI.bcmp `_, `Clang Static Analyzer `_, `clang-analyzer-security.insecureAPI.bcopy `_, `Clang Static Analyzer `_, `clang-analyzer-security.insecureAPI.bzero `_, `Clang Static Analyzer `_, `clang-analyzer-security.insecureAPI.getpw `_, `Clang Static Analyzer `_, `clang-analyzer-security.insecureAPI.gets `_, `Clang Static Analyzer `_, `clang-analyzer-security.insecureAPI.mkstemp `_, `Clang Static Analyzer `_, `clang-analyzer-security.insecureAPI.mktemp `_, `Clang Static Analyzer `_, `clang-analyzer-security.insecureAPI.rand `_, `Clang Static Analyzer `_, `clang-analyzer-security.insecureAPI.strcpy `_, `Clang Static Analyzer `_, `clang-analyzer-security.insecureAPI.vfork `_, `Clang Static Analyzer `_, `clang-analyzer-unix.API `_, `Clang Static Analyzer `_, `clang-analyzer-unix.Malloc `_, `Clang Static Analyzer `_, `clang-analyzer-unix.MallocSizeof `_, `Clang Static Analyzer `_, `clang-analyzer-unix.MismatchedDeallocator `_, `Clang Static Analyzer `_, `clang-analyzer-unix.Vfork `_, `Clang Static Analyzer `_, `clang-analyzer-unix.cstring.BadSizeArg `_, `Clang Static Analyzer `_, `clang-analyzer-unix.cstring.NullArg `_, `Clang Static Analyzer `_, `cppcoreguidelines-avoid-c-arrays `_, `modernize-avoid-c-arrays `_, `cppcoreguidelines-avoid-magic-numbers `_, `readability-magic-numbers `_, `cppcoreguidelines-c-copy-assignment-signature `_, `misc-unconventional-assign-operator `_, `cppcoreguidelines-explicit-virtual-functions `_, `modernize-use-override `_, "Yes" `cppcoreguidelines-non-private-member-variables-in-classes `_, `misc-non-private-member-variables-in-classes `_, `fuchsia-header-anon-namespaces `_, `google-build-namespaces `_, `google-readability-braces-around-statements `_, `readability-braces-around-statements `_, "Yes" `google-readability-function-size `_, `readability-function-size `_, `google-readability-namespace-comments `_, `llvm-namespace-comment `_, `hicpp-avoid-c-arrays `_, `modernize-avoid-c-arrays `_, `hicpp-braces-around-statements `_, `readability-braces-around-statements `_, "Yes" `hicpp-deprecated-headers `_, `modernize-deprecated-headers `_, "Yes" `hicpp-explicit-conversions `_, `google-explicit-constructor `_, "Yes" `hicpp-function-size `_, `readability-function-size `_, `hicpp-invalid-access-moved `_, `bugprone-use-after-move `_, `hicpp-member-init `_, `cppcoreguidelines-pro-type-member-init `_, "Yes" `hicpp-move-const-arg `_, `performance-move-const-arg `_, "Yes" `hicpp-named-parameter `_, `readability-named-parameter `_, "Yes" `hicpp-new-delete-operators `_, `misc-new-delete-overloads `_, `hicpp-no-array-decay `_, `cppcoreguidelines-pro-bounds-array-to-pointer-decay `_, `hicpp-no-malloc `_, `cppcoreguidelines-no-malloc `_, `hicpp-noexcept-move `_, `performance-noexcept-move-constructor `_, "Yes" `hicpp-special-member-functions `_, `cppcoreguidelines-special-member-functions `_, `hicpp-static-assert `_, `misc-static-assert `_, "Yes" `hicpp-undelegated-constructor `_, `bugprone-undelegated-constructor `_, `hicpp-uppercase-literal-suffix `_, `readability-uppercase-literal-suffix `_, "Yes" `hicpp-use-auto `_, `modernize-use-auto `_, "Yes" `hicpp-use-emplace `_, `modernize-use-emplace `_, "Yes" `hicpp-use-equals-default `_, `modernize-use-equals-default `_, "Yes" `hicpp-use-equals-delete `_, `modernize-use-equals-delete `_, "Yes" `hicpp-use-noexcept `_, `modernize-use-noexcept `_, "Yes" `hicpp-use-nullptr `_, `modernize-use-nullptr `_, "Yes" `hicpp-use-override `_, `modernize-use-override `_, "Yes" `hicpp-vararg `_, `cppcoreguidelines-pro-type-vararg `_, `llvm-else-after-return `_, `readability-else-after-return `_, "Yes" `llvm-qualified-auto `_, `readability-qualified-auto `_, "Yes" diff --git a/clang-tools-extra/docs/clang-tidy/index.rst b/clang-tools-extra/docs/clang-tidy/index.rst index b9a4a7d694b4..a85c72154178 100644 --- a/clang-tools-extra/docs/clang-tidy/index.rst +++ b/clang-tools-extra/docs/clang-tidy/index.rst @@ -1,346 +1,347 @@ ========== Clang-Tidy ========== .. contents:: See also: .. toctree:: :maxdepth: 1 The list of clang-tidy checks Clang-tidy IDE/Editor Integrations Getting Involved :program:`clang-tidy` is a clang-based C++ "linter" tool. Its purpose is to provide an extensible framework for diagnosing and fixing typical programming errors, like style violations, interface misuse, or bugs that can be deduced via static analysis. :program:`clang-tidy` is modular and provides a convenient interface for writing new checks. Using clang-tidy ================ :program:`clang-tidy` is a `LibTooling`_-based tool, and it's easier to work with if you set up a compile command database for your project (for an example of how to do this see `How To Setup Tooling For LLVM`_). You can also specify compilation options on the command line after ``--``: .. code-block:: console $ clang-tidy test.cpp -- -Imy_project/include -DMY_DEFINES ... :program:`clang-tidy` has its own checks and can also run Clang static analyzer checks. Each check has a name and the checks to run can be chosen using the ``-checks=`` option, which specifies a comma-separated list of positive and negative (prefixed with ``-``) globs. Positive globs add subsets of checks, negative globs remove them. For example, .. code-block:: console $ clang-tidy test.cpp -checks=-*,clang-analyzer-*,-clang-analyzer-cplusplus* will disable all default checks (``-*``) and enable all ``clang-analyzer-*`` checks except for ``clang-analyzer-cplusplus*`` ones. The ``-list-checks`` option lists all the enabled checks. When used without ``-checks=``, it shows checks enabled by default. Use ``-checks=*`` to see all available checks or with any other value of ``-checks=`` to see which checks are enabled by this value. .. _checks-groups-table: There are currently the following groups of checks: ====================== ========================================================= Name prefix Description ====================== ========================================================= ``abseil-`` Checks related to Abseil library. +``altera-`` Checks related to OpenCL programming for FPGAs. ``android-`` Checks related to Android. ``boost-`` Checks related to Boost library. ``bugprone-`` Checks that target bugprone code constructs. ``cert-`` Checks related to CERT Secure Coding Guidelines. ``clang-analyzer-`` Clang Static Analyzer checks. ``cppcoreguidelines-`` Checks related to C++ Core Guidelines. ``darwin-`` Checks related to Darwin coding conventions. ``fuchsia-`` Checks related to Fuchsia coding conventions. ``google-`` Checks related to Google coding conventions. ``hicpp-`` Checks related to High Integrity C++ Coding Standard. ``linuxkernel-`` Checks related to the Linux Kernel coding conventions. ``llvm-`` Checks related to the LLVM coding conventions. ``llvmlibc-`` Checks related to the LLVM-libc coding standards. ``misc-`` Checks that we didn't have a better category for. ``modernize-`` Checks that advocate usage of modern (currently "modern" means "C++11") language constructs. ``mpi-`` Checks related to MPI (Message Passing Interface). ``objc-`` Checks related to Objective-C coding conventions. ``openmp-`` Checks related to OpenMP API. ``performance-`` Checks that target performance-related issues. ``portability-`` Checks that target portability-related issues that don't relate to any particular coding style. ``readability-`` Checks that target readability-related issues that don't relate to any particular coding style. ``zircon-`` Checks related to Zircon kernel coding conventions. ====================== ========================================================= Clang diagnostics are treated in a similar way as check diagnostics. Clang diagnostics are displayed by :program:`clang-tidy` and can be filtered out using ``-checks=`` option. However, the ``-checks=`` option does not affect compilation arguments, so it can not turn on Clang warnings which are not already turned on in build configuration. The ``-warnings-as-errors=`` option upgrades any warnings emitted under the ``-checks=`` flag to errors (but it does not enable any checks itself). Clang diagnostics have check names starting with ``clang-diagnostic-``. Diagnostics which have a corresponding warning option, are named ``clang-diagnostic-``, e.g. Clang warning controlled by ``-Wliteral-conversion`` will be reported with check name ``clang-diagnostic-literal-conversion``. The ``-fix`` flag instructs :program:`clang-tidy` to fix found errors if supported by corresponding checks. An overview of all the command-line options: .. code-block:: console $ clang-tidy --help USAGE: clang-tidy [options] [... ] OPTIONS: Generic Options: --help - Display available options (--help-hidden for more) --help-list - Display list of available options (--help-list-hidden for more) --version - Display the version of this program clang-tidy options: --checks= - Comma-separated list of globs with optional '-' prefix. Globs are processed in order of appearance in the list. Globs without '-' prefix add checks with matching names to the set, globs with the '-' prefix remove checks with matching names from the set of enabled checks. This option's value is appended to the value of the 'Checks' option in .clang-tidy file, if any. --config= - Specifies a configuration in YAML/JSON format: -config="{Checks: '*', CheckOptions: [{key: x, value: y}]}" When the value is empty, clang-tidy will attempt to find a file named .clang-tidy for each source file in its parent directories. --dump-config - Dumps configuration in the YAML format to stdout. This option can be used along with a file name (and '--' if the file is outside of a project with configured compilation database). The configuration used for this file will be printed. Use along with -checks=* to include configuration of all checks. --enable-check-profile - Enable per-check timing profiles, and print a report to stderr. --explain-config - For each enabled check explains, where it is enabled, i.e. in clang-tidy binary, command line or a specific configuration file. --export-fixes= - YAML file to store suggested fixes in. The stored fixes can be applied to the input source code with clang-apply-replacements. --extra-arg= - Additional argument to append to the compiler command line Can be used several times. --extra-arg-before= - Additional argument to prepend to the compiler command line Can be used several times. --fix - Apply suggested fixes. Without -fix-errors clang-tidy will bail out if any compilation errors were found. --fix-errors - Apply suggested fixes even if compilation errors were found. If compiler errors have attached fix-its, clang-tidy will apply them as well. --format-style= - Style for formatting code around applied fixes: - 'none' (default) turns off formatting - 'file' (literally 'file', not a placeholder) uses .clang-format file in the closest parent directory - '{ }' specifies options inline, e.g. -format-style='{BasedOnStyle: llvm, IndentWidth: 8}' - 'llvm', 'google', 'webkit', 'mozilla' See clang-format documentation for the up-to-date information about formatting styles and options. This option overrides the 'FormatStyle` option in .clang-tidy file, if any. --header-filter= - Regular expression matching the names of the headers to output diagnostics from. Diagnostics from the main file of each translation unit are always displayed. Can be used together with -line-filter. This option overrides the 'HeaderFilterRegex' option in .clang-tidy file, if any. --line-filter= - List of files with line ranges to filter the warnings. Can be used together with -header-filter. The format of the list is a JSON array of objects: [ {"name":"file1.cpp","lines":[[1,3],[5,7]]}, {"name":"file2.h"} ] --list-checks - List all enabled checks and exit. Use with -checks=* to list all available checks. -p= - Build path --quiet - Run clang-tidy in quiet mode. This suppresses printing statistics about ignored warnings and warnings treated as errors if the respective options are specified. --store-check-profile= - By default reports are printed in tabulated format to stderr. When this option is passed, these per-TU profiles are instead stored as JSON. --system-headers - Display the errors from system headers. --vfsoverlay= - Overlay the virtual filesystem described by file over the real file system. --warnings-as-errors= - Upgrades warnings to errors. Same format as '-checks'. This option's value is appended to the value of the 'WarningsAsErrors' option in .clang-tidy file, if any. -p is used to read a compile command database. For example, it can be a CMake build directory in which a file named compile_commands.json exists (use -DCMAKE_EXPORT_COMPILE_COMMANDS=ON CMake option to get this output). When no build path is specified, a search for compile_commands.json will be attempted through all parent paths of the first input file . See: https://clang.llvm.org/docs/HowToSetupToolingForLLVM.html for an example of setting up Clang Tooling on a source tree. ... specify the paths of source files. These paths are looked up in the compile command database. If the path of a file is absolute, it needs to point into CMake's source tree. If the path is relative, the current working directory needs to be in the CMake source tree and the file must be in a subdirectory of the current working directory. "./" prefixes in the relative files will be automatically removed, but the rest of a relative path must be a suffix of a path in the compile command database. Configuration files: clang-tidy attempts to read configuration for each source file from a .clang-tidy file located in the closest parent directory of the source file. If InheritParentConfig is true in a config file, the configuration file in the parent directory (if any exists) will be taken and current config file will be applied on top of the parent one. If any configuration options have a corresponding command-line option, command-line option takes precedence. The effective configuration can be inspected using -dump-config: $ clang-tidy -dump-config --- Checks: '-*,some-check' WarningsAsErrors: '' HeaderFilterRegex: '' FormatStyle: none InheritParentConfig: true User: user CheckOptions: - key: some-check.SomeOption value: 'some value' ... .. _clang-tidy-nolint: Suppressing Undesired Diagnostics ================================= :program:`clang-tidy` diagnostics are intended to call out code that does not adhere to a coding standard, or is otherwise problematic in some way. However, if the code is known to be correct, it may be useful to silence the warning. Some clang-tidy checks provide a check-specific way to silence the diagnostics, e.g. `bugprone-use-after-move `_ can be silenced by re-initializing the variable after it has been moved out, `bugprone-string-integer-assignment `_ can be suppressed by explicitly casting the integer to ``char``, `readability-implicit-bool-conversion `_ can also be suppressed by using explicit casts, etc. If a specific suppression mechanism is not available for a certain warning, or its use is not desired for some reason, :program:`clang-tidy` has a generic mechanism to suppress diagnostics using ``NOLINT`` or ``NOLINTNEXTLINE`` comments. The ``NOLINT`` comment instructs :program:`clang-tidy` to ignore warnings on the *same line* (it doesn't apply to a function, a block of code or any other language construct, it applies to the line of code it is on). If introducing the comment in the same line would change the formatting in undesired way, the ``NOLINTNEXTLINE`` comment allows to suppress clang-tidy warnings on the *next line*. Both comments can be followed by an optional list of check names in parentheses (see below for the formal syntax). For example: .. code-block:: c++ class Foo { // Suppress all the diagnostics for the line Foo(int param); // NOLINT // Consider explaining the motivation to suppress the warning. Foo(char param); // NOLINT: Allow implicit conversion from `char`, because . // Silence only the specified checks for the line Foo(double param); // NOLINT(google-explicit-constructor, google-runtime-int) // Silence only the specified diagnostics for the next line // NOLINTNEXTLINE(google-explicit-constructor, google-runtime-int) Foo(bool param); }; The formal syntax of ``NOLINT``/``NOLINTNEXTLINE`` is the following: .. parsed-literal:: lint-comment: lint-command lint-command lint-args lint-args: **(** check-name-list **)** check-name-list: *check-name* check-name-list **,** *check-name* lint-command: **NOLINT** **NOLINTNEXTLINE** Note that whitespaces between ``NOLINT``/``NOLINTNEXTLINE`` and the opening parenthesis are not allowed (in this case the comment will be treated just as ``NOLINT``/``NOLINTNEXTLINE``), whereas in check names list (inside the parenthesis) whitespaces can be used and will be ignored. .. _LibTooling: https://clang.llvm.org/docs/LibTooling.html .. _How To Setup Tooling For LLVM: https://clang.llvm.org/docs/HowToSetupToolingForLLVM.html diff --git a/clang-tools-extra/test/clang-tidy/checkers/altera-struct-pack-align.cpp b/clang-tools-extra/test/clang-tidy/checkers/altera-struct-pack-align.cpp new file mode 100644 index 000000000000..615b6cafe87a --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/altera-struct-pack-align.cpp @@ -0,0 +1,101 @@ +// RUN: %check_clang_tidy %s altera-struct-pack-align %t -- -header-filter=.* + +// Struct needs both alignment and packing +struct error { + char a; + double b; + char c; +}; +// CHECK-MESSAGES: :[[@LINE-5]]:8: warning: accessing fields in struct 'error' is inefficient due to padding; only needs 10 bytes but is using 24 bytes [altera-struct-pack-align] +// CHECK-MESSAGES: :[[@LINE-6]]:8: note: use "__attribute__((packed))" to reduce the amount of padding applied to struct 'error' +// CHECK-MESSAGES: :[[@LINE-7]]:8: warning: accessing fields in struct 'error' is inefficient due to poor alignment; currently aligned to 8 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align] +// CHECK-MESSAGES: :[[@LINE-8]]:8: note: use "__attribute__((aligned(16)))" to align struct 'error' to 16 bytes +// CHECK-FIXES: __attribute__((packed)) +// CHECK-FIXES: __attribute__((aligned(16))); + +// Struct is explicitly packed, but needs alignment +struct error_packed { + char a; + double b; + char c; +} __attribute__((packed)); +// CHECK-MESSAGES: :[[@LINE-5]]:8: warning: accessing fields in struct 'error_packed' is inefficient due to poor alignment; currently aligned to 1 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align] +// CHECK-MESSAGES: :[[@LINE-6]]:8: note: use "__attribute__((aligned(16)))" to align struct 'error_packed' to 16 bytes +// CHECK-FIXES: __attribute__((aligned(16))) + +// Struct is properly packed, but needs alignment +struct align_only { + char a; + char b; + char c; + char d; + int e; + double f; +}; +// CHECK-MESSAGES: :[[@LINE-8]]:8: warning: accessing fields in struct 'align_only' is inefficient due to poor alignment; currently aligned to 8 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align] +// CHECK-MESSAGES: :[[@LINE-9]]:8: note: use "__attribute__((aligned(16)))" to align struct 'align_only' to 16 bytes +// CHECK-FIXES: __attribute__((aligned(16))); + +// Struct is perfectly packed but wrongly aligned +struct bad_align { + char a; + double b; + char c; +} __attribute__((packed)) __attribute__((aligned(8))); +// CHECK-MESSAGES: :[[@LINE-5]]:8: warning: accessing fields in struct 'bad_align' is inefficient due to poor alignment; currently aligned to 8 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align] +// CHECK-MESSAGES: :[[@LINE-6]]:8: note: use "__attribute__((aligned(16)))" to align struct 'bad_align' to 16 bytes +// CHECK-FIXES: __attribute__((aligned(16))); + +struct bad_align2 { + char a; + double b; + char c; +} __attribute__((packed)) __attribute__((aligned(32))); +// CHECK-MESSAGES: :[[@LINE-5]]:8: warning: accessing fields in struct 'bad_align2' is inefficient due to poor alignment; currently aligned to 32 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align] +// CHECK-MESSAGES: :[[@LINE-6]]:8: note: use "__attribute__((aligned(16)))" to align struct 'bad_align2' to 16 bytes +// CHECK-FIXES: __attribute__((aligned(16))); + +struct bad_align3 { + char a; + double b; + char c; +} __attribute__((packed)) __attribute__((aligned(4))); +// CHECK-MESSAGES: :[[@LINE-5]]:8: warning: accessing fields in struct 'bad_align3' is inefficient due to poor alignment; currently aligned to 4 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align] +// CHECK-MESSAGES: :[[@LINE-6]]:8: note: use "__attribute__((aligned(16)))" to align struct 'bad_align3' to 16 bytes +// CHECK-FIXES: __attribute__((aligned(16))); + +// Struct is both perfectly packed and aligned +struct success { + char a; + double b; + char c; +} __attribute__((packed)) __attribute__((aligned(16))); +//Should take 10 bytes and be aligned to 16 bytes + +// Struct is properly packed, and explicitly aligned +struct success2 { + int a; + int b; + int c; +} __attribute__((aligned(16))); + +// If struct is properly aligned, packing not needed +struct success3 { + char a; + double b; + char c; +} __attribute__((aligned(16))); + +// If struct is templated, warnings should not be triggered +template +struct success4 { + A a; + B b; + int c; +}; + +// Warnings should not trigger on struct instantiations +void no_trigger_on_instantiation() { + struct bad_align3 instantiated { 'a', 0.001, 'b' }; +} +