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 | |