diff --git a/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp b/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp --- a/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp @@ -16,6 +16,7 @@ #include "../bugprone/SpuriouslyWakeUpFunctionsCheck.h" #include "../bugprone/SuspiciousMemoryComparisonCheck.h" #include "../bugprone/UnhandledSelfAssignmentCheck.h" +#include "../bugprone/UnusedReturnValueCheck.h" #include "../concurrency/ThreadCanceltypeAsynchronousCheck.h" #include "../google/UnnamedNamespaceInHeaderCheck.h" #include "../misc/NewDeleteOverloadsCheck.h" @@ -39,6 +40,195 @@ #include "ThrownExceptionTypeCheck.h" #include "VariadicFunctionDefCheck.h" +namespace { + +// The following functions are +// deliberately excluded because they can +// be called with NULL argument and in +// this case the check is not applicable: +// mblen, mbrlen, mbrtowc, mbtowc, wctomb, +// wctomb_s +// FIXME: The check can be improved to handle such cases. +const llvm::StringRef CertErr33CCheckedFunctions = "::aligned_alloc;" + "::asctime_s;" + "::at_quick_exit;" + "::atexit;" + "::bsearch;" + "::bsearch_s;" + "::btowc;" + "::c16rtomb;" + "::c32rtomb;" + "::calloc;" + "::clock;" + "::cnd_broadcast;" + "::cnd_init;" + "::cnd_signal;" + "::cnd_timedwait;" + "::cnd_wait;" + "::ctime_s;" + "::fclose;" + "::fflush;" + "::fgetc;" + "::fgetpos;" + "::fgets;" + "::fgetwc;" + "::fopen;" + "::fopen_s;" + "::fprintf;" + "::fprintf_s;" + "::fputc;" + "::fputs;" + "::fputwc;" + "::fputws;" + "::fread;" + "::freopen;" + "::freopen_s;" + "::fscanf;" + "::fscanf_s;" + "::fseek;" + "::fsetpos;" + "::ftell;" + "::fwprintf;" + "::fwprintf_s;" + "::fwrite;" + "::fwscanf;" + "::fwscanf_s;" + "::getc;" + "::getchar;" + "::getenv;" + "::getenv_s;" + "::gets_s;" + "::getwc;" + "::getwchar;" + "::gmtime;" + "::gmtime_s;" + "::localtime;" + "::localtime_s;" + "::malloc;" + "::mbrtoc16;" + "::mbrtoc32;" + "::mbsrtowcs;" + "::mbsrtowcs_s;" + "::mbstowcs;" + "::mbstowcs_s;" + "::memchr;" + "::mktime;" + "::mtx_init;" + "::mtx_lock;" + "::mtx_timedlock;" + "::mtx_trylock;" + "::mtx_unlock;" + "::printf_s;" + "::putc;" + "::putwc;" + "::raise;" + "::realloc;" + "::remove;" + "::rename;" + "::scanf;" + "::scanf_s;" + "::setlocale;" + "::setvbuf;" + "::signal;" + "::snprintf;" + "::snprintf_s;" + "::sprintf;" + "::sprintf_s;" + "::sscanf;" + "::sscanf_s;" + "::strchr;" + "::strerror_s;" + "::strftime;" + "::strpbrk;" + "::strrchr;" + "::strstr;" + "::strtod;" + "::strtof;" + "::strtoimax;" + "::strtok;" + "::strtok_s;" + "::strtol;" + "::strtold;" + "::strtoll;" + "::strtoul;" + "::strtoull;" + "::strtoumax;" + "::strxfrm;" + "::swprintf;" + "::swprintf_s;" + "::swscanf;" + "::swscanf_s;" + "::thrd_create;" + "::thrd_detach;" + "::thrd_join;" + "::thrd_sleep;" + "::time;" + "::timespec_get;" + "::tmpfile;" + "::tmpfile_s;" + "::tmpnam;" + "::tmpnam_s;" + "::tss_create;" + "::tss_get;" + "::tss_set;" + "::ungetc;" + "::ungetwc;" + "::vfprintf;" + "::vfprintf_s;" + "::vfscanf;" + "::vfscanf_s;" + "::vfwprintf;" + "::vfwprintf_s;" + "::vfwscanf;" + "::vfwscanf_s;" + "::vprintf_s;" + "::vscanf;" + "::vscanf_s;" + "::vsnprintf;" + "::vsnprintf_s;" + "::vsprintf;" + "::vsprintf_s;" + "::vsscanf;" + "::vsscanf_s;" + "::vswprintf;" + "::vswprintf_s;" + "::vswscanf;" + "::vswscanf_s;" + "::vwprintf_s;" + "::vwscanf;" + "::vwscanf_s;" + "::wcrtomb;" + "::wcschr;" + "::wcsftime;" + "::wcspbrk;" + "::wcsrchr;" + "::wcsrtombs;" + "::wcsrtombs_s;" + "::wcsstr;" + "::wcstod;" + "::wcstof;" + "::wcstoimax;" + "::wcstok;" + "::wcstok_s;" + "::wcstol;" + "::wcstold;" + "::wcstoll;" + "::wcstombs;" + "::wcstombs_s;" + "::wcstoul;" + "::wcstoull;" + "::wcstoumax;" + "::wcsxfrm;" + "::wctob;" + "::wctrans;" + "::wctype;" + "::wmemchr;" + "::wprintf_s;" + "::wscanf;" + "::wscanf_s;"; + +} // namespace + namespace clang { namespace tidy { namespace cert { @@ -110,6 +300,8 @@ CheckFactories.registerCheck("cert-fio38-c"); // ERR CheckFactories.registerCheck("cert-err34-c"); + CheckFactories.registerCheck( + "cert-err33-c"); // MSC CheckFactories.registerCheck("cert-msc30-c"); CheckFactories.registerCheck( @@ -133,6 +325,7 @@ Opts["cert-dcl16-c.NewSuffixes"] = "L;LL;LU;LLU"; Opts["cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField"] = "false"; Opts["cert-str34-c.DiagnoseSignedUnsignedCharComparisons"] = "false"; + Opts["cert-err33-c.CheckedFunctions"] = CertErr33CCheckedFunctions; return Options; } }; diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone-unused-return-value.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone-unused-return-value.rst --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone-unused-return-value.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone-unused-return-value.rst @@ -45,3 +45,6 @@ - ``std::basic_string::empty()`` and ``std::vector::empty()``. Not using the return value often indicates that the programmer confused the function with ``clear()``. + +`cert-err33-c` is a version of this check that checks exactly the functions +listed in CERT_rule ERR33-C. \ No newline at end of file diff --git a/clang-tools-extra/docs/clang-tidy/checks/cert-err33-c.rst b/clang-tools-extra/docs/clang-tidy/checks/cert-err33-c.rst new file mode 100644 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/cert-err33-c.rst @@ -0,0 +1,18 @@ +.. title:: clang-tidy - cert-err33-c + +cert-err33-c +============ + +Warns on unused function return values. +This check corresponds to (a part of) CERT C Coding Standard rule `ERR33-C. +Detect and handle standard library errors +`_. +The list of checked functions is the same as specified in the rule, with +following exception: + +* These functions are safe if called with NULL argument. The check can not + differentiate this case from the others.:: + + mblen; mbrlen; mbrtowc; mbtowc; wctomb; wctomb_s + +If a custom list of checked functions is needed the check `bugprone-unused-return-value` can be used instead. diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -114,6 +114,7 @@ `cert-dcl50-cpp `_, `cert-dcl58-cpp `_, `cert-env33-c `_, + `cert-err33-c `_, `cert-err34-c `_, `cert-err52-cpp `_, `cert-err58-cpp `_,