Index: clang-tools-extra/clang-tidy/CMakeLists.txt =================================================================== --- clang-tools-extra/clang-tidy/CMakeLists.txt +++ clang-tools-extra/clang-tidy/CMakeLists.txt @@ -38,4 +38,5 @@ add_subdirectory(mpi) add_subdirectory(performance) add_subdirectory(readability) +add_subdirectory(safety) add_subdirectory(utils) Index: clang-tools-extra/clang-tidy/safety/CMakeLists.txt =================================================================== --- /dev/null +++ clang-tools-extra/clang-tidy/safety/CMakeLists.txt @@ -0,0 +1,14 @@ +set(LLVM_LINK_COMPONENTS support) + +add_clang_library(clangTidySafetyModule + NoAssemblerCheck.cpp + SafetyTidyModule.cpp + + LINK_LIBS + clangAST + clangASTMatchers + clangBasic + clangLex + clangTidy + clangTidyUtils + ) Index: clang-tools-extra/clang-tidy/safety/NoAssemblerCheck.h =================================================================== --- /dev/null +++ clang-tools-extra/clang-tidy/safety/NoAssemblerCheck.h @@ -0,0 +1,35 @@ +//===--- NoAssemblerCheck.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_SAFETY_NO_ASSEMBLER_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_SAFETY_NO_ASSEMBLER_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { +namespace safety { + +/// Find assembler statements. No fix is offered. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/safety-no-assembler.html +class NoAssemblerCheck : public ClangTidyCheck { +public: + NoAssemblerCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; +}; + +} // namespace safety +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_SAFETY_NO_ASSEMBLER_H Index: clang-tools-extra/clang-tidy/safety/NoAssemblerCheck.cpp =================================================================== --- /dev/null +++ clang-tools-extra/clang-tidy/safety/NoAssemblerCheck.cpp @@ -0,0 +1,37 @@ +//===--- NoAssemblerCheck.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 "NoAssemblerCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace safety { + +void NoAssemblerCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(asmStmt().bind("asm"), this); +} + +void NoAssemblerCheck::check(const MatchFinder::MatchResult &Result) { + const auto *ASM = Result.Nodes.getNodeAs<AsmStmt>("asm"); + + StringRef SourceText = Lexer::getSourceText( + CharSourceRange::getTokenRange(ASM->getSourceRange()), + *Result.SourceManager, getLangOpts()); + + diag(ASM->getAsmLoc(), "'%0' is an inline assembler statement") << SourceText; +} + +} // namespace safety +} // namespace tidy +} // namespace clang Index: clang-tools-extra/clang-tidy/safety/SafetyTidyModule.cpp =================================================================== --- /dev/null +++ clang-tools-extra/clang-tidy/safety/SafetyTidyModule.cpp @@ -0,0 +1,38 @@ +//===------- SafetyTidyModule.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 "../ClangTidy.h" +#include "../ClangTidyModule.h" +#include "../ClangTidyModuleRegistry.h" +#include "NoAssemblerCheck.h" + +namespace clang { +namespace tidy { +namespace safety { + +class SafetyModule : public ClangTidyModule { +public: + void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { + CheckFactories.registerCheck<NoAssemblerCheck>( + "safety-no-assembler"); + } +}; + +// Register the SafetyModule using this statically initialized variable. +static ClangTidyModuleRegistry::Add<SafetyModule> + X("safety-module", "Adds safety-critical checks."); + +} // namespace safety + +// This anchor is used to force the linker to link in the generated object file +// and thus register the SafetyModule. +volatile int SafetyModuleAnchorSource = 0; + +} // namespace tidy +} // namespace clang Index: clang-tools-extra/clang-tidy/tool/CMakeLists.txt =================================================================== --- clang-tools-extra/clang-tidy/tool/CMakeLists.txt +++ clang-tools-extra/clang-tidy/tool/CMakeLists.txt @@ -23,6 +23,7 @@ clangTidyMPIModule clangTidyPerformanceModule clangTidyReadabilityModule + clangTidySafetyModule clangTooling ) Index: clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp =================================================================== --- clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp +++ clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp @@ -475,6 +475,11 @@ static int LLVM_ATTRIBUTE_UNUSED ReadabilityModuleAnchorDestination = ReadabilityModuleAnchorSource; +// This anchor is used to force the linker to link the SafetyModule. +extern volatile int SafetyModuleAnchorSource; +static int LLVM_ATTRIBUTE_UNUSED SafetyModuleAnchorDestination = + SafetyModuleAnchorSource; + } // namespace tidy } // namespace clang Index: clang-tools-extra/docs/ReleaseNotes.rst =================================================================== --- clang-tools-extra/docs/ReleaseNotes.rst +++ clang-tools-extra/docs/ReleaseNotes.rst @@ -57,7 +57,10 @@ Improvements to clang-tidy -------------------------- -The improvements are... +- New `safety-no-assembler + <http://clang.llvm.org/extra/clang-tidy/checks/safety-no-assembler.html>`_ check + + Finds uses of inline assembler. Improvements to include-fixer ----------------------------- Index: clang-tools-extra/docs/clang-tidy/checks/list.rst =================================================================== --- clang-tools-extra/docs/clang-tidy/checks/list.rst +++ clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -152,3 +152,5 @@ readability-simplify-boolean-expr readability-static-definition-in-anonymous-namespace readability-uniqueptr-delete-release + safety-no-assembler + safety-no-vector-bool Index: clang-tools-extra/docs/clang-tidy/checks/safety-no-assembler.rst =================================================================== --- /dev/null +++ clang-tools-extra/docs/clang-tidy/checks/safety-no-assembler.rst @@ -0,0 +1,10 @@ +.. title:: clang-tidy - safety-no-assembler + +safety-no-assembler +=================== + +Check for assembler statements. No fix is offered. + +Inline assembler is forbidden by safety-critical C++ standards like `High +Intergrity C++ <http://www.codingstandard.com>`_ as it restricts the +portability of code. Index: clang-tools-extra/test/clang-tidy/safety-no-assembler.cpp =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/safety-no-assembler.cpp @@ -0,0 +1,7 @@ +// RUN: %check_clang_tidy %s safety-no-assembler %t + +void f() { + __asm("mov al, 2"); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: '__asm("mov al, 2")' is an inline assembler statement [safety-no-assembler] +} +