futogergely updated this revision to Diff 390270.
futogergely retitled this revision from "[clang-tidy] CERT MSC24-C Obsolescent 
Functions check" to "[clang-tidy] Add cert-msc24-c checker.".
futogergely edited the summary of this revision.

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-msc24-c.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/test/clang-tidy/checkers/cert-msc24-c.c

Index: clang-tools-extra/test/clang-tidy/checkers/cert-msc24-c.c
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cert-msc24-c.c
@@ -0,0 +1,96 @@
+// RUN: %check_clang_tidy -check-suffix=WITH-ANNEX-K    %s cert-msc24-c %t -- -- -D__STDC_LIB_EXT1__=1 -D__STDC_WANT_LIB_EXT1__=1
+// RUN: %check_clang_tidy -check-suffix=WITHOUT-ANNEX-K %s cert-msc24-c %t -- -- -U__STDC_LIB_EXT1__   -U__STDC_WANT_LIB_EXT1__
+// RUN: %check_clang_tidy -check-suffix=WITHOUT-ANNEX-K %s cert-msc24-c %t -- -- -D__STDC_LIB_EXT1__=1 -U__STDC_WANT_LIB_EXT1__
+// RUN: %check_clang_tidy -check-suffix=WITHOUT-ANNEX-K %s cert-msc24-c %t -- -- -U__STDC_LIB_EXT1__   -D__STDC_WANT_LIB_EXT1__=1
+
+typedef void *FILE;
+char *gets(char *s);
+void rewind(FILE *stream);
+void setbuf(FILE *stream, char *buf);
+
+void f1(char *s, FILE *f) {
+  gets(s);
+  // CHECK-MESSAGES-WITH-ANNEX-K:    :[[@LINE-1]]:3: warning: function 'gets' is deprecated as of C99, removed from C11.
+  // CHECK-MESSAGES-WITHOUT-ANNEX-K: :[[@LINE-2]]:3: warning: function 'gets' is deprecated as of C99, removed from C11.
+
+  rewind(f);
+  // CHECK-MESSAGES-WITH-ANNEX-K:    :[[@LINE-1]]:3: warning: function 'rewind' has no error detection; 'fseek' should be used instead.
+  // CHECK-MESSAGES-WITHOUT-ANNEX-K: :[[@LINE-2]]:3: warning: function 'rewind' has no error detection; 'fseek' should be used instead.
+
+  setbuf(f, s);
+  // CHECK-MESSAGES-WITH-ANNEX-K:    :[[@LINE-1]]:3: warning: function 'setbuf' has no error detection; 'setvbuf' should be used instead.
+  // CHECK-MESSAGES-WITHOUT-ANNEX-K: :[[@LINE-2]]:3: warning: function 'setbuf' has no error detection; 'setvbuf' should be used instead.
+}
+
+struct tm;
+char *asctime(const struct tm *timeptr);
+
+void f2(const struct tm *timeptr) {
+  asctime(timeptr);
+  // CHECK-MESSAGES-WITH-ANNEX-K: :[[@LINE-1]]:3: warning: function 'asctime' is non-reentrant; 'asctime_s' should be used instead.
+  // no-warning WITHOUT-ANNEX-K
+
+  char *(*f_ptr1)(const struct tm *) = asctime;
+  // CHECK-MESSAGES-WITH-ANNEX-K: :[[@LINE-1]]:40: warning: function 'asctime' is non-reentrant; 'asctime_s' should be used instead.
+  // no-warning WITHOUT-ANNEX-K
+
+  char *(*f_ptr2)(const struct tm *) = &asctime;
+  // CHECK-MESSAGES-WITH-ANNEX-K: :[[@LINE-1]]:41: warning: function 'asctime' is non-reentrant; 'asctime_s' should be used instead.
+  // no-warning WITHOUT-ANNEX-K
+}
+
+FILE *fopen(const char *filename, const char *mode);
+FILE *freopen(const char *filename, const char *mode, FILE *stream);
+int fscanf(FILE *stream, const char *format, ...);
+
+void f3(char *s, FILE *f) {
+  fopen(s, s);
+  // CHECK-MESSAGES-WITH-ANNEX-K: :[[@LINE-1]]:3: warning: function 'fopen' has no exclusive access to file; 'fopen_s' should be used instead.
+  // no-warning WITHOUT-ANNEX-K
+
+  freopen(s, s, f);
+  // CHECK-MESSAGES-WITH-ANNEX-K: :[[@LINE-1]]:3: warning: function 'freopen' has no exclusive access to file; 'freopen_s' should be used instead.
+  // no-warning WITHOUT-ANNEX-K
+
+  int i;
+  fscanf(f, "%d", &i);
+  // CHECK-MESSAGES-WITH-ANNEX-K: :[[@LINE-1]]:3: warning: function 'fscanf' is obsolescent; 'fscanf_s' should be used instead.
+  // no-warning WITHOUT-ANNEX-K
+}
+
+typedef int time_t;
+char *ctime(const time_t *timer);
+
+void f4(const time_t *timer) {
+  ctime(timer);
+  // CHECK-MESSAGES-WITH-ANNEX-K: :[[@LINE-1]]:3: warning: function 'ctime' is non-reentrant; 'ctime_s' should be used instead.
+  // no-warning WITHOUT-ANNEX-K
+}
+
+typedef int errno_t;
+typedef size_t rsize_t;
+errno_t asctime_s(char *s, rsize_t maxsize, const struct tm *timeptr);
+errno_t strcat_s(char *s1, rsize_t s1max, const char *s2);
+int fseek(FILE *stream, long int offset, int whence);
+int setvbuf(FILE *stream, char *buf, int mode, size_t size);
+
+void fUsingSafeFunctions(const struct tm *timeptr, FILE *f) {
+  const size_t BUFFSIZE = 32;
+  char buf[BUFFSIZE] = {0};
+
+  // no-warning, safe function from annex K is used
+  if (asctime_s(buf, BUFFSIZE, timeptr) != 0)
+    return;
+
+  // no-warning, safe function from annex K is used
+  if (strcat_s(buf, BUFFSIZE, "something") != 0)
+    return;
+
+  // no-warning, fseeks supports error checking
+  if (fseek(f, 0, 0) != 0)
+    return;
+
+  // no-warning, setvbuf supports error checking
+  if (setvbuf(f, buf, 0, BUFFSIZE) != 0)
+    return;
+}
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
@@ -123,6 +123,7 @@
    `cert-flp30-c <cert-flp30-c.html>`_,
    `cert-flp37-c <cert-flp37-c.html>`_,
    `cert-mem57-cpp <cert-mem57-cpp.html>`_,
