| 1 | //===--- CERTTidyModule.cpp - clang-tidy ----------------------------------===// |
|---|---|
| 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-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| 9 | #include "../ClangTidy.h" |
| 10 | #include "../ClangTidyModule.h" |
| 11 | #include "../ClangTidyModuleRegistry.h" |
| 12 | #include "../bugprone/BadSignalToKillThreadCheck.h" |
| 13 | #include "../bugprone/PointerArithmeticOnPolymorphicObjectCheck.h" |
| 14 | #include "../bugprone/ReservedIdentifierCheck.h" |
| 15 | #include "../bugprone/SignalHandlerCheck.h" |
| 16 | #include "../bugprone/SignedCharMisuseCheck.h" |
| 17 | #include "../bugprone/SizeofExpressionCheck.h" |
| 18 | #include "../bugprone/SpuriouslyWakeUpFunctionsCheck.h" |
| 19 | #include "../bugprone/SuspiciousMemoryComparisonCheck.h" |
| 20 | #include "../bugprone/UnhandledSelfAssignmentCheck.h" |
| 21 | #include "../bugprone/UnsafeFunctionsCheck.h" |
| 22 | #include "../bugprone/UnusedReturnValueCheck.h" |
| 23 | #include "../concurrency/ThreadCanceltypeAsynchronousCheck.h" |
| 24 | #include "../google/UnnamedNamespaceInHeaderCheck.h" |
| 25 | #include "../misc/NewDeleteOverloadsCheck.h" |
| 26 | #include "../misc/NonCopyableObjects.h" |
| 27 | #include "../misc/StaticAssertCheck.h" |
| 28 | #include "../misc/ThrowByValueCatchByReferenceCheck.h" |
| 29 | #include "../performance/MoveConstructorInitCheck.h" |
| 30 | #include "../readability/EnumInitialValueCheck.h" |
| 31 | #include "../readability/UppercaseLiteralSuffixCheck.h" |
| 32 | #include "CommandProcessorCheck.h" |
| 33 | #include "DefaultOperatorNewAlignmentCheck.h" |
| 34 | #include "DontModifyStdNamespaceCheck.h" |
| 35 | #include "FloatLoopCounter.h" |
| 36 | #include "LimitedRandomnessCheck.h" |
| 37 | #include "MutatingCopyCheck.h" |
| 38 | #include "NonTrivialTypesLibcMemoryCallsCheck.h" |
| 39 | #include "ProperlySeededRandomGeneratorCheck.h" |
| 40 | #include "SetLongJmpCheck.h" |
| 41 | #include "StaticObjectExceptionCheck.h" |
| 42 | #include "StrToNumCheck.h" |
| 43 | #include "ThrownExceptionTypeCheck.h" |
| 44 | #include "VariadicFunctionDefCheck.h" |
| 45 | |
| 46 | namespace { |
| 47 | |
| 48 | // Checked functions for cert-err33-c. |
| 49 | // The following functions are deliberately excluded because they can be called |
| 50 | // 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. |
| 53 | const 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 | } // namespace |
| 232 | |
| 233 | namespace clang::tidy { |
| 234 | namespace cert { |
| 235 | |
| 236 | class CERTModule : public ClangTidyModule { |
| 237 | public: |
| 238 | void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { |
| 239 | // C++ checkers |
| 240 | // CON |
| 241 | CheckFactories.registerCheck<bugprone::SpuriouslyWakeUpFunctionsCheck>( |
| 242 | CheckName: "cert-con54-cpp"); |
| 243 | // CTR |
| 244 | CheckFactories |
| 245 | .registerCheck<bugprone::PointerArithmeticOnPolymorphicObjectCheck>( |
| 246 | CheckName: "cert-ctr56-cpp"); |
| 247 | // DCL |
| 248 | CheckFactories.registerCheck<VariadicFunctionDefCheck>(CheckName: "cert-dcl50-cpp"); |
| 249 | CheckFactories.registerCheck<bugprone::ReservedIdentifierCheck>( |
| 250 | CheckName: "cert-dcl51-cpp"); |
| 251 | CheckFactories.registerCheck<misc::NewDeleteOverloadsCheck>( |
| 252 | CheckName: "cert-dcl54-cpp"); |
| 253 | CheckFactories.registerCheck<DontModifyStdNamespaceCheck>(CheckName: "cert-dcl58-cpp"); |
| 254 | CheckFactories.registerCheck<google::build::UnnamedNamespaceInHeaderCheck>( |
| 255 | CheckName: "cert-dcl59-cpp"); |
| 256 | // ERR |
| 257 | CheckFactories.registerCheck<misc::ThrowByValueCatchByReferenceCheck>( |
| 258 | CheckName: "cert-err09-cpp"); |
| 259 | CheckFactories.registerCheck<SetLongJmpCheck>(CheckName: "cert-err52-cpp"); |
| 260 | CheckFactories.registerCheck<StaticObjectExceptionCheck>(CheckName: "cert-err58-cpp"); |
| 261 | CheckFactories.registerCheck<ThrownExceptionTypeCheck>(CheckName: "cert-err60-cpp"); |
| 262 | CheckFactories.registerCheck<misc::ThrowByValueCatchByReferenceCheck>( |
| 263 | CheckName: "cert-err61-cpp"); |
| 264 | // MEM |
| 265 | CheckFactories.registerCheck<DefaultOperatorNewAlignmentCheck>( |
| 266 | CheckName: "cert-mem57-cpp"); |
| 267 | // MSC |
| 268 | CheckFactories.registerCheck<LimitedRandomnessCheck>(CheckName: "cert-msc50-cpp"); |
| 269 | CheckFactories.registerCheck<ProperlySeededRandomGeneratorCheck>( |
| 270 | CheckName: "cert-msc51-cpp"); |
| 271 | CheckFactories.registerCheck<bugprone::SignalHandlerCheck>( |
| 272 | CheckName: "cert-msc54-cpp"); |
| 273 | // OOP |
| 274 | CheckFactories.registerCheck<performance::MoveConstructorInitCheck>( |
| 275 | CheckName: "cert-oop11-cpp"); |
| 276 | CheckFactories.registerCheck<bugprone::UnhandledSelfAssignmentCheck>( |
| 277 | CheckName: "cert-oop54-cpp"); |
| 278 | CheckFactories.registerCheck<NonTrivialTypesLibcMemoryCallsCheck>( |
| 279 | CheckName: "cert-oop57-cpp"); |
| 280 | CheckFactories.registerCheck<MutatingCopyCheck>(CheckName: "cert-oop58-cpp"); |
| 281 | |
| 282 | // C checkers |
| 283 | // ARR |
| 284 | CheckFactories.registerCheck<bugprone::SizeofExpressionCheck>( |
| 285 | CheckName: "cert-arr39-c"); |
| 286 | // CON |
| 287 | CheckFactories.registerCheck<bugprone::SpuriouslyWakeUpFunctionsCheck>( |
| 288 | CheckName: "cert-con36-c"); |
| 289 | // DCL |
| 290 | CheckFactories.registerCheck<misc::StaticAssertCheck>(CheckName: "cert-dcl03-c"); |
| 291 | CheckFactories.registerCheck<readability::UppercaseLiteralSuffixCheck>( |
| 292 | CheckName: "cert-dcl16-c"); |
| 293 | CheckFactories.registerCheck<bugprone::ReservedIdentifierCheck>( |
| 294 | CheckName: "cert-dcl37-c"); |
| 295 | // ENV |
| 296 | CheckFactories.registerCheck<CommandProcessorCheck>(CheckName: "cert-env33-c"); |
| 297 | // ERR |
| 298 | CheckFactories.registerCheck<bugprone::UnusedReturnValueCheck>( |
| 299 | CheckName: "cert-err33-c"); |
| 300 | CheckFactories.registerCheck<StrToNumCheck>(CheckName: "cert-err34-c"); |
| 301 | // EXP |
| 302 | CheckFactories.registerCheck<bugprone::SuspiciousMemoryComparisonCheck>( |
| 303 | CheckName: "cert-exp42-c"); |
| 304 | // FLP |
| 305 | CheckFactories.registerCheck<FloatLoopCounter>(CheckName: "cert-flp30-c"); |
| 306 | CheckFactories.registerCheck<bugprone::SuspiciousMemoryComparisonCheck>( |
| 307 | CheckName: "cert-flp37-c"); |
| 308 | // FIO |
| 309 | CheckFactories.registerCheck<misc::NonCopyableObjectsCheck>(CheckName: "cert-fio38-c"); |
| 310 | // INT |
| 311 | CheckFactories.registerCheck<readability::EnumInitialValueCheck>( |
| 312 | CheckName: "cert-int09-c"); |
| 313 | // MSC |
| 314 | CheckFactories.registerCheck<bugprone::UnsafeFunctionsCheck>( |
| 315 | CheckName: "cert-msc24-c"); |
| 316 | CheckFactories.registerCheck<LimitedRandomnessCheck>(CheckName: "cert-msc30-c"); |
| 317 | CheckFactories.registerCheck<ProperlySeededRandomGeneratorCheck>( |
| 318 | CheckName: "cert-msc32-c"); |
| 319 | CheckFactories.registerCheck<bugprone::UnsafeFunctionsCheck>( |
| 320 | CheckName: "cert-msc33-c"); |
| 321 | // POS |
| 322 | CheckFactories.registerCheck<bugprone::BadSignalToKillThreadCheck>( |
| 323 | CheckName: "cert-pos44-c"); |
| 324 | CheckFactories |
| 325 | .registerCheck<concurrency::ThreadCanceltypeAsynchronousCheck>( |
| 326 | CheckName: "cert-pos47-c"); |
| 327 | // SIG |
| 328 | CheckFactories.registerCheck<bugprone::SignalHandlerCheck>(CheckName: "cert-sig30-c"); |
| 329 | // STR |
| 330 | CheckFactories.registerCheck<bugprone::SignedCharMisuseCheck>( |
| 331 | CheckName: "cert-str34-c"); |
| 332 | } |
| 333 | |
| 334 | ClangTidyOptions getModuleOptions() override { |
| 335 | ClangTidyOptions Options; |
| 336 | ClangTidyOptions::OptionMap &Opts = Options.CheckOptions; |
| 337 | Opts["cert-arr39-c.WarnOnSizeOfConstant"] = "false"; |
| 338 | Opts["cert-arr39-c.WarnOnSizeOfIntegerExpression"] = "false"; |
| 339 | Opts["cert-arr39-c.WarnOnSizeOfThis"] = "false"; |
| 340 | Opts["cert-arr39-c.WarnOnSizeOfCompareToConstant"] = "false"; |
| 341 | Opts["cert-arr39-c.WarnOnSizeOfPointer"] = "false"; |
| 342 | Opts["cert-arr39-c.WarnOnSizeOfPointerToAggregate"] = "false"; |
| 343 | Opts["cert-dcl16-c.NewSuffixes"] = "L;LL;LU;LLU"; |
| 344 | Opts["cert-err33-c.CheckedFunctions"] = CertErr33CCheckedFunctions; |
| 345 | Opts["cert-err33-c.AllowCastToVoid"] = "true"; |
| 346 | Opts["cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField"] = "false"; |
| 347 | Opts["cert-str34-c.DiagnoseSignedUnsignedCharComparisons"] = "false"; |
| 348 | return Options; |
| 349 | } |
| 350 | }; |
| 351 | |
| 352 | } // namespace cert |
| 353 | |
| 354 | // Register the MiscTidyModule using this statically initialized variable. |
| 355 | static ClangTidyModuleRegistry::Add<cert::CERTModule> |
| 356 | X("cert-module", |
| 357 | "Adds lint checks corresponding to CERT secure coding guidelines."); |
| 358 | |
| 359 | // This anchor is used to force the linker to link in the generated object file |
| 360 | // and thus register the CERTModule. |
| 361 | volatile int CERTModuleAnchorSource = 0; // NOLINT(misc-use-internal-linkage) |
| 362 | |
| 363 | } // namespace clang::tidy |
| 364 |
