| //===----------------------------------------------------------------------===// |
| // |
| // 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 "../ClangTidy.h" |
| #include "../ClangTidyModule.h" |
| #include "../ClangTidyModuleRegistry.h" |
| #include "../bugprone/BadSignalToKillThreadCheck.h" |
| #include "../bugprone/PointerArithmeticOnPolymorphicObjectCheck.h" |
| #include "../bugprone/ReservedIdentifierCheck.h" |
| #include "../bugprone/SignalHandlerCheck.h" |
| #include "../bugprone/SignedCharMisuseCheck.h" |
| #include "../bugprone/SizeofExpressionCheck.h" |
| #include "../bugprone/SpuriouslyWakeUpFunctionsCheck.h" |
| #include "../bugprone/SuspiciousMemoryComparisonCheck.h" |
| #include "../bugprone/UncheckedStringToNumberConversionCheck.h" |
| #include "../bugprone/UnhandledSelfAssignmentCheck.h" |
| #include "../bugprone/UnsafeFunctionsCheck.h" |
| #include "../bugprone/UnusedReturnValueCheck.h" |
| #include "../concurrency/ThreadCanceltypeAsynchronousCheck.h" |
| #include "../google/UnnamedNamespaceInHeaderCheck.h" |
| #include "../misc/NewDeleteOverloadsCheck.h" |
| #include "../misc/NonCopyableObjects.h" |
| #include "../misc/StaticAssertCheck.h" |
| #include "../misc/ThrowByValueCatchByReferenceCheck.h" |
| #include "../performance/MoveConstructorInitCheck.h" |
| #include "../readability/EnumInitialValueCheck.h" |
| #include "../readability/UppercaseLiteralSuffixCheck.h" |
| #include "CommandProcessorCheck.h" |
| #include "DefaultOperatorNewAlignmentCheck.h" |
| #include "DontModifyStdNamespaceCheck.h" |
| #include "FloatLoopCounter.h" |
| #include "LimitedRandomnessCheck.h" |
| #include "MutatingCopyCheck.h" |
| #include "NonTrivialTypesLibcMemoryCallsCheck.h" |
| #include "ProperlySeededRandomGeneratorCheck.h" |
| #include "SetLongJmpCheck.h" |
| #include "StaticObjectExceptionCheck.h" |
| #include "ThrownExceptionTypeCheck.h" |
| #include "VariadicFunctionDefCheck.h" |
| |
| namespace { |
| |
| // Checked functions for cert-err33-c. |
| // 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::tidy { |
| namespace cert { |
| |
| class CERTModule : public ClangTidyModule { |
| public: |
| void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { |
| // C++ checkers |
| // CON |
| CheckFactories.registerCheck<bugprone::SpuriouslyWakeUpFunctionsCheck>( |
| "cert-con54-cpp"); |
| // CTR |
| CheckFactories |
| .registerCheck<bugprone::PointerArithmeticOnPolymorphicObjectCheck>( |
| "cert-ctr56-cpp"); |
| // DCL |
| CheckFactories.registerCheck<VariadicFunctionDefCheck>("cert-dcl50-cpp"); |
| CheckFactories.registerCheck<bugprone::ReservedIdentifierCheck>( |
| "cert-dcl51-cpp"); |
| CheckFactories.registerCheck<misc::NewDeleteOverloadsCheck>( |
| "cert-dcl54-cpp"); |
| CheckFactories.registerCheck<DontModifyStdNamespaceCheck>("cert-dcl58-cpp"); |
| CheckFactories.registerCheck<google::build::UnnamedNamespaceInHeaderCheck>( |
| "cert-dcl59-cpp"); |
| // ERR |
| CheckFactories.registerCheck<misc::ThrowByValueCatchByReferenceCheck>( |
| "cert-err09-cpp"); |
| CheckFactories.registerCheck<SetLongJmpCheck>("cert-err52-cpp"); |
| CheckFactories.registerCheck<StaticObjectExceptionCheck>("cert-err58-cpp"); |
| CheckFactories.registerCheck<ThrownExceptionTypeCheck>("cert-err60-cpp"); |
| CheckFactories.registerCheck<misc::ThrowByValueCatchByReferenceCheck>( |
| "cert-err61-cpp"); |
| // MEM |
| CheckFactories.registerCheck<DefaultOperatorNewAlignmentCheck>( |
| "cert-mem57-cpp"); |
| // MSC |
| CheckFactories.registerCheck<LimitedRandomnessCheck>("cert-msc50-cpp"); |
| CheckFactories.registerCheck<ProperlySeededRandomGeneratorCheck>( |
| "cert-msc51-cpp"); |
| CheckFactories.registerCheck<bugprone::SignalHandlerCheck>( |
| "cert-msc54-cpp"); |
| // OOP |
| CheckFactories.registerCheck<performance::MoveConstructorInitCheck>( |
| "cert-oop11-cpp"); |
| CheckFactories.registerCheck<bugprone::UnhandledSelfAssignmentCheck>( |
| "cert-oop54-cpp"); |
| CheckFactories.registerCheck<NonTrivialTypesLibcMemoryCallsCheck>( |
| "cert-oop57-cpp"); |
| CheckFactories.registerCheck<MutatingCopyCheck>("cert-oop58-cpp"); |
| |
| // C checkers |
| // ARR |
| CheckFactories.registerCheck<bugprone::SizeofExpressionCheck>( |
| "cert-arr39-c"); |
| // CON |
| CheckFactories.registerCheck<bugprone::SpuriouslyWakeUpFunctionsCheck>( |
| "cert-con36-c"); |
| // DCL |
| CheckFactories.registerCheck<misc::StaticAssertCheck>("cert-dcl03-c"); |
| CheckFactories.registerCheck<readability::UppercaseLiteralSuffixCheck>( |
| "cert-dcl16-c"); |
| CheckFactories.registerCheck<bugprone::ReservedIdentifierCheck>( |
| "cert-dcl37-c"); |
| // ENV |
| CheckFactories.registerCheck<CommandProcessorCheck>("cert-env33-c"); |
| // ERR |
| CheckFactories.registerCheck<bugprone::UnusedReturnValueCheck>( |
| "cert-err33-c"); |
| CheckFactories |
| .registerCheck<bugprone::UncheckedStringToNumberConversionCheck>( |
| "cert-err34-c"); |
| // EXP |
| CheckFactories.registerCheck<bugprone::SuspiciousMemoryComparisonCheck>( |
| "cert-exp42-c"); |
| // FLP |
| CheckFactories.registerCheck<FloatLoopCounter>("cert-flp30-c"); |
| CheckFactories.registerCheck<bugprone::SuspiciousMemoryComparisonCheck>( |
| "cert-flp37-c"); |
| // FIO |
| CheckFactories.registerCheck<misc::NonCopyableObjectsCheck>("cert-fio38-c"); |
| // INT |
| CheckFactories.registerCheck<readability::EnumInitialValueCheck>( |
| "cert-int09-c"); |
| // MSC |
| CheckFactories.registerCheck<bugprone::UnsafeFunctionsCheck>( |
| "cert-msc24-c"); |
| CheckFactories.registerCheck<LimitedRandomnessCheck>("cert-msc30-c"); |
| CheckFactories.registerCheck<ProperlySeededRandomGeneratorCheck>( |
| "cert-msc32-c"); |
| CheckFactories.registerCheck<bugprone::UnsafeFunctionsCheck>( |
| "cert-msc33-c"); |
| // POS |
| CheckFactories.registerCheck<bugprone::BadSignalToKillThreadCheck>( |
| "cert-pos44-c"); |
| CheckFactories |
| .registerCheck<concurrency::ThreadCanceltypeAsynchronousCheck>( |
| "cert-pos47-c"); |
| // SIG |
| CheckFactories.registerCheck<bugprone::SignalHandlerCheck>("cert-sig30-c"); |
| // STR |
| CheckFactories.registerCheck<bugprone::SignedCharMisuseCheck>( |
| "cert-str34-c"); |
| } |
| |
| ClangTidyOptions getModuleOptions() override { |
| ClangTidyOptions Options; |
| ClangTidyOptions::OptionMap &Opts = Options.CheckOptions; |
| Opts["cert-arr39-c.WarnOnSizeOfConstant"] = "false"; |
| Opts["cert-arr39-c.WarnOnSizeOfIntegerExpression"] = "false"; |
| Opts["cert-arr39-c.WarnOnSizeOfThis"] = "false"; |
| Opts["cert-arr39-c.WarnOnSizeOfCompareToConstant"] = "false"; |
| Opts["cert-arr39-c.WarnOnSizeOfPointer"] = "false"; |
| Opts["cert-arr39-c.WarnOnSizeOfPointerToAggregate"] = "false"; |
| Opts["cert-dcl16-c.NewSuffixes"] = "L;LL;LU;LLU"; |
| Opts["cert-err33-c.CheckedFunctions"] = CertErr33CCheckedFunctions; |
| Opts["cert-err33-c.AllowCastToVoid"] = "true"; |
| Opts["cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField"] = "false"; |
| Opts["cert-str34-c.DiagnoseSignedUnsignedCharComparisons"] = "false"; |
| return Options; |
| } |
| }; |
| |
| } // namespace cert |
| |
| // Register the MiscTidyModule using this statically initialized variable. |
| static ClangTidyModuleRegistry::Add<cert::CERTModule> |
| X("cert-module", |
| "Adds lint checks corresponding to CERT secure coding guidelines."); |
| |
| // This anchor is used to force the linker to link in the generated object file |
| // and thus register the CERTModule. |
| volatile int CERTModuleAnchorSource = 0; // NOLINT(misc-use-internal-linkage) |
| |
| } // namespace clang::tidy |