+   `cert-msc24-c <cert-msc24-c.html>`_,
    `cert-msc50-cpp <cert-msc50-cpp.html>`_,
    `cert-msc51-cpp <cert-msc51-cpp.html>`_,
    `cert-oop57-cpp <cert-oop57-cpp.html>`_,
Index: clang-tools-extra/docs/clang-tidy/checks/cert-msc24-c.rst
===================================================================
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/cert-msc24-c.rst
@@ -0,0 +1,91 @@
+.. title:: clang-tidy - cert-msc24-c
+
+cert-msc24-c
+============
+
+Checks for deprecated and obsolescent functions listed in
+CERT C Coding Standard Recommendation MSC24-C (`MSC24-C. Do not use deprecated or obsolescent functions
+<https://wiki.sei.cmu.edu/confluence/display/c/MSC24-C.+Do+not+use+deprecated+or+obsolescent+functions>`_.).
+For the listed functions, an alternative, more secure replacement is suggested, if available.
+The checker heavily relies on the functions from annex K (Bounds-checking interfaces) of C11.
+
+For the following functions, replacement is suggested from annex K: `asctime`, 
+`ctime`, `fopen`, `freopen`, `bsearch`, `fprintf`, `fscanf`, `fwprintf`, `fwscanf`, 
+`getenv`, `gmtime`, `localtime`, `mbsrtowcs`, `mbstowcs`, `memcpy`, `memmove`, `printf`, 
+`qsort`, `snprintf`, `sprintf`,  `sscanf`, `strcat`, `strcpy`, `strerror`, 
+`strncat`, `strncpy`, `strtok`, `swprintf`, `swscanf`, `vfprintf`, `vfscanf`, `vfwprintf`, 
+`vfwscanf`, `vprintf`, `vscanf`, `vsnprintf`, `vsprintf`, `vsscanf`, `vswprintf`, 
+`vswscanf`, `vwprintf`, `vwscanf`, `wcrtomb`, `wcscat`, `wcscpy`, `wcsncat`, `wcsncpy`, 
+`wcsrtombs`, `wcstok`, `wcstombs`, `wctomb`, `wmemcpy`, `wmemmove`, `wprintf`, `wscanf`. 
+If annex K is not available, the checker ignores these functions.
+
+The availability of annex K is checked based on the following macros.
+ - `__STDC_LIB_EXT1__`: feature macro, which indicates the presence of
+   annex K (Bounds-checking interfaces) in the library implementation
+ - `__STDC_WANT_LIB_EXT1__`: user defined macro, which indicates if the user wants the functions from
+   annex K to be defined.
+
+Both macros have to be defined to suggest replacement functions from annex K. `__STDC_LIB_EXT1__` is
+defined by the library implementation, and `__STDC_WANT_LIB_EXT1__` must be define to "1" by the user 
+before including any system headers.
+
+Deprecated function `gets` is checked, and a warning is issued if used.
+
+The following functions are also checked, and an alternative replacement function is suggested:
+ - `rewind`, suggested replacement: `fseek`
+ - `setbuf`, suggested replacement: `setvbuf`
+
+The following functions are covered in the check `cert-err34-c <cert-err34-c.html>`_,
+so this checker **ignores** them: `atof`, `atoi`, `atol`, `atoll`.
+
+Examples:
+
+.. code-block:: c++
+  
+  //__STDC_LIB_EXT1__ is defined by the library implementation
+  #define __STDC_WANT_LIB_EXT1__ 1
+
+  #include <string.h> // defines the functions from annex K
+  #include <stdio.h>
+  
+  enum { BUFSIZE = 32 };
+
+  void fWarning(const char *msg) { 
+    static const char prefix[] = "Error: ";
+    static const char suffix[] = "\n";
+    char buf[BUFSIZE] = {0}; 
+    
+    strcpy(buf, prefix); // warning: function 'strcpy' is obsolescent; 'strcpy_s' should be used instead.
+    strcat(buf, msg); // warning: function 'strcat' is obsolescent; 'strcat_s' should be used instead.
+    strcat(buf, suffix); // warning: function 'strcat' is obsolescent; 'strcat_s' should be used instead.
+    if (fputs(buf, stderr) < 0) {
+      // error handling
+      return;
+    }
+  }
+
+  void fUsingSafeFunctions(const char *msg) { 
+    static const char prefix[] = "Error: ";
+    static const char suffix[] = "\n";
+    char buf[BUFSIZE] = {0}; 
+    
+    if (strcpy_s(buf, prefix) != 0) {
+      // error handling
+      return;
+    }
+
+    if (strcat_s(buf, msg) != 0) {
+      // error handling
+      return;
+    }
+    
+    if (strcat_s(buf, suffix) != 0) {
+      // error handling
+      return;
+    }
+    
+    if (fputs(buf, stderr) < 0) {
+      // error handling
+      return;
+    }
+  }
Index: clang-tools-extra/docs/ReleaseNotes.rst
===================================================================
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -89,6 +89,14 @@
   Finds potentially incorrect calls to ``memcmp()`` based on properties of the
   arguments.
 
