ktomi996 updated this revision to Diff 303633.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D91000/new/
https://reviews.llvm.org/D91000
Files:
clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
clang-tools-extra/clang-tidy/cert/CMakeLists.txt
clang-tools-extra/clang-tidy/cert/ObsolescentFunctionsCheck.cpp
clang-tools-extra/clang-tidy/cert/ObsolescentFunctionsCheck.h
clang-tools-extra/docs/ReleaseNotes.rst
clang-tools-extra/docs/clang-tidy/checks/cert-obsolescent-functions.rst
clang-tools-extra/docs/clang-tidy/checks/list.rst
clang-tools-extra/test/clang-tidy/cert-obsolescent-functions.cpp
Index: clang-tools-extra/test/clang-tidy/cert-obsolescent-functions.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/cert-obsolescent-functions.cpp
@@ -0,0 +1,17 @@
+// RUN: %check_clang_tidy %s cert-obsolescent-functions %t --
+
+#define __STDC_LIB_EXT1__
+#define __STDC_WANT_LIB_EXT1__ 1
+void * memmove(void *, void *, unsigned int);
+void f1(const char *in) {
+ int i = 1;
+ int j = 2;
+ memmove(&i, &j, sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: Unsafe function memmove used. Safe memmove_s can be used instead. [cert-obsolescent-functions]
+}
+
+
+void f2(const char *in) {
+ void * (*func_ptr)(void *, void *, unsigned int) = memmove;
+// CHECK-MESSAGES: :[[@LINE-1]]:56: warning: Unsafe function memmove used. Safe memmove_s can be used instead. [cert-obsolescent-functions]
+}
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
@@ -100,6 +100,7 @@
cert-msc32-c (redirects to cert-msc51-cpp) <cert-msc32-c>
cert-msc50-cpp
cert-msc51-cpp
+ cert-obsolescent-functions
cert-oop11-cpp (redirects to performance-move-constructor-init) <cert-oop11-cpp>
cert-oop54-cpp (redirects to bugprone-unhandled-self-assignment) <cert-oop54-cpp>
cppcoreguidelines-avoid-c-arrays (redirects to modernize-avoid-c-arrays) <cppcoreguidelines-avoid-c-arrays>
Index: clang-tools-extra/docs/clang-tidy/checks/cert-obsolescent-functions.rst
===================================================================
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/cert-obsolescent-functions.rst
@@ -0,0 +1,23 @@
+..title::clang-tidy-cert-obsolescent-functions
+
+cert-obsolescent-functions
+==========================
+
+Guards against using some unsafe function calls and function pointers which initialized with unsafe functions if __STDC_LIB_EXT1__ macro is defined and the value of __STDC_WANT_LIB_EXT1__ is 1. The usage of following functions are checked : bsearch,
+ fprintf, fscanf, fwprintf, fwscanf, getenv, gmtime, localtime, mbsrtowcs,
+ mbstowcs, memcpy, memmove, printf, qsort, setbuf, snprintf, sprintf, sscanf,
+ strcat, strcpy, strerror, strncat, strncpy, strtok, swprintf, swscanf,
+ vfprintf, vfscanf, vfwprintf, vfwscanf, vprintf, vscanf vsnprintf, vspr,
+ wcscpy, wcsncat, wcsncpy wcsrtombs, wcstok, wcstombs, wctomb, wmemcpy,
+ wmemmove, wprintf, wscanf,
+ strlen
+
+This is a CERT security rule:
+https://wiki.sei.cmu.edu/confluence/display/c/MSC24-C.+Do+not+use+deprecated+or+obsolescent+functions
+ Example :
+ .code-block::
+ #define __STDC_WANT_LIB_EXT1__ 1
+ int i = 2;
+ int j = 3;
+ memmove(&i, &j, sizeof(int)); // diagnosed if __STDC_LIB_EXT1__ is defined in a
+ // header, memmove_s usage is suggested instead.
Index: clang-tools-extra/docs/ReleaseNotes.rst
===================================================================
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -194,6 +194,13 @@
against self-assignment either by checking self-assignment explicitly or
using the copy-and-swap or the copy-and-move method.
+- New :doc:`cert-obsolescent-functions
+ <clang-tidy/checks/cert-obsolescent-functions>` check.
+
+ Guards against using some unsafe function calls and function pointers which
+ initialized with unsafe functions if some macros defined.
+
+
- New :doc:`fuchsia-default-arguments-calls
<clang-tidy/checks/fuchsia-default-arguments-calls>` check.
Index: clang-tools-extra/clang-tidy/cert/ObsolescentFunctionsCheck.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/cert/ObsolescentFunctionsCheck.h
@@ -0,0 +1,36 @@
+//===--- ObsolescentFunctionsCheck.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_CERT_OBSOLESCENTFUNCTIONSCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_OBSOLESCENTFUNCTIONSCHECK_H
+
+#include "../ClangTidyCheck.h"
+namespace clang {
+namespace tidy {
+namespace cert {
+
+/// Guards against using some unsafe function calls and function pointers which initialized with unsafe functions if some macros defined.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/cert-obsolescent-functions.html
+class ObsolescentFunctionsCheck : public ClangTidyCheck {
+public:
+ ObsolescentFunctionsCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+ const std::pair<bool, bool> UsingAnnexK();
+ void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+ Preprocessor *ModuleExpandedPP) override;
+};
+
+} // namespace cert
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_OBSOLESCENTFUNCTIONSCHECK_H
Index: clang-tools-extra/clang-tidy/cert/ObsolescentFunctionsCheck.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/cert/ObsolescentFunctionsCheck.cpp
@@ -0,0 +1,103 @@
+//===--- ObsolescentFunctionsCheck.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 "ObsolescentFunctionsCheck.h"
+#include "clang/Lex/Preprocessor.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace cert {
+
+namespace {
+static Preprocessor *PP;
+}
+
+void ObsolescentFunctionsCheck::registerMatchers(MatchFinder *Finder) {
+ const auto CheckedFunctions = functionDecl(hasAnyName(
+ "::bsearch", "::fprintf", "::fscanf", "::fwprintf", "::fwscanf",
+ "::getenv", "::gmtime", "::localtime", "::mbsrtowcs", "::mbstowcs",
+ "::memcpy", "::memmove", "::printf", "::qsort", "::setbuf", "::snprintf",
+ "::sprintf", "::sscanf", "::strcat", "::strcpy", "::strerror",
+ "::strncat", "::strncpy", "::strtok", "::swprintf", "::swscanf",
+ "::vfprintf", "::vfscanf", "vfwprintf", "vfwscanf", "vprintf", "::vscanf",
+ "::vsnprintf", "::vsprintf", "::vsscanf", "::vswprintf", "::vswcanf",
+ "::wcrtomb", "::wcscat", "::wcscpy", "::wcsncat", "::wcsncpy",
+ "::wcsrtombs", "::wcstok", "::wcstombs", "::wctomb", "::wmemcpy",
+ "::wmemmove", "::wprintf", "::wscanf", "::strlen"));
+ Finder->addMatcher(
+ callExpr(callee(CheckedFunctions.bind("fn"))).bind("callexpr"), this);
+
+ Finder->addMatcher(varDecl(hasInitializer(ignoringImpCasts(declRefExpr(
+ to(CheckedFunctions.bind("fnp"))))))
+ .bind("fp"),
+ this);
+}
+
+void ObsolescentFunctionsCheck::registerPPCallbacks(
+ const SourceManager &SM, Preprocessor *Preproc,
+ Preprocessor *ModuleExpandedPP) {
+ PP = Preproc;
+}
+
+const std::pair<bool, bool> ObsolescentFunctionsCheck::UsingAnnexK() {
+ bool AnnexKIsAvailable;
+ bool AnnexKIsWanted;
+ if (!PP->isMacroDefined("__STDC_LIB_EXT1__")) {
+ AnnexKIsAvailable = false;
+ } else {
+ AnnexKIsAvailable = true;
+ }
+ const IdentifierInfo *Id = PP->getIdentifierInfo("__STDC_WANT_LIB_EXT1__");
+ AnnexKIsWanted = false;
+ if (!Id) {
+ AnnexKIsWanted = false;
+ } else {
+ const auto *MI = PP->getMacroInfo(Id);
+ const auto &T = MI->tokens().back();
+ StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength());
+ llvm::APInt IntValue;
+ ValueStr.getAsInteger(10, IntValue);
+ Optional<bool> AreSafeFunctionsWanted;
+ AreSafeFunctionsWanted = IntValue.getZExtValue();
+ if (AreSafeFunctionsWanted.hasValue()) {
+ AnnexKIsWanted = AreSafeFunctionsWanted.getValue();
+ }
+ }
+ return std::make_pair(AnnexKIsAvailable, AnnexKIsWanted);
+}
+
+void ObsolescentFunctionsCheck::check(const MatchFinder::MatchResult &Result) {
+ std::pair<bool, bool> AnnexKUsage = UsingAnnexK();
+ bool AnnexKIsAvailable = std::get<0>(AnnexKUsage);
+ bool AnnexKIsWanted = std::get<1>(AnnexKUsage);
+ if (!AnnexKIsWanted || !AnnexKIsAvailable) {
+ return;
+ }
+ if (const auto *Function = Result.Nodes.getNodeAs<CallExpr>("callexpr")) {
+ const FunctionDecl *FD = Result.Nodes.getNodeAs<FunctionDecl>("fn");
+ const NamedDecl *NFD = dyn_cast<NamedDecl>(FD);
+ std::string FunctionName = NFD->getNameAsString();
+ diag(Function->getExprLoc(), "Unsafe function " + FunctionName + " used. " +
+ "Safe " + FunctionName +
+ "_s can be used instead.");
+ }
+ if (const auto *FunctionPointer = Result.Nodes.getNodeAs<VarDecl>("fp")) {
+ if (const FunctionDecl *FD = Result.Nodes.getNodeAs<FunctionDecl>("fnp")) {
+ const NamedDecl *NFD = dyn_cast<NamedDecl>(FD);
+ std::string FunctionName = NFD->getNameAsString();
+ diag(FunctionPointer->getEndLoc(),
+ "Unsafe function " + FunctionName + " used. " + "Safe " +
+ FunctionName + "_s can be used instead.");
+ }
+ }
+}
+} // namespace cert
+} // namespace tidy
+} // namespace clang
Index: clang-tools-extra/clang-tidy/cert/CMakeLists.txt
===================================================================
--- clang-tools-extra/clang-tidy/cert/CMakeLists.txt
+++ clang-tools-extra/clang-tidy/cert/CMakeLists.txt
@@ -6,6 +6,7 @@
DontModifyStdNamespaceCheck.cpp
FloatLoopCounter.cpp
LimitedRandomnessCheck.cpp
+ ObsolescentFunctionsCheck.cpp
PostfixOperatorCheck.cpp
ProperlySeededRandomGeneratorCheck.cpp
SetLongJmpCheck.cpp
Index: clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
===================================================================
--- clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
+++ clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
@@ -21,6 +21,7 @@
#include "DontModifyStdNamespaceCheck.h"
#include "FloatLoopCounter.h"
#include "LimitedRandomnessCheck.h"
+#include "ObsolescentFunctionsCheck.h"
#include "PostfixOperatorCheck.h"
#include "ProperlySeededRandomGeneratorCheck.h"
#include "SetLongJmpCheck.h"
@@ -79,6 +80,8 @@
// ERR
CheckFactories.registerCheck<StrToNumCheck>("cert-err34-c");
// MSC
+ CheckFactories.registerCheck<ObsolescentFunctionsCheck>(
+ "cert-obsolescent-functions");
CheckFactories.registerCheck<LimitedRandomnessCheck>("cert-msc30-c");
CheckFactories.registerCheck<ProperlySeededRandomGeneratorCheck>(
"cert-msc32-c");
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits