|
| 1 | +# SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. |
| 2 | +# All rights reserved. |
| 3 | +# SPDX-License-Identifier: Apache-2.0 |
| 4 | +--- |
| 5 | +Checks: |
| 6 | + # enable everything first |
| 7 | + - 'performance-*' |
| 8 | + - 'modernize-*' |
| 9 | + - 'readability-*' |
| 10 | + - 'clang-analyzer-*' |
| 11 | + - 'clang-diagnostic-*' |
| 12 | + - 'bugprone-*' |
| 13 | + - 'misc-*' |
| 14 | + - 'core-*' |
| 15 | + - 'mpi-*' |
| 16 | + - 'cert-*' |
| 17 | + - 'portability-*' |
| 18 | + - 'google-*' |
| 19 | + - 'cppcoreguidelines-*' |
| 20 | + - 'concurrency-*' |
| 21 | + # TODO: BEGIN REMOVE ME |
| 22 | + - '-*' |
| 23 | + - 'performance-implicit-conversion-in-loop' |
| 24 | + # END REMOVE ME |
| 25 | + # HICPP is 99% aliased to other checks (mostly modernize-* and bugprone-*). We don't |
| 26 | + # want to also enable it because then we need to duplicate the NOLINT. The only 2 checks |
| 27 | + # that aren't aliases are: |
| 28 | + # |
| 29 | + # - hicpp-multiway-paths-covered. This check is useful for detecting degenerate if-else |
| 30 | + # branches, but the switch cases are IMO better handled by -Wswitch. To make -Wswitch |
| 31 | + # even stronger, we should ban default: cases entirely, |
| 32 | + # |
| 33 | + # - hicpp-signed-bitwise. This check is also covered by |
| 34 | + # clang.llvm.org/extra/clang-tidy/checks/clang-analyzer/core.BitwiseShift.html |
| 35 | + # |
| 36 | + # - 'hicpp-*' |
| 37 | + # |
| 38 | + # LLVM checks are extremely specific to the LLVM project and aren't suitable for |
| 39 | + # downstream users. |
| 40 | + # |
| 41 | + # - 'llvm-*' |
| 42 | + # |
| 43 | + # then disable the stuff we don't want |
| 44 | + - '-cert-dcl21-cpp' # returning non-const from operator-- or operator++ |
| 45 | + - '-cert-dcl50-cpp' # allow c-style variadics |
| 46 | + # No reserved identifiers, both of these are aliased to bugprone-reserved-identifier, |
| 47 | + # which we do enable. Leaving these enabled however, leads to needing to specify all |
| 48 | + # three (bugprone-reserved-identifier, cert-dcl51-cpp, and cert-dcl37-c) in NOLINT lines |
| 49 | + # which is a hassle. Since bugprone-reserved-identifier is enabled, the check still |
| 50 | + # fires. |
| 51 | + - '-cert-dcl51-cpp,-cert-dcl37-c,-cert-oop54-cpp' |
| 52 | + # Covered by bugprone-throwing-static-initialization |
| 53 | + - '-cert-err58-cpp' |
| 54 | + - '-modernize-use-trailing-return-type' |
| 55 | + - '-readability-function-cognitive-complexity' |
| 56 | + - '-readability-implicit-bool-conversion' |
| 57 | + - '-readability-braces-around-statements' |
| 58 | + - '-readability-qualified-auto' |
| 59 | + - '-readability-isolate-declaration' |
| 60 | + - '-modernize-avoid-c-arrays' |
| 61 | + - '-cppcoreguidelines-avoid-c-arrays' |
| 62 | + - '-readability-named-parameter' |
| 63 | + - '-readability-identifier-length' |
| 64 | + - '-misc-non-private-member-variables-in-classes' |
| 65 | + - '-bugprone-easily-swappable-parameters' |
| 66 | + - '-bugprone-implicit-widening-of-multiplication-result' |
| 67 | + - '-misc-include-cleaner' |
| 68 | + - '-misc-header-include-cycle' |
| 69 | + - '-modernize-macro-to-enum' |
| 70 | + - '-cppcoreguidelines-macro-to-enum' |
| 71 | + - '-misc-no-recursion' |
| 72 | + - '-bugprone-dynamic-static-initializers' |
| 73 | + - '-portability-avoid-pragma-once' |
| 74 | + # Generally speaking if something is static then it has an express reason to be. 99% of |
| 75 | + # the candidates identified by this check were because they just so happened not to |
| 76 | + # touch any member variables, not because they are logically static. So we disable the |
| 77 | + # check. |
| 78 | + - '-readability-convert-member-functions-to-static' |
| 79 | + # When running in a conda env, ignore options that may have been added by conda but are unused |
| 80 | + - '-clang-diagnostic-unused-command-line-argument' |
| 81 | + # Given |
| 82 | + # |
| 83 | + # std::make_pair<some_type, some_other_type>(...) |
| 84 | + # |
| 85 | + # Results in: error: for C++11-compatibility, use pair directly. But we don't care about |
| 86 | + # C++11, and so we don't care about this warning. |
| 87 | + - '-google-build-explicit-make-pair' |
| 88 | + # This check is incredibly expensive for absolutely no reason, and since we a) use |
| 89 | + # modern google-test and b) don't have clang-tidy enabled on our testing code, we don't |
| 90 | + # need to enable it! |
| 91 | + - '-google-upgrade-googletest-case' |
| 92 | + # This warning will warn if you have redundant default-initializers for class |
| 93 | + # members. For example: |
| 94 | + # |
| 95 | + # class Foo |
| 96 | + # { |
| 97 | + # int x_{}; // WARNING: redundant initializer here |
| 98 | + # |
| 99 | + # public: |
| 100 | + # Foo(int x) : x_{x} { } |
| 101 | + # }; |
| 102 | + # |
| 103 | + # Since Foo can only ever be constructed with an explicit value for x_ via its constructor, |
| 104 | + # the default initializer is technically redundant. However, if we change the definition |
| 105 | + # of Foo to now allow a default ctor, then the initializer becomes non-redundant |
| 106 | + # again. It is easier to just follow the rule of "always explicitly default initialize |
| 107 | + # members" than to remember to change 2 places at once. |
| 108 | + - '-readability-redundant-member-init' |
| 109 | + # Alias for readability-enum-initial-value, disable this one because the readability- |
| 110 | + # name is easier to understand, and we don't want to silence 2 things for the same |
| 111 | + # warning. |
| 112 | + - '-cert-int09-c' |
| 113 | + # This one is potentially controversial. This check warns when iterating over unordered |
| 114 | + # containers of pointers: |
| 115 | + # |
| 116 | + # { |
| 117 | + # int a = 1, b = 2; |
| 118 | + # std::unordered_set<int *> set = {&a, &b}; |
| 119 | + # |
| 120 | + # for (auto *i : set) { // iteration order not deterministic |
| 121 | + # f(i); |
| 122 | + # } |
| 123 | + # } |
| 124 | + # |
| 125 | + # On the one hand, this is a clear case of non-determinism. But on the other hand, I |
| 126 | + # feel it is obvious that a user does not care about the order of iteration |
| 127 | + # because... they are using unordered containers! |
| 128 | + - '-bugprone-nondeterministic-pointer-iteration-order' |
| 129 | + - '-cppcoreguidelines-pro-type-reinterpret-cast' |
| 130 | + # We don't use GSL |
| 131 | + - '-cppcoreguidelines-owning-memory' |
| 132 | + # Covered by modernize-use-override already |
| 133 | + - '-cppcoreguidelines-explicit-virtual-functions' |
| 134 | + # Covered by readability-magic-numbers |
| 135 | + - '-cppcoreguidelines-avoid-magic-numbers' |
| 136 | + # This check does more harm than good, as it appears to be very rudimentary. For |
| 137 | + # example, it emits warnings saying that: |
| 138 | + # |
| 139 | + # #define DEFINE_OPERATOR(op) \ |
| 140 | + # _CCCL_HOST_DEVICE custom_numeric operator op() const \ |
| 141 | + # { \ |
| 142 | + # return custom_numeric(op value[0]); \ |
| 143 | + # } |
| 144 | + # |
| 145 | + # Should be replaced by a template function, but this is not possible. We instead rely |
| 146 | + # on best judgment of reviewers to catch macros that can be functions. |
| 147 | + - '-cppcoreguidelines-macro-usage' |
| 148 | + # This check does not understand more complex macro usage where brackets are not allowed |
| 149 | + # |
| 150 | + # error: macro replacement list should be enclosed in parentheses [bugprone-macro-parentheses] |
| 151 | + # 36 | #define __THRUST_HOST_SYSTEM_INCLUDE(filename) <__THRUST_HOST_SYSTEM_ROOT/filename> |
| 152 | + # | ^ |
| 153 | + # | ( ) |
| 154 | + # |
| 155 | + # So better left disabled. |
| 156 | + - '-bugprone-macro-parentheses' |
| 157 | + # TODO: ironically enough, enable this someday |
| 158 | + - '-google-readability-todo' |
| 159 | + # Covered by modernize-avoid-c-style-cast, and also is buggier. It seems to fire on |
| 160 | + # `_v`-style constexpr bools as well sometimes. |
| 161 | + - '-google-readability-casting' |
| 162 | + # Covered by performance-noexcept-move-constructor |
| 163 | + - '-cppcoreguidelines-noexcept-move-operations' |
| 164 | + # REVIEW ME: This warns about any usage of operator[], suggesting usage of .at() instead. Could |
| 165 | + - '-cppcoreguidelines-pro-bounds-avoid-unchecked-container-access' |
| 166 | + # Covered by bugprone-narrowing-conversions |
| 167 | + - '-cppcoreguidelines-narrowing-conversions' |
| 168 | + # Covered by misc-unconventional-assign-operator |
| 169 | + - '-cppcoreguidelines-c-copy-assignment-signature' |
| 170 | + # Covered by performance-noexcept-swap |
| 171 | + - '-cppcoreguidelines-noexcept-swap' |
| 172 | + # Covered by modernize-use-default-member-init |
| 173 | + - '-cppcoreguidelines-use-default-member-init' |
| 174 | + # clang-tidy documentation says that for a given file, it matches the closest |
| 175 | + # .clang-tidy up the directory stack and applies the configuration from it. However, by |
| 176 | + # "it" `clang-tidy` means the closest `.clang-tidy` to the *source* file, not the file |
| 177 | + # that was included by the source file. |
| 178 | + # |
| 179 | + # So `cuda/std/foo.h` included by `cccl/foo/bar/baz.cpp` will never "match" against |
| 180 | + # `cccl/libcudacxx/.clang-tidy` because `clang-tidy` finds `cccl/.clang-tidy` instead. |
| 181 | + # |
| 182 | + # So we disable this for now. In the future we should add a custom check that bans |
| 183 | + # reserved identifiers except symbols from libcu++. |
| 184 | + - '-bugprone-reserved-identifier' |
| 185 | +WarningsAsErrors: '*' |
| 186 | +HeaderFileExtensions: |
| 187 | + - '' |
| 188 | + - h |
| 189 | + - hh |
| 190 | + - hpp |
| 191 | + - hxx |
| 192 | + - cuh |
| 193 | + - inl |
| 194 | + - ipp |
| 195 | +ImplementationFileExtensions: |
| 196 | + - c |
| 197 | + - cc |
| 198 | + - cpp |
| 199 | + - cxx |
| 200 | + - cu |
| 201 | +SystemHeaders: false |
| 202 | +ExtraArgsBefore: |
| 203 | + - '-Wno-unknown-warning-option' |
| 204 | + - '-Wno-error=unused-command-line-argument' |
| 205 | + # To match _CCCL_DOXYGEN_INVOKED |
| 206 | + - '-D_CCCL_CLANG_TIDY_INVOKED=1' |
| 207 | +CheckOptions: |
| 208 | + cert-dcl16-c.NewSuffixes: 'L;LL;LU;LLU' |
| 209 | + cert-err33-c.CheckedFunctions: '::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;' |
| 210 | + llvm-else-after-return.WarnOnUnfixable: 'false' |
| 211 | + cert-str34-c.DiagnoseSignedUnsignedCharComparisons: 'false' |
| 212 | + cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic: 'true' |
| 213 | + google-readability-braces-around-statements.ShortStatementLines: '1' |
| 214 | + llvm-qualified-auto.AddConstToQualified: 'false' |
| 215 | + llvm-else-after-return.WarnOnConditionVariables: 'false' |
| 216 | + cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField: 'false' |
| 217 | + performance-move-const-arg.CheckTriviallyCopyableMove: 'false' |
| 218 | + performance-inefficient-string-concatenation.StrictMode: 'true' |
| 219 | + readability-simplify-boolean-expr.ChainedConditionalReturn: 'true' |
| 220 | + readability-simplify-boolean-expr.ChainedConditionalAssignment: 'true' |
| 221 | + bugprone-dangling-handle.HandleClasses: '::cuda::std::span;::cuda::std::mdspan' |
| 222 | + bugprone-misplaced-widening-cast.CheckImplicitCasts: 'true' |
| 223 | + bugprone-unused-return-value.AllowCastToVoid: 'true' |
| 224 | + readability-enum-initial-value.AllowExplicitZeroFirstInitialValue: 'false' |
| 225 | + readability-enum-initial-value.AllowExplicitSequentialInitialValues: 'false' |
| 226 | + readability-redundant-access-specifiers.CheckFirstDeclaration: 'true' |
| 227 | + bugprone-lambda-function-name.IgnoreMacros: 'true' |
| 228 | + # readability-identifier-naming.ClassCase: 'lower_case' |
| 229 | + # readability-identifier-naming.UnionCase: 'lower_case' |
| 230 | + # readability-identifier-naming.ClassConstantCase: 'UPPER_CASE' |
| 231 | + # readability-identifier-naming.ClassIgnoredRegexp: 'tuple|has_.*|is_.*|as_.*|.*_tag|tag|.*_of' |
| 232 | + # readability-identifier-naming.ConstantMemberCase: 'UPPER_CASE' |
| 233 | + # readability-identifier-naming.ConstantMemberIgnoredRegexp: 'value' |
| 234 | + # readability-identifier-naming.EnumCase: 'lower_case' |
| 235 | + # readability-identifier-naming.EnumConstantCase: 'UPPER_CASE' |
| 236 | + # readability-identifier-naming.FunctionCase: 'lower_case' |
| 237 | + # readability-identifier-naming.GlobalConstantCase: 'UPPER_CASE' |
| 238 | + # readability-identifier-naming.GlobalConstantIgnoredRegexp: '.*_v' |
| 239 | + # readability-identifier-naming.LocalVariableCase: 'lower_case' |
| 240 | + # # We want to allow constexpr auto MY_VAL1 |
| 241 | + # readability-identifier-naming.LocalVariableIgnoredRegexp: '[A-Z_0-9]+' |
| 242 | + # readability-identifier-naming.MacroDefinitionCase: 'UPPER_CASE' |
| 243 | + # # We want to allow MY_MACRO_PRIVATE_1_ |
| 244 | + # readability-identifier-naming.MacroDefinitionIgnoredRegexp: '[A-Z_0-9]+' |
| 245 | + # readability-identifier-naming.NamespaceCase: 'lower_case' |
| 246 | + # readability-identifier-naming.PrivateMemberCase: 'lower_case' |
| 247 | + # readability-identifier-naming.PrivateMemberSuffix: '_' |
| 248 | + # readability-identifier-naming.PrivateMethodCase: 'lower_case' |
| 249 | + # readability-identifier-naming.PrivateMethodSuffix: '_' |
| 250 | + # readability-identifier-naming.ProtectedMemberCase: 'lower_case' |
| 251 | + # readability-identifier-naming.ProtectedMemberSuffix: '_' |
| 252 | + # readability-identifier-naming.ProtectedMethodCase: 'lower_case' |
| 253 | + # readability-identifier-naming.ProtectedMethodSuffix: '_' |
| 254 | + # readability-identifier-naming.PublicMethodCase: 'lower_case' |
| 255 | + # readability-identifier-naming.ScopedEnumCase: 'lower_case' |
| 256 | + # readability-identifier-naming.ScopedEnumConstantCase: 'UPPER_CASE' |
| 257 | + readability-magic-numbers.IgnoredIntegerValues: '0;1;2;3;4;5;6;7;8;9' |
| 258 | + # There are some single-argument functions that we would not like to ignore |
| 259 | + # (`to_string(bool provenance = false)` comes to mind), but setting this to false makes |
| 260 | + # clang-tidy warn on a bunch of "obvious" calls, like `set_dim(1)` or |
| 261 | + # `with_concurrent(true)`. |
| 262 | + bugprone-argument-comment.IgnoreSingleArgument: true |
| 263 | + bugprone-argument-comment.CommentBoolLiterals: true |
| 264 | + bugprone-argument-comment.CommentIntegerLiterals: true |
| 265 | + bugprone-argument-comment.CommentFloatLiterals: true |
| 266 | + bugprone-argument-comment.CommentStringLiterals: true |
| 267 | + bugprone-argument-comment.CommentCharacterLiterals: true |
| 268 | + bugprone-argument-comment.CommentUserDefinedLiterals: true |
| 269 | + bugprone-argument-comment.CommentNullPtrs: true |
| 270 | + cppcoreguidelines-macro-usage.AllowedRegexp: '^DEBUG_.*|THRUST_PP_.*|_CCCL.*_PP_.*' |
| 271 | + bugprone-reserved-identifier.AllowedIdentifiers: '^_CCCL.*' |
| 272 | +... |
0 commit comments