375 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "../ClangTidy.h"10#include "../ClangTidyModule.h"11#include "../ClangTidyModuleRegistry.h"12#include "../bugprone/BadSignalToKillThreadCheck.h"13#include "../bugprone/CommandProcessorCheck.h"14#include "../bugprone/CopyConstructorMutatesArgumentCheck.h"15#include "../bugprone/DefaultOperatorNewOnOveralignedTypeCheck.h"16#include "../bugprone/ExceptionCopyConstructorThrowsCheck.h"17#include "../bugprone/FloatLoopCounterCheck.h"18#include "../bugprone/PointerArithmeticOnPolymorphicObjectCheck.h"19#include "../bugprone/RandomGeneratorSeedCheck.h"20#include "../bugprone/RawMemoryCallOnNonTrivialTypeCheck.h"21#include "../bugprone/ReservedIdentifierCheck.h"22#include "../bugprone/SignalHandlerCheck.h"23#include "../bugprone/SignedCharMisuseCheck.h"24#include "../bugprone/SizeofExpressionCheck.h"25#include "../bugprone/SpuriouslyWakeUpFunctionsCheck.h"26#include "../bugprone/StdNamespaceModificationCheck.h"27#include "../bugprone/SuspiciousMemoryComparisonCheck.h"28#include "../bugprone/ThrowingStaticInitializationCheck.h"29#include "../bugprone/UncheckedStringToNumberConversionCheck.h"30#include "../bugprone/UnhandledSelfAssignmentCheck.h"31#include "../bugprone/UnsafeFunctionsCheck.h"32#include "../bugprone/UnusedReturnValueCheck.h"33#include "../concurrency/ThreadCanceltypeAsynchronousCheck.h"34#include "../google/UnnamedNamespaceInHeaderCheck.h"35#include "../misc/NewDeleteOverloadsCheck.h"36#include "../misc/NonCopyableObjectsCheck.h"37#include "../misc/PredictableRandCheck.h"38#include "../misc/StaticAssertCheck.h"39#include "../misc/ThrowByValueCatchByReferenceCheck.h"40#include "../modernize/AvoidSetjmpLongjmpCheck.h"41#include "../modernize/AvoidVariadicFunctionsCheck.h"42#include "../performance/MoveConstructorInitCheck.h"43#include "../readability/EnumInitialValueCheck.h"44#include "../readability/UppercaseLiteralSuffixCheck.h"45 46namespace {47 48// Checked functions for cert-err33-c.49// The following functions are deliberately excluded because they can be50// called with NULL argument and in this case the check is not applicable:51// `mblen, mbrlen, mbrtowc, mbtowc, wctomb, wctomb_s`.52// FIXME: The check can be improved to handle such cases.53const llvm::StringRef CertErr33CCheckedFunctions = "^::aligned_alloc$;"54 "^::asctime_s$;"55 "^::at_quick_exit$;"56 "^::atexit$;"57 "^::bsearch$;"58 "^::bsearch_s$;"59 "^::btowc$;"60 "^::c16rtomb$;"61 "^::c32rtomb$;"62 "^::calloc$;"63 "^::clock$;"64 "^::cnd_broadcast$;"65 "^::cnd_init$;"66 "^::cnd_signal$;"67 "^::cnd_timedwait$;"68 "^::cnd_wait$;"69 "^::ctime_s$;"70 "^::fclose$;"71 "^::fflush$;"72 "^::fgetc$;"73 "^::fgetpos$;"74 "^::fgets$;"75 "^::fgetwc$;"76 "^::fopen$;"77 "^::fopen_s$;"78 "^::fprintf$;"79 "^::fprintf_s$;"80 "^::fputc$;"81 "^::fputs$;"82 "^::fputwc$;"83 "^::fputws$;"84 "^::fread$;"85 "^::freopen$;"86 "^::freopen_s$;"87 "^::fscanf$;"88 "^::fscanf_s$;"89 "^::fseek$;"90 "^::fsetpos$;"91 "^::ftell$;"92 "^::fwprintf$;"93 "^::fwprintf_s$;"94 "^::fwrite$;"95 "^::fwscanf$;"96 "^::fwscanf_s$;"97 "^::getc$;"98 "^::getchar$;"99 "^::getenv$;"100 "^::getenv_s$;"101 "^::gets_s$;"102 "^::getwc$;"103 "^::getwchar$;"104 "^::gmtime$;"105 "^::gmtime_s$;"106 "^::localtime$;"107 "^::localtime_s$;"108 "^::malloc$;"109 "^::mbrtoc16$;"110 "^::mbrtoc32$;"111 "^::mbsrtowcs$;"112 "^::mbsrtowcs_s$;"113 "^::mbstowcs$;"114 "^::mbstowcs_s$;"115 "^::memchr$;"116 "^::mktime$;"117 "^::mtx_init$;"118 "^::mtx_lock$;"119 "^::mtx_timedlock$;"120 "^::mtx_trylock$;"121 "^::mtx_unlock$;"122 "^::printf_s$;"123 "^::putc$;"124 "^::putwc$;"125 "^::raise$;"126 "^::realloc$;"127 "^::remove$;"128 "^::rename$;"129 "^::scanf$;"130 "^::scanf_s$;"131 "^::setlocale$;"132 "^::setvbuf$;"133 "^::signal$;"134 "^::snprintf$;"135 "^::snprintf_s$;"136 "^::sprintf$;"137 "^::sprintf_s$;"138 "^::sscanf$;"139 "^::sscanf_s$;"140 "^::strchr$;"141 "^::strerror_s$;"142 "^::strftime$;"143 "^::strpbrk$;"144 "^::strrchr$;"145 "^::strstr$;"146 "^::strtod$;"147 "^::strtof$;"148 "^::strtoimax$;"149 "^::strtok$;"150 "^::strtok_s$;"151 "^::strtol$;"152 "^::strtold$;"153 "^::strtoll$;"154 "^::strtoul$;"155 "^::strtoull$;"156 "^::strtoumax$;"157 "^::strxfrm$;"158 "^::swprintf$;"159 "^::swprintf_s$;"160 "^::swscanf$;"161 "^::swscanf_s$;"162 "^::thrd_create$;"163 "^::thrd_detach$;"164 "^::thrd_join$;"165 "^::thrd_sleep$;"166 "^::time$;"167 "^::timespec_get$;"168 "^::tmpfile$;"169 "^::tmpfile_s$;"170 "^::tmpnam$;"171 "^::tmpnam_s$;"172 "^::tss_create$;"173 "^::tss_get$;"174 "^::tss_set$;"175 "^::ungetc$;"176 "^::ungetwc$;"177 "^::vfprintf$;"178 "^::vfprintf_s$;"179 "^::vfscanf$;"180 "^::vfscanf_s$;"181 "^::vfwprintf$;"182 "^::vfwprintf_s$;"183 "^::vfwscanf$;"184 "^::vfwscanf_s$;"185 "^::vprintf_s$;"186 "^::vscanf$;"187 "^::vscanf_s$;"188 "^::vsnprintf$;"189 "^::vsnprintf_s$;"190 "^::vsprintf$;"191 "^::vsprintf_s$;"192 "^::vsscanf$;"193 "^::vsscanf_s$;"194 "^::vswprintf$;"195 "^::vswprintf_s$;"196 "^::vswscanf$;"197 "^::vswscanf_s$;"198 "^::vwprintf_s$;"199 "^::vwscanf$;"200 "^::vwscanf_s$;"201 "^::wcrtomb$;"202 "^::wcschr$;"203 "^::wcsftime$;"204 "^::wcspbrk$;"205 "^::wcsrchr$;"206 "^::wcsrtombs$;"207 "^::wcsrtombs_s$;"208 "^::wcsstr$;"209 "^::wcstod$;"210 "^::wcstof$;"211 "^::wcstoimax$;"212 "^::wcstok$;"213 "^::wcstok_s$;"214 "^::wcstol$;"215 "^::wcstold$;"216 "^::wcstoll$;"217 "^::wcstombs$;"218 "^::wcstombs_s$;"219 "^::wcstoul$;"220 "^::wcstoull$;"221 "^::wcstoumax$;"222 "^::wcsxfrm$;"223 "^::wctob$;"224 "^::wctrans$;"225 "^::wctype$;"226 "^::wmemchr$;"227 "^::wprintf_s$;"228 "^::wscanf$;"229 "^::wscanf_s$;";230 231} // namespace232 233namespace clang::tidy {234namespace cert {235 236class CERTModule : public ClangTidyModule {237public:238 void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {239 // C++ checkers240 // CON241 CheckFactories.registerCheck<bugprone::SpuriouslyWakeUpFunctionsCheck>(242 "cert-con54-cpp");243 // CTR244 CheckFactories245 .registerCheck<bugprone::PointerArithmeticOnPolymorphicObjectCheck>(246 "cert-ctr56-cpp");247 // DCL248 CheckFactories.registerCheck<modernize::AvoidVariadicFunctionsCheck>(249 "cert-dcl50-cpp");250 CheckFactories.registerCheck<bugprone::ReservedIdentifierCheck>(251 "cert-dcl51-cpp");252 CheckFactories.registerCheck<misc::NewDeleteOverloadsCheck>(253 "cert-dcl54-cpp");254 CheckFactories.registerCheck<bugprone::StdNamespaceModificationCheck>(255 "cert-dcl58-cpp");256 CheckFactories.registerCheck<google::build::UnnamedNamespaceInHeaderCheck>(257 "cert-dcl59-cpp");258 // ERR259 CheckFactories.registerCheck<misc::ThrowByValueCatchByReferenceCheck>(260 "cert-err09-cpp");261 CheckFactories.registerCheck<modernize::AvoidSetjmpLongjmpCheck>(262 "cert-err52-cpp");263 CheckFactories.registerCheck<bugprone::ThrowingStaticInitializationCheck>(264 "cert-err58-cpp");265 CheckFactories.registerCheck<bugprone::ExceptionCopyConstructorThrowsCheck>(266 "cert-err60-cpp");267 CheckFactories.registerCheck<misc::ThrowByValueCatchByReferenceCheck>(268 "cert-err61-cpp");269 // MEM270 CheckFactories271 .registerCheck<bugprone::DefaultOperatorNewOnOveralignedTypeCheck>(272 "cert-mem57-cpp");273 // MSC274 CheckFactories.registerCheck<misc::PredictableRandCheck>("cert-msc50-cpp");275 CheckFactories.registerCheck<bugprone::RandomGeneratorSeedCheck>(276 "cert-msc51-cpp");277 CheckFactories.registerCheck<bugprone::SignalHandlerCheck>(278 "cert-msc54-cpp");279 // OOP280 CheckFactories.registerCheck<performance::MoveConstructorInitCheck>(281 "cert-oop11-cpp");282 CheckFactories.registerCheck<bugprone::UnhandledSelfAssignmentCheck>(283 "cert-oop54-cpp");284 CheckFactories.registerCheck<bugprone::RawMemoryCallOnNonTrivialTypeCheck>(285 "cert-oop57-cpp");286 CheckFactories.registerCheck<bugprone::CopyConstructorMutatesArgumentCheck>(287 "cert-oop58-cpp");288 289 // C checkers290 // ARR291 CheckFactories.registerCheck<bugprone::SizeofExpressionCheck>(292 "cert-arr39-c");293 // CON294 CheckFactories.registerCheck<bugprone::SpuriouslyWakeUpFunctionsCheck>(295 "cert-con36-c");296 // DCL297 CheckFactories.registerCheck<misc::StaticAssertCheck>("cert-dcl03-c");298 CheckFactories.registerCheck<readability::UppercaseLiteralSuffixCheck>(299 "cert-dcl16-c");300 CheckFactories.registerCheck<bugprone::ReservedIdentifierCheck>(301 "cert-dcl37-c");302 // ENV303 CheckFactories.registerCheck<bugprone::CommandProcessorCheck>(304 "cert-env33-c");305 // ERR306 CheckFactories.registerCheck<bugprone::UnusedReturnValueCheck>(307 "cert-err33-c");308 CheckFactories309 .registerCheck<bugprone::UncheckedStringToNumberConversionCheck>(310 "cert-err34-c");311 // EXP312 CheckFactories.registerCheck<bugprone::SuspiciousMemoryComparisonCheck>(313 "cert-exp42-c");314 // FLP315 CheckFactories.registerCheck<bugprone::FloatLoopCounterCheck>(316 "cert-flp30-c");317 CheckFactories.registerCheck<bugprone::SuspiciousMemoryComparisonCheck>(318 "cert-flp37-c");319 // FIO320 CheckFactories.registerCheck<misc::NonCopyableObjectsCheck>("cert-fio38-c");321 // INT322 CheckFactories.registerCheck<readability::EnumInitialValueCheck>(323 "cert-int09-c");324 // MSC325 CheckFactories.registerCheck<bugprone::UnsafeFunctionsCheck>(326 "cert-msc24-c");327 CheckFactories.registerCheck<misc::PredictableRandCheck>("cert-msc30-c");328 CheckFactories.registerCheck<bugprone::RandomGeneratorSeedCheck>(329 "cert-msc32-c");330 CheckFactories.registerCheck<bugprone::UnsafeFunctionsCheck>(331 "cert-msc33-c");332 // POS333 CheckFactories.registerCheck<bugprone::BadSignalToKillThreadCheck>(334 "cert-pos44-c");335 CheckFactories336 .registerCheck<concurrency::ThreadCanceltypeAsynchronousCheck>(337 "cert-pos47-c");338 // SIG339 CheckFactories.registerCheck<bugprone::SignalHandlerCheck>("cert-sig30-c");340 // STR341 CheckFactories.registerCheck<bugprone::SignedCharMisuseCheck>(342 "cert-str34-c");343 }344 345 ClangTidyOptions getModuleOptions() override {346 ClangTidyOptions Options;347 ClangTidyOptions::OptionMap &Opts = Options.CheckOptions;348 Opts["cert-arr39-c.WarnOnSizeOfConstant"] = "false";349 Opts["cert-arr39-c.WarnOnSizeOfIntegerExpression"] = "false";350 Opts["cert-arr39-c.WarnOnSizeOfThis"] = "false";351 Opts["cert-arr39-c.WarnOnSizeOfCompareToConstant"] = "false";352 Opts["cert-arr39-c.WarnOnSizeOfPointer"] = "false";353 Opts["cert-arr39-c.WarnOnSizeOfPointerToAggregate"] = "false";354 Opts["cert-dcl16-c.NewSuffixes"] = "L;LL;LU;LLU";355 Opts["cert-err33-c.CheckedFunctions"] = CertErr33CCheckedFunctions;356 Opts["cert-err33-c.AllowCastToVoid"] = "true";357 Opts["cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField"] = "false";358 Opts["cert-str34-c.DiagnoseSignedUnsignedCharComparisons"] = "false";359 return Options;360 }361};362 363} // namespace cert364 365// Register the MiscTidyModule using this statically initialized variable.366static ClangTidyModuleRegistry::Add<cert::CERTModule>367 X("cert-module",368 "Adds lint checks corresponding to CERT secure coding guidelines.");369 370// This anchor is used to force the linker to link in the generated object file371// and thus register the CERTModule.372volatile int CERTModuleAnchorSource = 0; // NOLINT(misc-use-internal-linkage)373 374} // namespace clang::tidy375