mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-23 16:06:24 +00:00
[clang-tidy] Add module for llvm-libc and restrict-system-libc-header-check.
Summary: This adds a new module to enforce standards specific to the llvm-libc project. This change also adds the first check which restricts user from including system libc headers accidentally which can lead to subtle bugs that would be a challenge to detect. Reviewers: alexfh, hokein, aaron.ballman Reviewed By: aaron.ballman Subscribers: juliehockett, arphaman, jfb, abrachet, sivachandra, Eugene.Zelenko, njames93, mgorny, xazax.hun, MaskRay, cfe-commits Tags: #clang-tools-extra, #libc-project, #clang Differential Revision: https://reviews.llvm.org/D75332
This commit is contained in:
parent
360aff0493
commit
eb41cc6198
@ -51,6 +51,7 @@ add_subdirectory(google)
|
|||||||
add_subdirectory(hicpp)
|
add_subdirectory(hicpp)
|
||||||
add_subdirectory(linuxkernel)
|
add_subdirectory(linuxkernel)
|
||||||
add_subdirectory(llvm)
|
add_subdirectory(llvm)
|
||||||
|
add_subdirectory(llvmlibc)
|
||||||
add_subdirectory(misc)
|
add_subdirectory(misc)
|
||||||
add_subdirectory(modernize)
|
add_subdirectory(modernize)
|
||||||
if(CLANG_ENABLE_STATIC_ANALYZER)
|
if(CLANG_ENABLE_STATIC_ANALYZER)
|
||||||
@ -75,6 +76,7 @@ set(ALL_CLANG_TIDY_CHECKS
|
|||||||
clangTidyHICPPModule
|
clangTidyHICPPModule
|
||||||
clangTidyLinuxKernelModule
|
clangTidyLinuxKernelModule
|
||||||
clangTidyLLVMModule
|
clangTidyLLVMModule
|
||||||
|
clangTidyLLVMLibcModule
|
||||||
clangTidyMiscModule
|
clangTidyMiscModule
|
||||||
clangTidyModernizeModule
|
clangTidyModernizeModule
|
||||||
clangTidyObjCModule
|
clangTidyObjCModule
|
||||||
|
@ -45,6 +45,11 @@ extern volatile int LLVMModuleAnchorSource;
|
|||||||
static int LLVM_ATTRIBUTE_UNUSED LLVMModuleAnchorDestination =
|
static int LLVM_ATTRIBUTE_UNUSED LLVMModuleAnchorDestination =
|
||||||
LLVMModuleAnchorSource;
|
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 CppCoreGuidelinesModule.
|
// This anchor is used to force the linker to link the CppCoreGuidelinesModule.
|
||||||
extern volatile int CppCoreGuidelinesModuleAnchorSource;
|
extern volatile int CppCoreGuidelinesModuleAnchorSource;
|
||||||
static int LLVM_ATTRIBUTE_UNUSED CppCoreGuidelinesModuleAnchorDestination =
|
static int LLVM_ATTRIBUTE_UNUSED CppCoreGuidelinesModuleAnchorDestination =
|
||||||
|
15
clang-tools-extra/clang-tidy/llvmlibc/CMakeLists.txt
Normal file
15
clang-tools-extra/clang-tidy/llvmlibc/CMakeLists.txt
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
set(LLVM_LINK_COMPONENTS support)
|
||||||
|
|
||||||
|
add_clang_library(clangTidyLLVMLibcModule
|
||||||
|
LLVMLibcTidyModule.cpp
|
||||||
|
RestrictSystemLibcHeadersCheck.cpp
|
||||||
|
|
||||||
|
LINK_LIBS
|
||||||
|
clangAST
|
||||||
|
clangASTMatchers
|
||||||
|
clangBasic
|
||||||
|
clangLex
|
||||||
|
clangTidy
|
||||||
|
clangTidyUtils
|
||||||
|
clangTooling
|
||||||
|
)
|
37
clang-tools-extra/clang-tidy/llvmlibc/LLVMLibcTidyModule.cpp
Normal file
37
clang-tools-extra/clang-tidy/llvmlibc/LLVMLibcTidyModule.cpp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
//===--- LLVMLibcTidyModule.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 "RestrictSystemLibcHeadersCheck.h"
|
||||||
|
|
||||||
|
namespace clang {
|
||||||
|
namespace tidy {
|
||||||
|
namespace llvm_libc {
|
||||||
|
|
||||||
|
class LLVMLibcModule : public ClangTidyModule {
|
||||||
|
public:
|
||||||
|
void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
|
||||||
|
CheckFactories.registerCheck<RestrictSystemLibcHeadersCheck>(
|
||||||
|
"llvmlibc-restrict-system-libc-headers");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Register the LLVMLibcTidyModule using this statically initialized variable.
|
||||||
|
static ClangTidyModuleRegistry::Add<LLVMLibcModule>
|
||||||
|
X("llvmlibc-module", "Adds LLVM libc standards checks.");
|
||||||
|
|
||||||
|
} // namespace llvm_libc
|
||||||
|
|
||||||
|
// This anchor is used to force the linker to link in the generated object file
|
||||||
|
// and thus register the LLVMLibcModule.
|
||||||
|
volatile int LLVMLibcModuleAnchorSource = 0;
|
||||||
|
|
||||||
|
} // namespace tidy
|
||||||
|
} // namespace clang
|
@ -0,0 +1,73 @@
|
|||||||
|
//===--- RestrictSystemLibcHeadersCheck.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 "RestrictSystemLibcHeadersCheck.h"
|
||||||
|
#include "clang/AST/ASTContext.h"
|
||||||
|
#include "clang/ASTMatchers/ASTMatchFinder.h"
|
||||||
|
#include "clang/Lex/HeaderSearch.h"
|
||||||
|
#include "clang/Lex/HeaderSearchOptions.h"
|
||||||
|
|
||||||
|
namespace clang {
|
||||||
|
namespace tidy {
|
||||||
|
namespace llvm_libc {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class RestrictedIncludesPPCallbacks : public PPCallbacks {
|
||||||
|
public:
|
||||||
|
explicit RestrictedIncludesPPCallbacks(
|
||||||
|
RestrictSystemLibcHeadersCheck &Check, const SourceManager &SM,
|
||||||
|
const SmallString<128> CompilerIncudeDir)
|
||||||
|
: Check(Check), SM(SM), CompilerIncudeDir(CompilerIncudeDir) {}
|
||||||
|
|
||||||
|
void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
|
||||||
|
StringRef FileName, bool IsAngled,
|
||||||
|
CharSourceRange FilenameRange, const FileEntry *File,
|
||||||
|
StringRef SearchPath, StringRef RelativePath,
|
||||||
|
const Module *Imported,
|
||||||
|
SrcMgr::CharacteristicKind FileType) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
RestrictSystemLibcHeadersCheck &Check;
|
||||||
|
const SourceManager &SM;
|
||||||
|
const SmallString<128> CompilerIncudeDir;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void RestrictedIncludesPPCallbacks::InclusionDirective(
|
||||||
|
SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName,
|
||||||
|
bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File,
|
||||||
|
StringRef SearchPath, StringRef RelativePath, const Module *Imported,
|
||||||
|
SrcMgr::CharacteristicKind FileType) {
|
||||||
|
if (SrcMgr::isSystem(FileType)) {
|
||||||
|
// Compiler provided headers are allowed (e.g stddef.h).
|
||||||
|
if (SearchPath == CompilerIncudeDir) return;
|
||||||
|
if (!SM.isInMainFile(HashLoc)) {
|
||||||
|
Check.diag(
|
||||||
|
HashLoc,
|
||||||
|
"system libc header %0 not allowed, transitively included from %1")
|
||||||
|
<< FileName << SM.getFilename(HashLoc);
|
||||||
|
} else {
|
||||||
|
Check.diag(HashLoc, "system libc header %0 not allowed") << FileName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RestrictSystemLibcHeadersCheck::registerPPCallbacks(
|
||||||
|
const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
|
||||||
|
SmallString<128> CompilerIncudeDir =
|
||||||
|
StringRef(PP->getHeaderSearchInfo().getHeaderSearchOpts().ResourceDir);
|
||||||
|
llvm::sys::path::append(CompilerIncudeDir, "include");
|
||||||
|
PP->addPPCallbacks(std::make_unique<RestrictedIncludesPPCallbacks>(
|
||||||
|
*this, SM, CompilerIncudeDir));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace llvm_libc
|
||||||
|
} // namespace tidy
|
||||||
|
} // namespace clang
|
@ -0,0 +1,35 @@
|
|||||||
|
//===--- RestrictSystemLibcHeadersCheck.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_LLVMLIBC_RESTRICTSYSTEMLIBCHEADERSCHECK_H
|
||||||
|
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVMLIBC_RESTRICTSYSTEMLIBCHEADERSCHECK_H
|
||||||
|
|
||||||
|
#include "../ClangTidyCheck.h"
|
||||||
|
|
||||||
|
namespace clang {
|
||||||
|
namespace tidy {
|
||||||
|
namespace llvm_libc {
|
||||||
|
|
||||||
|
/// Warns of accidental inclusions of system libc headers that aren't
|
||||||
|
/// compiler provided.
|
||||||
|
///
|
||||||
|
/// For the user-facing documentation see:
|
||||||
|
/// http://clang.llvm.org/extra/clang-tidy/checks/llvmlibc-restrict-system-libc-headers.html
|
||||||
|
class RestrictSystemLibcHeadersCheck : public ClangTidyCheck {
|
||||||
|
public:
|
||||||
|
RestrictSystemLibcHeadersCheck(StringRef Name, ClangTidyContext *Context)
|
||||||
|
: ClangTidyCheck(Name, Context) {}
|
||||||
|
void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
|
||||||
|
Preprocessor *ModuleExpanderPP) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace llvm_libc
|
||||||
|
} // namespace tidy
|
||||||
|
} // namespace clang
|
||||||
|
|
||||||
|
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVMLIBC_RESTRICTSYSTEMLIBCHEADERSCHECK_H
|
@ -67,6 +67,12 @@ The improvements are...
|
|||||||
Improvements to clang-tidy
|
Improvements to clang-tidy
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
|
New module
|
||||||
|
^^^^^^^^^^
|
||||||
|
- New module `llvmlibc`.
|
||||||
|
|
||||||
|
This module contains checks related to the LLVM-libc coding standards.
|
||||||
|
|
||||||
New checks
|
New checks
|
||||||
^^^^^^^^^^
|
^^^^^^^^^^
|
||||||
|
|
||||||
@ -95,6 +101,12 @@ New checks
|
|||||||
Flags use of the `C` standard library functions ``memset``, ``memcpy`` and
|
Flags use of the `C` standard library functions ``memset``, ``memcpy`` and
|
||||||
``memcmp`` and similar derivatives on non-trivial types.
|
``memcmp`` and similar derivatives on non-trivial types.
|
||||||
|
|
||||||
|
- New :doc:`llvmlibc-restrict-system-libc-headers
|
||||||
|
<clang-tidy/checks/llvmlibc-restrict-system-libc-headers>` check.
|
||||||
|
|
||||||
|
Finds includes of system libc headers not provided by the compiler within
|
||||||
|
llvm-libc implementations.
|
||||||
|
|
||||||
- New :doc:`objc-dealloc-in-category
|
- New :doc:`objc-dealloc-in-category
|
||||||
<clang-tidy/checks/objc-dealloc-in-category>` check.
|
<clang-tidy/checks/objc-dealloc-in-category>` check.
|
||||||
|
|
||||||
|
@ -187,6 +187,7 @@ Clang-Tidy Checks
|
|||||||
`llvm-prefer-isa-or-dyn-cast-in-conditionals <llvm-prefer-isa-or-dyn-cast-in-conditionals.html>`_, "Yes"
|
`llvm-prefer-isa-or-dyn-cast-in-conditionals <llvm-prefer-isa-or-dyn-cast-in-conditionals.html>`_, "Yes"
|
||||||
`llvm-prefer-register-over-unsigned <llvm-prefer-register-over-unsigned.html>`_, "Yes"
|
`llvm-prefer-register-over-unsigned <llvm-prefer-register-over-unsigned.html>`_, "Yes"
|
||||||
`llvm-twine-local <llvm-twine-local.html>`_, "Yes"
|
`llvm-twine-local <llvm-twine-local.html>`_, "Yes"
|
||||||
|
`llvmlibc-restrict-system-libc-headers <llvmlibc-restrict-system-libc-headers.html>`_,
|
||||||
`misc-definitions-in-headers <misc-definitions-in-headers.html>`_, "Yes"
|
`misc-definitions-in-headers <misc-definitions-in-headers.html>`_, "Yes"
|
||||||
`misc-misplaced-const <misc-misplaced-const.html>`_,
|
`misc-misplaced-const <misc-misplaced-const.html>`_,
|
||||||
`misc-new-delete-overloads <misc-new-delete-overloads.html>`_,
|
`misc-new-delete-overloads <misc-new-delete-overloads.html>`_,
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
.. title:: clang-tidy - llvmlibc-restrict-system-libc-headers
|
||||||
|
|
||||||
|
llvmlibc-restrict-system-libc-headers
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Finds includes of system libc headers not provided by the compiler within
|
||||||
|
llvm-libc implementations.
|
||||||
|
|
||||||
|
.. code-block:: c++
|
||||||
|
|
||||||
|
#include <stdio.h> // Not allowed because it is part of system libc.
|
||||||
|
#include <stddef.h> // Allowed because it is provided by the compiler.
|
||||||
|
#include "internal/stdio.h" // Allowed because it is NOT part of system libc.
|
||||||
|
|
||||||
|
|
||||||
|
This check is necessary because accidentally including system libc headers can
|
||||||
|
lead to subtle and hard to detect bugs. For example consider a system libc
|
||||||
|
whose ``dirent`` struct has slightly different field ordering than llvm-libc.
|
||||||
|
While this will compile successfully, this can cause issues during runtime
|
||||||
|
because they are ABI incompatible.
|
@ -68,6 +68,7 @@ Name prefix Description
|
|||||||
``google-`` Checks related to Google coding conventions.
|
``google-`` Checks related to Google coding conventions.
|
||||||
``hicpp-`` Checks related to High Integrity C++ Coding Standard.
|
``hicpp-`` Checks related to High Integrity C++ Coding Standard.
|
||||||
``llvm-`` Checks related to the LLVM 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.
|
``misc-`` Checks that we didn't have a better category for.
|
||||||
``modernize-`` Checks that advocate usage of modern (currently "modern"
|
``modernize-`` Checks that advocate usage of modern (currently "modern"
|
||||||
means "C++11") language constructs.
|
means "C++11") language constructs.
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
#include <math.h>
|
@ -0,0 +1,8 @@
|
|||||||
|
// RUN: %check_clang_tidy %s llvmlibc-restrict-system-libc-headers %t \
|
||||||
|
// RUN: -- -header-filter=.* \
|
||||||
|
// RUN: -- -I %S/Inputs/llvmlibc \
|
||||||
|
// RUN: -isystem %S/Inputs/llvmlibc/system \
|
||||||
|
// RUN: -resource-dir %S/Inputs/llvmlibc/resource
|
||||||
|
|
||||||
|
#include "transitive.h"
|
||||||
|
// CHECK-MESSAGES: :1:1: warning: system libc header math.h not allowed, transitively included from {{.*}}
|
@ -0,0 +1,13 @@
|
|||||||
|
// RUN: %check_clang_tidy %s llvmlibc-restrict-system-libc-headers %t \
|
||||||
|
// RUN: -- -- -isystem %S/Inputs/llvmlibc/system \
|
||||||
|
// RUN: -resource-dir %S/Inputs/llvmlibc/resource
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: system libc header stdio.h not allowed
|
||||||
|
#include <stdlib.h>
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: system libc header stdlib.h not allowed
|
||||||
|
#include "string.h"
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: system libc header string.h not allowed
|
||||||
|
#include "stdatomic.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
// Compiler provided headers should not throw warnings.
|
Loading…
Reference in New Issue
Block a user