+- New :doc:`cert-msc24-c
+  <clang-tidy/checks/cert-msc24-c>` check.
+
+  Checks for deprecated and obsolescent functions listed in
+  CERT C Coding Standard Recommendation MSC24-C. For the listed functions,
+  an alternative, more secure replacement is suggested, if available. The checker heavily
+  relies on the functions from annex K (Bounds-checking interfaces) of C11.
+
 - New :doc:`cppcoreguidelines-virtual-class-destructor
   <clang-tidy/checks/cppcoreguidelines-virtual-class-destructor>` check.
 
Index: clang-tools-extra/clang-tidy/cert/ObsolescentFunctionsCheck.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/cert/ObsolescentFunctionsCheck.h
@@ -0,0 +1,50 @@
+//===--- 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 {
+
+/// Checks for deprecated and obsolescent function listed in
+/// CERT C Coding Standard Recommendation MSC24 - C. For the listed functions,
+/// an alternative, safe replacement is suggested if available.
+/// The checker heavily relies on the availability of annexK(Bounds - checking
+/// interfaces) from C11. For the user-facing documentation see:
+///
+/// http://clang.llvm.org/extra/clang-tidy/checks/cert-msc24-c.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;
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                           Preprocessor *ModuleExpanderPP) override;
+
+private:
+  bool useSafeFunctionsFromAnnexK() const;
+  Optional<std::string>
+  getReplacementFunctionNameFor(StringRef FunctionName,
+                                bool FunctionHasAnnexKReplacement) const;
+
+  Preprocessor *PP = nullptr;
+
+  // Used for caching the result of useSafeFunctionsFromAnnexK.
+  mutable llvm::Optional<bool> IsAnnexKAvailable;
+};
+
+} // 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,156 @@
+//===--- 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/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/PPCallbacks.h"
+#include "clang/Lex/Preprocessor.h"
+#include <cassert>
+
+using namespace clang::ast_matchers;
+using namespace llvm;
+
+namespace clang {
+namespace tidy {
+namespace cert {
+
+static constexpr llvm::StringLiteral DeprecatedFunctionNamesId =
+    "DeprecatedFunctionNamesId";
+static constexpr llvm::StringLiteral FunctionNamesId = "FunctionNamesId";
+static constexpr llvm::StringLiteral FunctionNamesWithAnnexKReplacementId =
+    "FunctionNamesWithAnnexKReplacementExpr";
+
+static constexpr llvm::StringLiteral DeclRefId = "DeclRefId";
+
+static StringRef getRationale(StringRef FunctionName) {
+  return StringSwitch<StringRef>(FunctionName)
+      .Cases("asctime", "ctime", "is non-reentrant")
+      .Cases("fopen", "freopen", "has no exclusive access to file")
+      .Cases("rewind", "setbuf", "has no error detection")
+      .Default("is obsolescent");
+}
+
+void ObsolescentFunctionsCheck::registerMatchers(MatchFinder *Finder) {
+
+  // Matching the `gets` deprecated function without replacement.
+  auto DeprecatedFunctionNamesMatcher = hasAnyName("::gets");
+
+  // Matching functions with replacements without annex K.
+  auto FunctionNamesMatcher = hasAnyName("::rewind", "::setbuf");
+
+  // Matching functions with safe replacements in annex K.
+  auto FunctionNamesWithAnnexKReplacementMatcher = hasAnyName(
+      "::asctime", "::ctime", "::fopen", "::freopen", "::bsearch", "::fprintf",
+      "::fscanf", "::fwprintf", "::fwscanf", "::getenv", "::gmtime",
+      "::localtime", "::mbsrtowcs", "::mbstowcs", "::memcpy", "::memmove",
+      "::printf", "::qsort", "::snprintf", "::sprintf", "::sscanf", "::strcat",
+      "::strcpy", "::strerror", "::strncat", "::strncpy", "::strtok",
+      "::swprintf", "::swscanf", "::vfprintf", "::vfscanf", "::vfwprintf",
+      "::vfwscanf", "::vprintf", "::vscanf", "::vsnprintf", "::vsprintf",
+      "::vsscanf", "::vswprintf", "::vswscanf", "::vwprintf", "::vwscanf",
+      "::wcrtomb", "::wcscat", "::wcscpy", "::wcsncat", "::wcsncpy",
+      "::wcsrtombs", "::wcstok", "::wcstombs", "::wctomb", "::wmemcpy",
+      "::wmemmove", "::wprintf", "::wscanf");
+
+  Finder->addMatcher(
+      declRefExpr(
+          to(anyOf(functionDecl(DeprecatedFunctionNamesMatcher)
+                       .bind(DeprecatedFunctionNamesId),
+                   functionDecl(FunctionNamesMatcher).bind(FunctionNamesId),
+                   functionDecl(FunctionNamesWithAnnexKReplacementMatcher)
+                       .bind(FunctionNamesWithAnnexKReplacementId))))
+          .bind(DeclRefId),
+      this);
+}
+
+void ObsolescentFunctionsCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *DeclRef = Result.Nodes.getNodeAs<DeclRefExpr>(DeclRefId);
+  assert(DeclRef && "No matching declaration reference found.");
+  SourceRange Range = SourceRange(DeclRef->getBeginLoc(), DeclRef->getEndLoc());
+
+  // FIXME: I'm not sure if this can ever happen, but to be on the safe side,
+  // validity is checked.
+  if (Range.isInvalid())
+    return;
+
+  if (const auto *Deprecated =
+          Result.Nodes.getNodeAs<FunctionDecl>(DeprecatedFunctionNamesId)) {
+    diag(Range.getBegin(),
+         "function '%0' is deprecated as of C99, removed from C11.")
+        << Deprecated->getName() << Range;
+    return;
+  }
+
+  const auto *Normal = Result.Nodes.getNodeAs<FunctionDecl>(FunctionNamesId);
+  const auto *AnnexK = Normal ? nullptr
+                              : Result.Nodes.getNodeAs<FunctionDecl>(
+                                    FunctionNamesWithAnnexKReplacementId);
+  assert((Normal && !AnnexK) || (!Normal && AnnexK));
+
+  StringRef FunctionName = (Normal ? Normal : AnnexK)->getName();
+  Optional<std::string> ReplacementFunctionName =
+      getReplacementFunctionNameFor(FunctionName, AnnexK);
+
+  if (!ReplacementFunctionName.hasValue())
+    return;
+
+  diag(Range.getBegin(), "function '%0' %1; '%2' should be used instead.")
+      << FunctionName << getRationale(FunctionName)
+      << ReplacementFunctionName.getValue() << Range;
+}
+
+void ObsolescentFunctionsCheck::registerPPCallbacks(
+    const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
+  ObsolescentFunctionsCheck::PP = PP;
+}
+
+bool ObsolescentFunctionsCheck::useSafeFunctionsFromAnnexK() const {
+  if (IsAnnexKAvailable.hasValue())
+    return IsAnnexKAvailable.getValue();
+
+  assert(PP && "No Preprocessor registered.");
+
+  if (!PP->isMacroDefined("__STDC_LIB_EXT1__") ||
+      !PP->isMacroDefined("__STDC_WANT_LIB_EXT1__")) {
+    // Caching the result.
+    return (IsAnnexKAvailable = false).getValue();
+  }
+
+  const auto *MI =
+      PP->getMacroInfo(PP->getIdentifierInfo("__STDC_WANT_LIB_EXT1__"));
+  if (!MI || MI->tokens_empty()) {
+    // Caching the result.
+    return (IsAnnexKAvailable = false).getValue();
+  }
+
+  const Token &T = MI->tokens().back();
+  if (!T.isLiteral() || !T.getLiteralData()) {
+    // Caching the result.
+    return (IsAnnexKAvailable = false).getValue();
+  }
+
+  // Caching the result.
+  IsAnnexKAvailable = StringRef(T.getLiteralData(), T.getLength()) == "1";
+  return IsAnnexKAvailable.getValue();
+}
+
+Optional<std::string> ObsolescentFunctionsCheck::getReplacementFunctionNameFor(
+    StringRef FunctionName, bool FunctionHasAnnexKReplacement) const {
+  if (FunctionHasAnnexKReplacement && useSafeFunctionsFromAnnexK())
+    return (Twine{FunctionName} + "_s").str();
+
+  return StringSwitch<Optional<std::string>>(FunctionName)
+      .Case("rewind", Optional<std::string>{"fseek"})
+      .Case("setbuf", Optional<std::string>{"setvbuf"})
+      .Default(None);
+}
+
+} // 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
@@ -12,6 +12,7 @@
   LimitedRandomnessCheck.cpp
   MutatingCopyCheck.cpp
   NonTrivialTypesLibcMemoryCallsCheck.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
@@ -32,6 +32,7 @@
 #include "LimitedRandomnessCheck.h"
 #include "MutatingCopyCheck.h"
 #include "NonTrivialTypesLibcMemoryCallsCheck.h"
+#include "ObsolescentFunctionsCheck.h"
 #include "PostfixOperatorCheck.h"
 #include "ProperlySeededRandomGeneratorCheck.h"
 #include "SetLongJmpCheck.h"
@@ -301,6 +302,7 @@
     // FIO
     CheckFactories.registerCheck<misc::NonCopyableObjectsCheck>("cert-fio38-c");
     // MSC
+    CheckFactories.registerCheck<ObsolescentFunctionsCheck>("cert-msc24-c");
     CheckFactories.registerCheck<LimitedRandomnessCheck>("cert-msc30-c");
     CheckFactories.registerCheck<ProperlySeededRandomGeneratorCheck>(
         "cert-msc32-c");
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to