llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-tools-extra Author: Csaba Zeitvogel (zeitcsabi) <details> <summary>Changes</summary> This simple check is based on the cerrno portion of MSC38-C. --- Full diff: https://github.com/llvm/llvm-project/pull/213015.diff 8 Files Affected: - (modified) clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp (+3) - (modified) clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt (+1) - (added) clang-tools-extra/clang-tidy/bugprone/CerrnoCheck.cpp (+38) - (added) clang-tools-extra/clang-tidy/bugprone/CerrnoCheck.h (+35) - (modified) clang-tools-extra/docs/ReleaseNotes.rst (+5) - (added) clang-tools-extra/docs/clang-tidy/checks/bugprone/cerrno.rst (+17) - (modified) clang-tools-extra/docs/clang-tidy/checks/list.rst (+1) - (added) clang-tools-extra/test/clang-tidy/checkers/bugprone/cerrno.cpp (+25) ``````````diff diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp index 3aa39d10ceb5d..54f0e7345ff97 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -18,6 +18,7 @@ #include "BranchCloneCheck.h" #include "CapturingThisInMemberVariableCheck.h" #include "CastingThroughVoidCheck.h" +#include "CerrnoCheck.h" #include "ChainedComparisonCheck.h" #include "CommandProcessorCheck.h" #include "ComparePointerToMemberVirtualFunctionCheck.h" @@ -144,6 +145,8 @@ class BugproneModule : public ClangTidyModule { "bugprone-capturing-this-in-member-variable"); CheckFactories.registerCheck<CastingThroughVoidCheck>( "bugprone-casting-through-void"); + CheckFactories.registerCheck<CerrnoCheck>( + "bugprone-cerrno"); CheckFactories.registerCheck<ChainedComparisonCheck>( "bugprone-chained-comparison"); CheckFactories.registerCheck<CommandProcessorCheck>( diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index 43e85b1407f21..6345e61b3b126 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -15,6 +15,7 @@ add_clang_library(clangTidyBugproneModule STATIC BugproneTidyModule.cpp CapturingThisInMemberVariableCheck.cpp CastingThroughVoidCheck.cpp + CerrnoCheck.cpp ChainedComparisonCheck.cpp CommandProcessorCheck.cpp ComparePointerToMemberVirtualFunctionCheck.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/CerrnoCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/CerrnoCheck.cpp new file mode 100644 index 0000000000000..8dbb685662084 --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/CerrnoCheck.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// 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 "CerrnoCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +void CerrnoCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(varDecl(hasType(asString("int")), hasName("errno"), hasExternalFormalLinkage()).bind("errnoDecl"), this); +} + +void CerrnoCheck::check(const MatchFinder::MatchResult &Result) { + const auto *MatchedDecl = Result.Nodes.getNodeAs<VarDecl>("errnoDecl"); // NULL? + const SourceManager &SM = *Result.SourceManager; + const auto Location = MatchedDecl->getLocation(); + const auto FileID = SM.getFileID(Location); + + unsigned Line = SM.getSpellingLineNumber(MatchedDecl->getBeginLoc()); + + const auto Diag = diag(Location, "errno declaration detected, include cerrno instead") + << FixItHint::CreateRemoval(CharSourceRange::getCharRange(SM.translateLineCol(FileID, Line, 1), SM.translateLineCol(FileID, Line + 1, 1))); + + if (alreadyInserted) + return; + + Diag << FixItHint::CreateInsertion(SM.getLocForStartOfFile(FileID), "#include <cerrno>\n"); + alreadyInserted = true; +} + +} // namespace clang::tidy::bugprone diff --git a/clang-tools-extra/clang-tidy/bugprone/CerrnoCheck.h b/clang-tools-extra/clang-tidy/bugprone/CerrnoCheck.h new file mode 100644 index 0000000000000..7517acd28a49f --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/CerrnoCheck.h @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// 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_BUGPRONE_CERRNOCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_CERRNOCHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang::tidy::bugprone { + +/// Warns if you declare an extern int variable named 'errno'. +/// +/// For the user-facing documentation see: +/// https://clang.llvm.org/extra/clang-tidy/checks/bugprone/cerrno.html +class CerrnoCheck : public ClangTidyCheck { +public: + CerrnoCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus; + } +private: + bool alreadyInserted = false; +}; + +} // namespace clang::tidy::bugprone + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_CERRNOCHECK_H diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 2581a9d3c5657..e3a19dffc931a 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -224,6 +224,11 @@ New checks Finds assignments within selection statements. +- New :doc:`bugprone-cerrno + <clang-tidy/checks/bugprone/cerrno>` check. + + Warns if you declare an extern int variable named 'errno'. + - New :doc:`bugprone-missing-end-comparison <clang-tidy/checks/bugprone/missing-end-comparison>` check. diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/cerrno.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/cerrno.rst new file mode 100644 index 0000000000000..73ec1c76901af --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/cerrno.rst @@ -0,0 +1,17 @@ +.. title:: clang-tidy - bugprone-cerrno + +bugprone-cerrno +=============== + +Warns if you declare an ``extern int`` variable named ``errno`` instead of including ``<cerrno>``. +It is able to fix the problem by removing the line of the declaration and inserting ``#include <cerrno>`` +at the top of the file. + +For further reading, see `the page of SEI CERT C Coding Standard +<https://cmu-sei.github.io/secure-coding-standards/sei-cert-c-coding-standard/rules/miscellaneous-msc/msc38-c/>`_. + +Example: + +.. code-block:: c++ + + extern int errno; diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index 2a44dc78fbc89..355401cbdccc6 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -87,6 +87,7 @@ Clang-Tidy Checks :doc:`bugprone-branch-clone <bugprone/branch-clone>`, :doc:`bugprone-capturing-this-in-member-variable <bugprone/capturing-this-in-member-variable>`, :doc:`bugprone-casting-through-void <bugprone/casting-through-void>`, + :doc:`bugprone-cerrno <bugprone/cerrno>`, "Yes" :doc:`bugprone-chained-comparison <bugprone/chained-comparison>`, :doc:`bugprone-command-processor <bugprone/command-processor>`, :doc:`bugprone-compare-pointer-to-member-virtual-function <bugprone/compare-pointer-to-member-virtual-function>`, diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/cerrno.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/cerrno.cpp new file mode 100644 index 0000000000000..40109d31aa26b --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/cerrno.cpp @@ -0,0 +1,25 @@ +// RUN: %check_clang_tidy %s bugprone-cerrno %t + +namespace cerrno_test_0 { + extern int errno; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: errno declaration detected, include cerrno instead [bugprone-cerrno] + // CHECK-FIXES: {{^}}{{$}} +} // namespace cerrno_test_0 + +namespace cerrno_test_1 { + extern "C" int errno; + // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: errno declaration detected, include cerrno instead [bugprone-cerrno] + // CHECK-FIXES: {{^}}{{$}} +} // namespace cerrno_test_1 + +namespace cerrno_test_2 { // all cases should be ignored in this namespace + extern bool errno; + + void foo(int errno) {} + + int fooo() + { + int errno = 0; + return errno; + } +} // namespace cerrno_test_2 `````````` </details> https://github.com/llvm/llvm-project/pull/213015 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
