'\" t .\" Man page generated from reStructuredText .\" by the Docutils 0.23 manpage writer. . . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .TH "EXTRACLANGTOOLS" "1" "Jun 21, 2026" "22" "Extra Clang Tools" .SH NAME extraclangtools \- Extra Clang Tools Documentation .sp Welcome to the clang\-tools\-extra project which contains extra tools built using Clang\(aqs tooling APIs. .SH EXTRA CLANG TOOLS 22.1.8 RELEASE NOTES .INDENT 0.0 .IP \(bu 2 Introduction .IP \(bu 2 What\(aqs New in Extra Clang Tools 22.1.8? .INDENT 2.0 .IP \(bu 2 Major New Features .IP \(bu 2 Potentially Breaking Changes .IP \(bu 2 Improvements to clangd .INDENT 2.0 .IP \(bu 2 Compile flags .IP \(bu 2 Diagnostics .IP \(bu 2 Hover .IP \(bu 2 Cross\-references .IP \(bu 2 Inlay hints .IP \(bu 2 Call hierarchy .IP \(bu 2 Document symbols .IP \(bu 2 Code folding .IP \(bu 2 Code completion .IP \(bu 2 Code actions .IP \(bu 2 C++20 Modules support .IP \(bu 2 Miscellaneous .UNINDENT .IP \(bu 2 Improvements to clang\-doc .IP \(bu 2 Improvements to clang\-query .IP \(bu 2 Improvements to clang\-tidy .INDENT 2.0 .IP \(bu 2 New checks .IP \(bu 2 New check aliases .IP \(bu 2 Changes in existing checks .IP \(bu 2 Removed checks .IP \(bu 2 Miscellaneous .UNINDENT .IP \(bu 2 Improvements to include\-fixer .IP \(bu 2 Improvements to clang\-include\-fixer .IP \(bu 2 Improvements to modularize .IP \(bu 2 Improvements to pp\-trace .IP \(bu 2 Clang\-tidy Visual Studio plugin .UNINDENT .UNINDENT .sp Written by the LLVM Team \% .SS Introduction .sp This document contains the release notes for the Extra Clang Tools, part of the Clang release 22.1.8\&. Here we describe the status of the Extra Clang Tools in some detail, including major improvements from the previous release and new feature work. All LLVM releases may be downloaded from the LLVM releases web site \%\&. .sp For more information about Clang or LLVM, including information about the latest release, please see the Clang Web Site \% or the LLVM Web Site \%\&. .sp Note that if you are reading this file from a Git checkout or the main Clang web page, this document applies to the \fInext\fP release, not the current one. To see the release notes for a specific release, please see the releases page \%\&. .SS What\(aqs New in Extra Clang Tools 22.1.8? .sp Some of the major new features and improvements to Extra Clang Tools are listed here. Generic improvements to Extra Clang Tools as a whole or to its underlying infrastructure are described first, followed by tool\-specific sections. .SS Major New Features .SS Potentially Breaking Changes .INDENT 0.0 .IP \(bu 2 Deprecated the \fBclang\-tidy\fP \fBhicpp\fP module. All checks have been moved to other modules instead. The \fBhicpp\fP module will be removed for the 23.x release. .IP \(bu 2 Deprecated the \fBclang\-tidy\fP \fBzircon\fP module. All checks have been moved to the \fBfuchsia\fP module instead. The \fBzircon\fP module will be removed in the 24th release. .IP \(bu 2 Removed \fBclang\-tidy\fP\(aqs global options \fIIgnoreMacros\fP and \fIStrictMode\fP, which were documented as deprecated since \fBclang\-tidy\-20\fP\&. Users should use the check\-specific options of the same name instead. .IP \(bu 2 Removed \fIclang\-analyzer\-*\fP checks from default checks in \fBclang\-tidy\fP\&. From now on, users should specify explicitly that they want CSA checks to run in \fBclang\-tidy\fP via \fIclang\-analyzer\-*\fP\&. .IP \(bu 2 Renamed a few \fBclang\-tidy\fP check options, as they were misspelled: .INDENT 2.0 .IP \(bu 2 \fINamePrefixSuffixSilenceDissimilarityTreshold\fP to \fINamePrefixSuffixSilenceDissimilarityThreshold\fP in bugprone\-easily\-swappable\-parameters \%<> .IP \(bu 2 \fICharTypdefsToIgnore\fP to \fICharTypedefsToIgnore\fP in bugprone\-signed\-char\-misuse \%<> .UNINDENT .IP \(bu 2 Modified the custom message format of bugprone\-unsafe\-functions \%<> by assigning a special meaning to the character \fB>\fP at the start of the value of the option \fBCustomFunctions\fP\&. If the option value starts with \fB>\fP, then the replacement suggestion part of the message (which would be included by default) is omitted. (This does not change the warning locations.) .IP \(bu 2 \fBclang\-tidy\fP now displays warnings from all non\-system headers by default. Previously, users had to explicitly opt\-in to header warnings using \fI\-header\-filter=\(aq.*\(aq\fP\&. To disable warnings from non\-system, set \fI\-header\-filter\fP to an empty string. .IP \(bu 2 The \fBclang\-tidy/ClangTidyModuleRegistry.h\fP header has been deprecated and will be removed in LLVM 24. All of the symbols it used to define have been moved into \fBclang\-tidy/ClangTidyModule.h\fP\&. .UNINDENT .SS Improvements to clangd .SS Compile flags .INDENT 0.0 .IP \(bu 2 Added proper support for the \fB\-std=c++latest\fP flag, often used by Windows users writing C++23 code. .UNINDENT .SS Diagnostics .INDENT 0.0 .IP \(bu 2 Fixed a bug that caused the quick\-fix for the \fBreadability\-identifier\-naming\fP diagnostic not to work in some editors. .UNINDENT .SS Hover .INDENT 0.0 .IP \(bu 2 Added support for parsing and presenting doxygen and markdown documentation .IP \(bu 2 Added a \fBMacroContentsLimit\fP config option to allow users to opt into showing macro definitions in hovers even if they\(aqre very long .IP \(bu 2 Fixed a bug that prevented documentation from being shown for members of class templates defined in a header .IP \(bu 2 Fixed a bug that prevented documentation from being shown for abbreviated function templates .UNINDENT .SS Cross\-references .INDENT 0.0 .IP \(bu 2 Improved \(dqgo to definition\(dq support for dependent \fBauto\fP .IP \(bu 2 Improved \(dqgo to definition\(dq support for C++23 \(dqdeducing this\(dq .IP \(bu 2 Fixed a bug where attributes on a method broke various features including \(dqgo to definition\(dq on a method\(aqs name .IP \(bu 2 \(dqFind references\(dq on a constructor now finds call sites of forwarding functions such as \fBmake_unique\fP as well .IP \(bu 2 \(dqDocument links\(dq now supports \fB#include\fP directives with a macro argument .UNINDENT .SS Inlay hints .INDENT 0.0 .IP \(bu 2 Show designator hints for aggregate initialization of structures with parentheses\-list initialization (\fBCXXParenListInitExpr\fP) syntax. .IP \(bu 2 Show type hints for simple cases of dependent \fBauto\fP .UNINDENT .SS Call hierarchy .INDENT 0.0 .IP \(bu 2 Support invoking call hierarchy on enum constants .IP \(bu 2 When invoked on a virtual function, show callers of base functions as well .UNINDENT .SS Document symbols .INDENT 0.0 .IP \(bu 2 Include inline friend functions in document symbols .UNINDENT .SS Code folding .INDENT 0.0 .IP \(bu 2 Support folding of preprocessor branches .IP \(bu 2 Support folding of \fB#pragma region\fP blocks .UNINDENT .SS Code completion .INDENT 0.0 .IP \(bu 2 Added a new \fBMacroFilter\fP configuration option to \fBCompletion\fP to allow fuzzy\-matching with the \fBFuzzyMatch\fP option when suggesting macros. \fBExactPrefix\fP is the default, which retains previous behavior of suggesting macros which match the prefix exactly. .IP \(bu 2 Improved support for C++23 \(dqdeducing this\(dq .IP \(bu 2 Header insertion now checks \fBAngledHeaders\fP and \fBQuotedHeaders\fP against resolved rather than spelled paths, consistent with the existing behaviour of include\-cleaner diagnostics. .UNINDENT .SS Code actions .INDENT 0.0 .IP \(bu 2 New \fBOverride pure virtual methods\fP code action. When invoked on a class definition, this action automatically generates C++ \fBoverride\fP declarations for all pure virtual methods inherited from its base classes that have not yet been implemented. The generated method stubs prompts the user for the actual implementation. The overrides are intelligently grouped under their original access specifiers (e.g., \fBpublic\fP, \fBprotected\fP), creating new access specifier blocks if necessary. .IP \(bu 2 Improved the \(dqmove function body out\-of\-line\(dq code action\(aqs logic for choosing where to place the definition. It now tries to place it next to the definition of a method with an adjacent declaration. .UNINDENT .SS C++20 Modules support .INDENT 0.0 .IP \(bu 2 Fixed a crash when using \fB\-\-experimental\-modules\-support\fP without a compilation database .IP \(bu 2 Added a \fB\-\-debug\-modules\-builder\fP option to help debug clangd\(aqs modules support .IP \(bu 2 Improved diagnostics related to modules .IP \(bu 2 Clangd now tries to reuse a module from the project\(aqs build if it\(aqs suitable .UNINDENT .SS Miscellaneous .INDENT 0.0 .IP \(bu 2 Add wildcard \fB\&.gitignore\fP file to the clangd index directory. .UNINDENT .SS Improvements to clang\-doc .INDENT 0.0 .IP \(bu 2 Use the Mustache HTML generator as the default HTML option. .IP \(bu 2 Document concepts, typedefs, aliases, public class members, nested records, nested namespaces, global functions, global variables, protected methods and members and friends in HTML. .IP \(bu 2 Document \fBthrows\fP comments in HTML. .IP \(bu 2 Add definition location for classes in HTML. .IP \(bu 2 Show class template declaration in HTML. .IP \(bu 2 Add a top\-level index page in HTML. This page lists the top\-level namespaces and serves as the documentation\(aqs root URL. .IP \(bu 2 Add a \fBHome\fP button to the navigation bar which replaces non\-useful buttons. This new button links to the top\-level index page. .IP \(bu 2 Add a breadcrumb navigation bar to the navbar. This helps navigate through a documented entity\(aqs context. .IP \(bu 2 If a filename is too long, then the name will be truncated and the documented entity\(aqs USR will be concatenated to guarantee its uniqueness. .IP \(bu 2 Revert the flat directory structure to a nested directory structure. .UNINDENT .SS Improvements to clang\-query .INDENT 0.0 .IP \(bu 2 Matcher queries interpreted by clang\-query are now support trailing comma (,) in matcher arguments. Note that C++ still doesn\(aqt allow this in function arguments. So when porting a query to C++, remove all instances of trailing comma (otherwise C++ compiler will just complain about \(dqexpected expression\(dq). .UNINDENT .SS Improvements to clang\-tidy .INDENT 0.0 .IP \(bu 2 The \fBcheck_clang_tidy.py\fP tool now recognizes the \fB\-std\fP argument when run over C files. If \fB\-std\fP is not specified, it defaults to \fBc99\-or\-later\fP\&. .IP \(bu 2 \fBclang\-tidy\fP now displays warnings from all non\-system headers by default. Previously, users had to explicitly opt\-in to header warnings using \fI\-header\-filter=\(aq.*\(aq\fP\&. To disable warnings from non\-system, set \fI\-header\-filter\fP to an empty string. .IP \(bu 2 \fBclang\-tidy\fP no longer attempts to analyze code from system headers by default, greatly improving performance. This behavior is disabled if the \fISystemHeaders\fP option is enabled. .IP \(bu 2 \fBclang\-tidy\fP now supports query based custom checks by \fICustomChecks\fP configuration option. Query Based Custom Check Document \%<> .IP \(bu 2 The \fBrun\-clang\-tidy.py\fP and \fBclang\-tidy\-diff.py\fP scripts now run checks in parallel by default using all available hardware threads. Both scripts display the number of threads being used in their output. .IP \(bu 2 Improved \fBrun\-clang\-tidy.py\fP by adding a new option \fIenable\-check\-profile\fP to enable per\-check timing profiles and print a report based on all analyzed files. .IP \(bu 2 Improved documentation of the \fI\-line\-filter\fP command\-line flag of \fBclang\-tidy\fP and \fBrun\-clang\-tidy.py\fP\&. .IP \(bu 2 Improved \fBclang\-tidy\fP option \fI\-quiet\fP by suppressing diagnostic count messages. .IP \(bu 2 Improved \fBclang\-tidy\fP by not crashing when an empty \fIdirectory\fP field is used in a compilation database; the current working directory will be used instead, and an error message will be printed. .IP \(bu 2 Removed \fBclang\-tidy\fP\(aqs global options \fIIgnoreMacros\fP and \fIStrictMode\fP, which were documented as deprecated since \fBclang\-tidy\-20\fP\&. Users should use the check\-specific options of the same name instead. .IP \(bu 2 Improved \fBrun\-clang\-tidy.py\fP and \fBclang\-tidy\-diff.py\fP scripts by adding the \fI\-hide\-progress\fP option to suppress progress and informational messages. .IP \(bu 2 Removed \fIclang\-analyzer\-*\fP check from default checks in \fBclang\-tidy\fP\&. From now on, users should specify explicitly that they want CSA checks to run in \fBclang\-tidy\fP\&. .IP \(bu 2 Improved \fBclang\-tidy\fP by adding the \fI\-\-removed\-arg\fP option to remove arguments sent to the compiler when invoking Clang\-Tidy. This option was also added to \fBrun\-clang\-tidy.py\fP and \fBclang\-tidy\-diff.py\fP and can be configured in the config file through the \fIRemovedArgs\fP option. .IP \(bu 2 Deprecated the \fBclang\-tidy\fP \fBzircon\fP module. All checks have been moved to the \fBfuchsia\fP module instead. The \fBzircon\fP module will be removed in the 24th release. .IP \(bu 2 Improved \fBclang\-tidy\fP configuration parsing by allowing the same list syntax in \fIWarningsAsErrors\fP as in \fIChecks\fP\&. .UNINDENT .SS New checks .INDENT 0.0 .IP \(bu 2 New abseil\-unchecked\-statusor\-access \%<> check. .sp Finds uses of \fBabsl::StatusOr\fP without checking if a value is present. .IP \(bu 2 New bugprone\-derived\-method\-shadowing\-base\-method \%<> check. .sp Finds derived class methods that shadow a (non\-virtual) base class method. .IP \(bu 2 New bugprone\-invalid\-enum\-default\-initialization \%<> check. .sp Detects default initialization (to 0) of variables with \fBenum\fP type where the enum has no enumerator with value of 0. .IP \(bu 2 New cppcoreguidelines\-pro\-bounds\-avoid\-unchecked\-container\-access \%<> check. .sp Finds calls to \fBoperator[]\fP in STL containers and suggests replacing them with safe alternatives. .IP \(bu 2 New google\-runtime\-float \%<> check. .sp Finds uses of \fBlong double\fP and suggests against their use due to lack of portability. .IP \(bu 2 New llvm\-mlir\-op\-builder \%<> check. .sp Checks for uses of MLIR\(aqs old/to be deprecated \fBOpBuilder::create\fP form and suggests using \fBT::create\fP instead. .IP \(bu 2 New llvm\-use\-ranges \%<> check. .sp Finds calls to STL library iterator algorithms that could be replaced with LLVM range\-based algorithms from \fBllvm/ADT/STLExtras.h\fP\&. .IP \(bu 2 New misc\-override\-with\-different\-visibility \%<> check. .sp Finds virtual function overrides with different visibility than the function in the base class. .IP \(bu 2 New readability\-inconsistent\-ifelse\-braces \%<> check. .sp Detects \fBif\fP/\fBelse\fP statements where one branch uses braces and the other does not. .IP \(bu 2 New readability\-redundant\-parentheses \%<> check. .sp Detect redundant parentheses. .IP \(bu 2 New readability\-redundant\-typename \%<> check. .sp Finds redundant uses of the \fBtypename\fP keyword. .UNINDENT .SS New check aliases .INDENT 0.0 .IP \(bu 2 Renamed cert\-dcl50\-cpp \%<> to modernize\-avoid\-variadic\-functions \%<> keeping initial check as an alias to the new one. .IP \(bu 2 Renamed cert\-dcl58\-cpp \%<> to bugprone\-std\-namespace\-modification \%<> keeping initial check as an alias to the new one. .IP \(bu 2 Renamed cert\-env33\-c \%<> to bugprone\-command\-processor \%<> keeping initial check as an alias to the new one. .IP \(bu 2 Renamed cert\-err34\-c \%<> to bugprone\-unchecked\-string\-to\-number\-conversion \%<> keeping initial check as an alias to the new one. .IP \(bu 2 Renamed cert\-err52\-cpp \%<> to modernize\-avoid\-setjmp\-longjmp \%<> keeping initial check as an alias to the new one. .IP \(bu 2 Renamed cert\-err58\-cpp \%<> to bugprone\-throwing\-static\-initialization \%<> keeping initial check as an alias to the new one. .IP \(bu 2 Renamed cert\-err60\-cpp \%<> to bugprone\-exception\-copy\-constructor\-throws \%<> .IP \(bu 2 Renamed cert\-flp30\-c \%<> to bugprone\-float\-loop\-counter \%<> keeping initial check as an alias to the new one. .IP \(bu 2 Renamed cert\-mem57\-cpp \%<> to bugprone\-default\-operator\-new\-on\-overaligned\-type \%<> keeping initial check as an alias to the new one. .IP \(bu 2 Renamed cert\-msc30\-c \%<> to misc\-predictable\-rand \%<> keeping initial check as an alias to the new one. .IP \(bu 2 Renamed cert\-msc32\-c \%<> to bugprone\-random\-generator\-seed \%<> keeping initial check as an alias to the new one. .IP \(bu 2 Renamed cert\-msc50\-cpp \%<> to misc\-predictable\-rand \%<> keeping initial check as an alias to the new one. .IP \(bu 2 Renamed cert\-msc51\-cpp \%<> to bugprone\-random\-generator\-seed \%<> keeping initial check as an alias to the new one. .IP \(bu 2 Renamed cert\-oop57\-cpp \%<> to bugprone\-raw\-memory\-call\-on\-non\-trivial\-type \%<> keeping initial check as an alias to the new one. .IP \(bu 2 Renamed cert\-oop58\-cpp \%<> to bugprone\-copy\-constructor\-mutates\-argument \%<> keeping initial check as an alias to the new one. .IP \(bu 2 Renamed fuchsia\-multiple\-inheritance \%<> to misc\-multiple\-inheritance \%<> keeping initial check as an alias to the new one. .IP \(bu 2 Renamed google\-build\-namespaces \%<> to misc\-anonymous\-namespace\-in\-header \%<> keeping initial check as an alias to the new one. .IP \(bu 2 Renamed google\-readability\-casting \%<> to modernize\-avoid\-c\-style\-cast \%<> keeping initial check as an alias to the new one. .UNINDENT .SS Changes in existing checks .INDENT 0.0 .IP \(bu 2 Improved bugprone\-chained\-comparison \%<> check by adding a new option \fIIgnoreMacros\fP to suppress warnings within macro expansions. .IP \(bu 2 Improved bugprone\-dynamic\-static\-initializers \%<> check: .INDENT 2.0 .IP \(bu 2 Avoided false positives for \fBconstexpr\fP variables whose initializers are value\-dependent. .IP \(bu 2 Added support for C++20 \fBconstinit\fP variables. .UNINDENT .IP \(bu 2 Improved bugprone\-easily\-swappable\-parameters \%<> check by correcting a spelling mistake on its option \fBNamePrefixSuffixSilenceDissimilarityTreshold\fP\&. .IP \(bu 2 Improved bugprone\-exception\-escape \%<> check: .INDENT 2.0 .IP \(bu 2 Exceptions from lambda captures are now diagnosed, exceptions in the bodies of lambdas that aren\(aqt actually invoked are not. .IP \(bu 2 Fixed an issue where the check wouldn\(aqt diagnose throws in arguments to functions or constructors. .IP \(bu 2 Added fine\-grained configuration via options \fICheckDestructors\fP, \fICheckMoveMemberFunctions\fP, \fICheckMain\fP, \fICheckedSwapFunctions\fP, and \fICheckNothrowFunctions\fP\&. .UNINDENT .IP \(bu 2 Improved bugprone\-infinite\-loop \%<> check by adding detection for variables introduced by structured bindings. .IP \(bu 2 Improved bugprone\-invalid\-enum\-default\-initialization \%<> with new \fIIgnoredEnums\fP option to ignore specified enums during analysis. .IP \(bu 2 Improved bugprone\-macro\-parentheses \%<> check by fixing false positives when using C++ template parameters. .IP \(bu 2 Improved bugprone\-narrowing\-conversions \%<> check by fixing false positive from analysis of a conditional expression in C. .IP \(bu 2 Improved bugprone\-not\-null\-terminated\-result \%<> check by fixing bogus fix\-its for \fBstrncmp\fP and \fBwcsncmp\fP on Windows and a crash caused by certain value\-dependent expressions. .IP \(bu 2 Improved bugprone\-reserved\-identifier \%<> check by ignoring declarations and macros in system headers. .IP \(bu 2 Improved bugprone\-signed\-char\-misuse \%<> check by fixing false positives on C23 enums with the fixed underlying type of signed char. .IP \(bu 2 Improved bugprone\-sizeof\-expression \%<> check by fixing a crash on \fBsizeof\fP of an array of dependent type. .IP \(bu 2 Improved bugprone\-suspicious\-include \%<> check by adding \fIIgnoredRegex\fP option. .IP \(bu 2 Improved bugprone\-tagged\-union\-member\-count \%<> by fixing a false positive when enums or unions from system header files or the \fBstd\fP namespace are treated as the tag or the data part of a user\-defined tagged union respectively. .IP \(bu 2 Improved bugprone\-throw\-keyword\-missing \%<> check: .INDENT 2.0 .IP \(bu 2 Now it only considers the canonical types of base classes as written. .IP \(bu 2 Added a note on the base class that triggered the warning. .IP \(bu 2 Fixed an issue where the check wouldn\(aqt fire in constructors or (in certain contexts) lambdas. .UNINDENT .IP \(bu 2 Improved bugprone\-unchecked\-optional\-access \%<> check: .INDENT 2.0 .IP \(bu 2 Added support for \fBNullableValue::makeValue\fP and \fBNullableValue::makeValueInplace\fP to prevent false\-positives for \fBBloombergLP::bdlb::NullableValue\fP\&. .IP \(bu 2 Fixed false\-positives for \fBbsl::optional\fP containing allocator\-aware type. .IP \(bu 2 Added the \fIIgnoreValueCalls\fP option to suppress diagnostics for \fBoptional::value()\fP\&. .IP \(bu 2 Added the \fIIgnoreSmartPointerDereference\fP option to ignore optionals reached via smart\-pointer\-like dereference, while still diagnosing UB\-prone dereferences via \fBoperator*\fP and \fBoperator\->\fP\&. .UNINDENT .IP \(bu 2 Improved bugprone\-unhandled\-self\-assignment \%<> check by adding an additional matcher that generalizes the copy\-and\-swap idiom pattern detection. .IP \(bu 2 Improved bugprone\-unsafe\-functions \%<> check by hiding the default suffix when the reason starts with the character \fI>\fP in the \fICustomFunctions\fP option. .IP \(bu 2 Improved bugprone\-use\-after\-move \%<> check: .INDENT 2.0 .IP \(bu 2 Added \fIInvalidationFunctions\fP option to support custom invalidation functions. .IP \(bu 2 Added \fIReinitializationFunctions\fP option to support custom reinitialization functions. .UNINDENT .IP \(bu 2 Improved cppcoreguidelines\-avoid\-non\-const\-global\-variables \%<> check by adding a new option \fIAllowThreadLocal\fP that suppresses warnings on non\-const global variables with thread\-local storage duration. .IP \(bu 2 Improved cppcoreguidelines\-init\-variables \%<> check by fixing the insertion location for function pointers with multiple parameters. .IP \(bu 2 Improved cppcoreguidelines\-macro\-usage \%<> check by excluding macro bodies that starts with \fB__attribute__((..))\fP keyword. Such a macro body is unlikely a proper expression and so suggesting users an impossible rewrite into a template function should be avoided. .IP \(bu 2 Improved cppcoreguidelines\-prefer\-member\-initializer \%<> check to avoid false positives on inherited members in class templates. .IP \(bu 2 Improved cppcoreguidelines\-pro\-bounds\-pointer\-arithmetic \%<> check adding \fIAllowIncrementDecrementOperators\fP option to allow pointer arithmetic via prefix/postfix increment or decrement operators. .IP \(bu 2 Improved cppcoreguidelines\-pro\-type\-member\-init \%<> check to correctly ignore \fBstd::array\fP and other array\-like containers when \fIIgnoreArrays\fP option is set to \fItrue\fP\&. .IP \(bu 2 Improved fuchsia\-multiple\-inheritance \%<> by fixing an issue where the check would only analyze the first class with a given name in the program, missing any subsequent classes with that same name (declared in a different scope). .IP \(bu 2 Improved google\-readability\-casting \%<> check by adding fix\-it notes for downcasts and casts to void pointer. .IP \(bu 2 Improved google\-readability\-todo \%<> check to accept the new TODO format from the Google Style Guide. .IP \(bu 2 Improved llvm\-prefer\-isa\-or\-dyn\-cast\-in\-conditionals \%<> check: .INDENT 2.0 .IP \(bu 2 Fix\-it handles callees with nested\-name\-specifier correctly. .IP \(bu 2 \fBif\fP statements with init\-statement (\fBif (auto X = ...; ...)\fP) are handled correctly. .IP \(bu 2 \fBfor\fP loops are supported. .UNINDENT .IP \(bu 2 Improved misc\-const\-correctness \%<> check: .INDENT 2.0 .IP \(bu 2 Fixed false positives when pointers is transferred to non\-const references. .IP \(bu 2 Fixed false positives of function pointer, on return of non\-const pointer, on pointer\-to\-member operator. .IP \(bu 2 Fixed false positives when the address of a variable is taken to be passed to a function. .UNINDENT .IP \(bu 2 Improved misc\-coroutine\-hostile\-raii \%<> check by adding the option \fIAllowedCallees\fP, that allows exempting safely awaitable callees from the check. .IP \(bu 2 Improved misc\-header\-include\-cycle \%<> check performance. .IP \(bu 2 Improved misc\-use\-internal\-linkage \%<> check: .INDENT 2.0 .IP \(bu 2 Added suggestion of internal linkage for user\-defined types (structs, classes, unions, and enums). .IP \(bu 2 Added fine\-grained options \fIAnalyzeFunctions\fP, \fIAnalyzeVariables\fP, \fIAnalyzeTypes\fP to control whether the check should diagnose functions, variables, and/or user\-defined types. .IP \(bu 2 Enabled the check for C. .UNINDENT .IP \(bu 2 Improved modernize\-avoid\-c\-arrays \%<> to not diagnose array types which are part of an implicit instantiation of a template. .IP \(bu 2 Improved modernize\-use\-constraints \%<> check by fixing a crash on uses of non\-standard \fBenable_if\fP with a signature different from \fBstd::enable_if\fP (such as \fBboost::enable_if\fP). .IP \(bu 2 Improved modernize\-use\-default\-member\-init \%<> check to enhance the robustness of the member initializer detection. .IP \(bu 2 Improved modernize\-use\-designated\-initializers \%<> check to suggest using designated initializers for aliased aggregate types. .IP \(bu 2 Improved modernize\-use\-integer\-sign\-comparison \%<> by providing correct fix\-its when the right\-hand side of a comparison contains a non\-C\-style cast. .IP \(bu 2 Improved modernize\-use\-nullptr \%<> check by fixing a crash on Windows when the check was enabled with a 32\-bit \fBclang\-tidy\fP binary. .IP \(bu 2 Improved modernize\-use\-override \%<> by fixing an issue where the check would sometimes suggest inserting \fBoverride\fP in an invalid place. .IP \(bu 2 Improved modernize\-use\-ranges \%<> check to suggest using the more idiomatic \fBstd::views::reverse\fP where it used to suggest \fBstd::ranges::reverse_view\fP\&. .IP \(bu 2 Improved modernize\-use\-scoped\-lock \%<> check by fixing a crash on malformed code (common when using \fBclang\-tidy\fP through \fBclangd\fP). .IP \(bu 2 Improved modernize\-use\-std\-format \%<> check to correctly match when the format string is converted to a different type by an implicit constructor call. .IP \(bu 2 Improved modernize\-use\-std\-print \%<> check to correctly match when the format string is converted to a different type by an implicit constructor call, and fixed a crash when handling format strings containing non\-ASCII characters. .IP \(bu 2 Improved modernize\-use\-using \%<> check to correctly provide fix\-its for typedefs of pointers or references to array types. .IP \(bu 2 Improved performance\-move\-const\-arg \%<> check by avoiding false positives on trivially copyable types with a non\-public copy constructor. .IP \(bu 2 Improved performance\-unnecessary\-copy\-initialization \%<> by printing the type of the diagnosed variable. .IP \(bu 2 Improved performance\-unnecessary\-value\-param \%<> by printing the type of the diagnosed variable and correctly generating fix\-it hints for parameter\-pack arguments. .IP \(bu 2 Improved portability\-template\-virtual\-member\-function \%<> check to avoid false positives on pure virtual member functions. .IP \(bu 2 Improved readability\-container\-contains \%<> to support string comparisons to \fBnpos\fP\&. Internal changes may cause new rare false positives in non\-standard containers. .IP \(bu 2 Improved readability\-container\-data\-pointer \%<> check by correctly adding parentheses when the container expression is a dereference. .IP \(bu 2 Improved readability\-container\-size\-empty \%<> check by correctly generating fix\-it hints when size method is called from implicit \fBthis\fP, ignoring default constructors with user provided arguments and adding detection in container\(aqs method except \fBempty\fP\&. .IP \(bu 2 Improved readability\-duplicate\-include \%<> check by adding the \fBIgnoredFilesList\fP option (semicolon\-separated list of regexes or filenames) to allow intentional duplicates. .IP \(bu 2 Improved readability\-identifier\-naming \%<> check: .INDENT 2.0 .IP \(bu 2 Now ignores declarations and macros in system headers. .IP \(bu 2 The documentation is improved to differentiate the general options from the specific ones. .IP \(bu 2 Options for fine\-grained control over \fBconstexpr\fP variables were added. .IP \(bu 2 Added default options which simplify configs by removing the need to specify each identifier kind separately. .UNINDENT .IP \(bu 2 Improved readability\-implicit\-bool\-conversion \%<> check: .INDENT 2.0 .IP \(bu 2 Now correctly adds parentheses when inner expressions are implicitly converted multiple times. .IP \(bu 2 Enabled the check for C99 and later standards. .IP \(bu 2 Now allows implicit conversions from \fBbool\fP to integer when used as operands of logical operators (\fB&&\fP, \fB||\fP) in C. .UNINDENT .IP \(bu 2 Improved readability\-inconsistent\-declaration\-parameter\-name \%<> check by not enforcing parameter name consistency between a variadic parameter pack in the primary template and specific parameters in its specializations. .IP \(bu 2 Improved readability\-math\-missing\-parentheses \%<> check by correctly diagnosing operator precedence issues inside parenthesized expressions. .IP \(bu 2 Improved readability\-qualified\-auto \%<> check by adding the option \fIIgnoreAliasing\fP, that allows not looking at underlying types of type aliases. .IP \(bu 2 Improved readability\-redundant\-casting \%<> check by fixing false negatives when explicitly cast from function pointer. .IP \(bu 2 Improved readability\-redundant\-control\-flow \%<> by fixing an issue where the check would sometimes suggest deleting not only a redundant \fBreturn\fP or \fBcontinue\fP, but also unrelated lines preceding it. .IP \(bu 2 Improved readability\-uppercase\-literal\-suffix \%<> check to recognize literal suffixes added in C++23 and C23. .IP \(bu 2 Improved readability\-use\-concise\-preprocessor\-directives \%<> check to generate correct fix\-its for forms without a space after the directive. .IP \(bu 2 Improved readability\-use\-std\-min\-max \%<> check by ensuring that comments between the \fBif\fP condition and the \fBthen\fP block are preserved when applying the fix. .UNINDENT .SS Removed checks .SS Miscellaneous .SS Improvements to include\-fixer .sp The improvements are... .SS Improvements to clang\-include\-fixer .sp The improvements are... .SS Improvements to modularize .sp The improvements are... .SS Improvements to pp\-trace .SS Clang\-tidy Visual Studio plugin .SH CLANG-TIDY .SS Contents .INDENT 0.0 .IP \(bu 2 Clang\-Tidy .INDENT 2.0 .IP \(bu 2 Using Clang\-Tidy .IP \(bu 2 Clang\-Tidy Automation .INDENT 2.0 .IP \(bu 2 Running Clang\-Tidy in Parallel .IP \(bu 2 Running Clang\-Tidy on Diff .UNINDENT .IP \(bu 2 Suppressing Undesired Diagnostics .UNINDENT .UNINDENT .sp See also: .SS Clang\-Tidy Checks .SS abseil\-cleanup\-ctad .sp Suggests switching the initialization pattern of \fBabsl::Cleanup\fP instances from the factory function to class template argument deduction (CTAD), in C++17 and higher. .INDENT 0.0 .INDENT 3.5 .sp .EX auto c1 = absl::MakeCleanup([] {}); const auto c2 = absl::MakeCleanup(std::function([] {})); .EE .UNINDENT .UNINDENT .sp becomes .INDENT 0.0 .INDENT 3.5 .sp .EX absl::Cleanup c1 = [] {}; const absl::Cleanup c2 = std::function([] {}); .EE .UNINDENT .UNINDENT .SS abseil\-duration\-addition .sp Checks for cases where addition should be performed in the \fBabsl::Time\fP domain. When adding two values, and one is known to be an \fBabsl::Time\fP, we can infer that the other should be interpreted as an \fBabsl::Duration\fP of a similar scale, and make that inference explicit. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX // Original \- Addition in the integer domain int x; absl::Time t; int result = absl::ToUnixSeconds(t) + x; // Suggestion \- Addition in the absl::Time domain int result = absl::ToUnixSeconds(t + absl::Seconds(x)); .EE .UNINDENT .UNINDENT .SS abseil\-duration\-comparison .sp Checks for comparisons which should be in the \fBabsl::Duration\fP domain instead of the floating point or integer domains. .sp N.B.: In cases where a \fBDuration\fP was being converted to an integer and then compared against a floating\-point value, truncation during the \fBDuration\fP conversion might yield a different result. In practice this is very rare, and still indicates a bug which should be fixed. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX // Original \- Comparison in the floating point domain double x; absl::Duration d; if (x < absl::ToDoubleSeconds(d)) ... // Suggested \- Compare in the absl::Duration domain instead if (absl::Seconds(x) < d) ... // Original \- Comparison in the integer domain int x; absl::Duration d; if (x < absl::ToInt64Microseconds(d)) ... // Suggested \- Compare in the absl::Duration domain instead if (absl::Microseconds(x) < d) ... .EE .UNINDENT .UNINDENT .SS abseil\-duration\-conversion\-cast .sp Checks for casts of \fBabsl::Duration\fP conversion functions, and recommends the right conversion function instead. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX // Original \- Cast from a double to an integer absl::Duration d; int i = static_cast(absl::ToDoubleSeconds(d)); // Suggested \- Use the integer conversion function directly. int i = absl::ToInt64Seconds(d); // Original \- Cast from a double to an integer absl::Duration d; double x = static_cast(absl::ToInt64Seconds(d)); // Suggested \- Use the integer conversion function directly. double x = absl::ToDoubleSeconds(d); .EE .UNINDENT .UNINDENT .sp Note: In the second example, the suggested fix could yield a different result, as the conversion to integer could truncate. In practice, this is very rare, and you should use \fBabsl::Trunc\fP to perform this operation explicitly instead. .SS abseil\-duration\-division .sp \fBabsl::Duration\fP arithmetic works like it does with integers. That means that division of two \fBabsl::Duration\fP objects returns an \fBint64\fP with any fractional component truncated toward 0. See this link \% for more information on arithmetic with \fBabsl::Duration\fP\&. .sp For example: .INDENT 0.0 .INDENT 3.5 .sp .EX absl::Duration d = absl::Seconds(3.5); int64 sec1 = d / absl::Seconds(1); // Truncates toward 0. int64 sec2 = absl::ToInt64Seconds(d); // Equivalent to division. assert(sec1 == 3 && sec2 == 3); double dsec = d / absl::Seconds(1); // WRONG: Still truncates toward 0. assert(dsec == 3.0); .EE .UNINDENT .UNINDENT .sp If you want floating\-point division, you should use either the \fBabsl::FDivDuration()\fP function, or one of the unit conversion functions such as \fBabsl::ToDoubleSeconds()\fP\&. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX absl::Duration d = absl::Seconds(3.5); double dsec1 = absl::FDivDuration(d, absl::Seconds(1)); // GOOD: No truncation. double dsec2 = absl::ToDoubleSeconds(d); // GOOD: No truncation. assert(dsec1 == 3.5 && dsec2 == 3.5); .EE .UNINDENT .UNINDENT .sp This check looks for uses of \fBabsl::Duration\fP division that is done in a floating\-point context, and recommends the use of a function that returns a floating\-point value. .SS abseil\-duration\-factory\-float .sp Checks for cases where the floating\-point overloads of various \fBabsl::Duration\fP factory functions are called when the more\-efficient integer versions could be used instead. .sp This check will not suggest fixes for literals which contain fractional floating point values or non\-literals. It will suggest removing superfluous casts. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX // Original \- Providing a floating\-point literal. absl::Duration d = absl::Seconds(10.0); // Suggested \- Use an integer instead. absl::Duration d = absl::Seconds(10); // Original \- Explicitly casting to a floating\-point type. absl::Duration d = absl::Seconds(static_cast(10)); // Suggested \- Remove the explicit cast absl::Duration d = absl::Seconds(10); .EE .UNINDENT .UNINDENT .SS abseil\-duration\-factory\-scale .sp Checks for cases where arguments to \fBabsl::Duration\fP factory functions are scaled internally and could be changed to a different factory function. This check also looks for arguments with a zero value and suggests using \fBabsl::ZeroDuration()\fP instead. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX // Original \- Internal multiplication. int x; absl::Duration d = absl::Seconds(60 * x); // Suggested \- Use absl::Minutes instead. absl::Duration d = absl::Minutes(x); // Original \- Internal division. int y; absl::Duration d = absl::Milliseconds(y / 1000.); // Suggested \- Use absl:::Seconds instead. absl::Duration d = absl::Seconds(y); // Original \- Zero\-value argument. absl::Duration d = absl::Hours(0); // Suggested = Use absl::ZeroDuration instead absl::Duration d = absl::ZeroDuration(); .EE .UNINDENT .UNINDENT .SS abseil\-duration\-subtraction .sp Checks for cases where subtraction should be performed in the \fBabsl::Duration\fP domain. When subtracting two values, and the first one is known to be a conversion from \fBabsl::Duration\fP, we can infer that the second should also be interpreted as an \fBabsl::Duration\fP, and make that inference explicit. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX // Original \- Subtraction in the double domain double x; absl::Duration d; double result = absl::ToDoubleSeconds(d) \- x; // Suggestion \- Subtraction in the absl::Duration domain instead double result = absl::ToDoubleSeconds(d \- absl::Seconds(x)); // Original \- Subtraction of two Durations in the double domain absl::Duration d1, d2; double result = absl::ToDoubleSeconds(d1) \- absl::ToDoubleSeconds(d2); // Suggestion \- Subtraction in the absl::Duration domain instead double result = absl::ToDoubleSeconds(d1 \- d2); .EE .UNINDENT .UNINDENT .sp Note: As with other \fBclang\-tidy\fP checks, it is possible that multiple fixes may overlap (as in the case of nested expressions), so not all occurrences can be transformed in one run. In particular, this may occur for nested subtraction expressions. Running \fBclang\-tidy\fP multiple times will find and fix these overlaps. .SS abseil\-duration\-unnecessary\-conversion .sp Finds and fixes cases where \fBabsl::Duration\fP values are being converted to numeric types and back again. .sp Floating\-point examples: .INDENT 0.0 .INDENT 3.5 .sp .EX // Original \- Conversion to double and back again absl::Duration d1; absl::Duration d2 = absl::Seconds(absl::ToDoubleSeconds(d1)); // Suggestion \- Remove unnecessary conversions absl::Duration d2 = d1; // Original \- Division to convert to double and back again absl::Duration d2 = absl::Seconds(absl::FDivDuration(d1, absl::Seconds(1))); // Suggestion \- Remove division and conversion absl::Duration d2 = d1; .EE .UNINDENT .UNINDENT .sp Integer examples: .INDENT 0.0 .INDENT 3.5 .sp .EX // Original \- Conversion to integer and back again absl::Duration d1; absl::Duration d2 = absl::Hours(absl::ToInt64Hours(d1)); // Suggestion \- Remove unnecessary conversions absl::Duration d2 = d1; // Original \- Integer division followed by conversion absl::Duration d2 = absl::Seconds(d1 / absl::Seconds(1)); // Suggestion \- Remove division and conversion absl::Duration d2 = d1; .EE .UNINDENT .UNINDENT .sp Unwrapping scalar operations: .INDENT 0.0 .INDENT 3.5 .sp .EX // Original \- Multiplication by a scalar absl::Duration d1; absl::Duration d2 = absl::Seconds(absl::ToInt64Seconds(d1) * 2); // Suggestion \- Remove unnecessary conversion absl::Duration d2 = d1 * 2; .EE .UNINDENT .UNINDENT .sp Note: Converting to an integer and back to an \fBabsl::Duration\fP might be a truncating operation if the value is not aligned to the scale of conversion. In the rare case where this is the intended result, callers should use \fBabsl::Trunc\fP to truncate explicitly. .SS abseil\-faster\-strsplit\-delimiter .sp Finds instances of \fBabsl::StrSplit()\fP or \fBabsl::MaxSplits()\fP where the delimiter is a single character string literal and replaces with a character. The check will offer a suggestion to change the string literal into a character. It will also catch code using \fBabsl::ByAnyChar()\fP for just a single character and will transform that into a single character as well. .sp These changes will give the same result, but using characters rather than single character string literals is more efficient and readable. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX // Original \- the argument is a string literal. for (auto piece : absl::StrSplit(str, \(dqB\(dq)) { // Suggested \- the argument is a character, which causes the more efficient // overload of absl::StrSplit() to be used. for (auto piece : absl::StrSplit(str, \(aqB\(aq)) { // Original \- the argument is a string literal inside absl::ByAnyChar call. for (auto piece : absl::StrSplit(str, absl::ByAnyChar(\(dqB\(dq))) { // Suggested \- the argument is a character, which causes the more efficient // overload of absl::StrSplit() to be used and we do not need absl::ByAnyChar // anymore. for (auto piece : absl::StrSplit(str, \(aqB\(aq)) { // Original \- the argument is a string literal inside absl::MaxSplits call. for (auto piece : absl::StrSplit(str, absl::MaxSplits(\(dqB\(dq, 1))) { // Suggested \- the argument is a character, which causes the more efficient // overload of absl::StrSplit() to be used. for (auto piece : absl::StrSplit(str, absl::MaxSplits(\(aqB\(aq, 1))) { .EE .UNINDENT .UNINDENT .SS abseil\-no\-internal\-dependencies .sp Warns if code using Abseil depends on internal details. If something is in a namespace that includes the word \(dqinternal\(dq, code is not allowed to depend upon it because it\(aqs an implementation detail. They cannot friend it, include it, you mention it or refer to it in any way. Doing so violates Abseil\(aqs compatibility guidelines and may result in breakage. See \% for more information. .sp The following cases will result in warnings: .INDENT 0.0 .INDENT 3.5 .sp .EX absl::strings_internal::foo(); // warning triggered on this line class foo { friend struct absl::container_internal::faa; // warning triggered on this line }; absl::memory_internal::MakeUniqueResult(); // warning triggered on this line .EE .UNINDENT .UNINDENT .SS abseil\-no\-namespace .sp Ensures code does not open \fBnamespace absl\fP as that violates Abseil\(aqs compatibility guidelines. Code should not open \fBnamespace absl\fP as that conflicts with Abseil\(aqs compatibility guidelines and may result in breakage. .sp Any code that uses: .INDENT 0.0 .INDENT 3.5 .sp .EX namespace absl { ... } .EE .UNINDENT .UNINDENT .sp will be prompted with a warning. .sp See the full Abseil compatibility guidelines \% for more information. .SS abseil\-redundant\-strcat\-calls .sp Suggests removal of unnecessary calls to \fBabsl::StrCat\fP when the result is being passed to another call to \fBabsl::StrCat\fP or \fBabsl::StrAppend\fP\&. .sp The extra calls cause unnecessary temporary strings to be constructed. Removing them makes the code smaller and faster. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX std::string s = absl::StrCat(\(dqA\(dq, absl::StrCat(\(dqB\(dq, absl::StrCat(\(dqC\(dq, \(dqD\(dq))); //before std::string s = absl::StrCat(\(dqA\(dq, \(dqB\(dq, \(dqC\(dq, \(dqD\(dq); //after absl::StrAppend(&s, absl::StrCat(\(dqE\(dq, \(dqF\(dq, \(dqG\(dq)); //before absl::StrAppend(&s, \(dqE\(dq, \(dqF\(dq, \(dqG\(dq); //after .EE .UNINDENT .UNINDENT .SS abseil\-str\-cat\-append .sp Flags uses of \fBabsl::StrCat()\fP to append to a \fBstd::string\fP\&. Suggests \fBabsl::StrAppend()\fP should be used instead. .sp The extra calls cause unnecessary temporary strings to be constructed. Removing them makes the code smaller and faster. .INDENT 0.0 .INDENT 3.5 .sp .EX a = absl::StrCat(a, b); // Use absl::StrAppend(&a, b) instead. .EE .UNINDENT .UNINDENT .sp Does not diagnose cases where \fBabsl::StrCat()\fP is used as a template argument for a functor. .SS abseil\-string\-find\-startswith .sp Checks whether a \fBstd::string::find()\fP or \fBstd::string::rfind()\fP (and corresponding \fBstd::string_view\fP methods) result is compared with 0, and suggests replacing with \fBabsl::StartsWith()\fP\&. This is both a readability and performance issue. .sp \fBstarts_with\fP was added as a built\-in function on those types in C++20. If available, prefer enabling modernize\-use\-starts\-ends\-with \%<> instead of this check. .INDENT 0.0 .INDENT 3.5 .sp .EX string s = \(dq...\(dq; if (s.find(\(dqHello World\(dq) == 0) { /* do something */ } if (s.rfind(\(dqHello World\(dq, 0) == 0) { /* do something */ } .EE .UNINDENT .UNINDENT .sp becomes .INDENT 0.0 .INDENT 3.5 .sp .EX string s = \(dq...\(dq; if (absl::StartsWith(s, \(dqHello World\(dq)) { /* do something */ } if (absl::StartsWith(s, \(dqHello World\(dq)) { /* do something */ } .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B StringLikeClasses Semicolon\-separated list of names of string\-like classes. By default both \fBstd::basic_string\fP and \fBstd::basic_string_view\fP are considered. The list of methods to be considered is fixed. .UNINDENT .INDENT 0.0 .TP .B IncludeStyle A string specifying which include\-style is used, \fIllvm\fP or \fIgoogle\fP\&. Default is \fIllvm\fP\&. .UNINDENT .INDENT 0.0 .TP .B AbseilStringsMatchHeader The location of Abseil\(aqs \fBstrings/match.h\fP\&. Defaults to \fBabsl/strings/match.h\fP\&. .UNINDENT .SS abseil\-string\-find\-str\-contains .sp Finds \fBs.find(...) == string::npos\fP comparisons (for various string\-like types) and suggests replacing with \fBabsl::StrContains()\fP\&. .sp This improves readability and reduces the likelihood of accidentally mixing \fBfind()\fP and \fBnpos\fP from different string\-like types. .sp By default, \(dqstring\-like types\(dq includes \fB::std::basic_string\fP, \fB::std::basic_string_view\fP, and \fB::absl::string_view\fP\&. See the StringLikeClasses option to change this. .INDENT 0.0 .INDENT 3.5 .sp .EX std::string s = \(dq...\(dq; if (s.find(\(dqHello World\(dq) == std::string::npos) { /* do something */ } absl::string_view a = \(dq...\(dq; if (absl::string_view::npos != a.find(\(dqHello World\(dq)) { /* do something */ } .EE .UNINDENT .UNINDENT .sp becomes .INDENT 0.0 .INDENT 3.5 .sp .EX std::string s = \(dq...\(dq; if (!absl::StrContains(s, \(dqHello World\(dq)) { /* do something */ } absl::string_view a = \(dq...\(dq; if (absl::StrContains(a, \(dqHello World\(dq)) { /* do something */ } .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B StringLikeClasses Semicolon\-separated list of names of string\-like classes. By default includes \fB::std::basic_string\fP, \fB::std::basic_string_view\fP, and \fB::absl::string_view\fP\&. .UNINDENT .INDENT 0.0 .TP .B IncludeStyle A string specifying which include\-style is used, \fIllvm\fP or \fIgoogle\fP\&. Default is \fIllvm\fP\&. .UNINDENT .INDENT 0.0 .TP .B AbseilStringsMatchHeader The location of Abseil\(aqs \fBstrings/match.h\fP\&. Defaults to \fBabsl/strings/match.h\fP\&. .UNINDENT .SS abseil\-time\-comparison .sp Prefer comparisons in the \fBabsl::Time\fP domain instead of the integer domain. .sp N.B.: In cases where an \fBabsl::Time\fP is being converted to an integer, alignment may occur. If the comparison depends on this alignment, doing the comparison in the \fBabsl::Time\fP domain may yield a different result. In practice this is very rare, and still indicates a bug which should be fixed. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX // Original \- Comparison in the integer domain int x; absl::Time t; if (x < absl::ToUnixSeconds(t)) ... // Suggested \- Compare in the absl::Time domain instead if (absl::FromUnixSeconds(x) < t) ... .EE .UNINDENT .UNINDENT .SS abseil\-time\-subtraction .sp Finds and fixes \fBabsl::Time\fP subtraction expressions to do subtraction in the Time domain instead of the numeric domain. .sp There are two cases of Time subtraction in which deduce additional type information: .INDENT 0.0 .IP \(bu 2 When the result is an \fBabsl::Duration\fP and the first argument is an \fBabsl::Time\fP\&. .IP \(bu 2 When the second argument is a \fBabsl::Time\fP\&. .UNINDENT .sp In the first case, we must know the result of the operation, since without that the second operand could be either an \fBabsl::Time\fP or an \fBabsl::Duration\fP\&. In the second case, the first operand \fImust\fP be an \fBabsl::Time\fP, because subtracting an \fBabsl::Time\fP from an \fBabsl::Duration\fP is not defined. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX int x; absl::Time t; // Original \- absl::Duration result and first operand is an absl::Time. absl::Duration d = absl::Seconds(absl::ToUnixSeconds(t) \- x); // Suggestion \- Perform subtraction in the Time domain instead. absl::Duration d = t \- absl::FromUnixSeconds(x); // Original \- Second operand is an absl::Time. int i = x \- absl::ToUnixSeconds(t); // Suggestion \- Perform subtraction in the Time domain instead. int i = absl::ToInt64Seconds(absl::FromUnixSeconds(x) \- t); .EE .UNINDENT .UNINDENT .SS abseil\-unchecked\-statusor\-access .sp This check identifies unsafe accesses to values contained in \fBabsl::StatusOr\fP objects. Below we will refer to this type as \fBStatusOr\fP\&. .sp An access to the value of an \fBStatusOr\fP occurs when one of its \fBvalue\fP, \fBoperator*\fP, or \fBoperator\->\fP member functions is invoked. To align with common misconceptions, the check considers these member functions as equivalent, even though there are subtle differences related to exceptions vs.\ undefined behavior. .sp An access to the value of a \fBStatusOr\fP is considered safe if and only if code in the local scope (e.g.\ function body) ensures that the status of the \fBStatusOr\fP is ok in all possible execution paths that can reach the access. That should happen either through an explicit check, using the \fBStatusOr::ok\fP member function, or by constructing the \fBStatusOr\fP in a way that shows that its status is unambiguously ok (e.g.\ by passing a value to its constructor). .sp Below we list some examples of safe and unsafe \fBStatusOr\fP access patterns. .sp Note: If the check isn’t behaving as you would have expected on a code snippet, please report it \%\&. .SS False negatives .sp This check generally does \fBnot\fP generate false negatives. That means that if an access is not marked as unsafe, it is provably safe. If it cannot prove an access safe, it is assumed to be unsafe. In some cases, the static analysis cannot prove an access safe even though it is, for a variety of reasons (e.g. unmodelled invariants of functions called). In these cases, the analysis does produce false positive reports. .sp That being said, there are some heuristics used that in very rare cases might be incorrect: .INDENT 0.0 .IP \(bu 2 a const method accessor (without arguments) that returns different values when called multiple times \%<#\:functionstability>\&. .UNINDENT .sp If you think the check generated a false negative, please report it \%\&. .SS Known limitations .sp This is a non\-exhaustive list of constructs that are currently not modelled in the check and will lead to false positives: .INDENT 0.0 .IP \(bu 2 Checking a StatusOr and then capturing it in a lambda \%<#\:lambdas> .IP \(bu 2 Indexing into a container with the same index \%<#\:containers> .IP \(bu 2 Project specific helper\-functions \%<#\:uncommonapi>, .IP \(bu 2 Functions with a stable return value \%<#\:functionstability> .IP \(bu 2 \fBAny\fP cross\-function reasoning \%<#\:crossfunction>\&. This is by design and will not change in the future. .UNINDENT .SS Checking if the status is ok, then accessing the value .sp The check recognizes all straightforward ways for checking the status and accessing the value contained in a \fBStatusOr\fP object. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX void f(absl::StatusOr sor) { if (sor.ok()) { use(*sor); } } .EE .UNINDENT .UNINDENT .SS Checking if the status is ok, then accessing the value from a copy .sp The criteria that the check uses is semantic, not syntactic. It recognizes when a copy of the \fBStatusOr\fP object being accessed is known to have ok status. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX void f(absl::StatusOr sor1) { if (sor1.ok()) { absl::optional sor2 = sor1; use(*sor2); } } .EE .UNINDENT .UNINDENT .SS Ensuring that the status is ok using common macros .sp The check is aware of common macros like \fBABSL_CHECK\fP and \fBASSERT_THAT\fP\&. Those can be used to ensure that the status of a \fBStatusOr\fP object is ok. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX void f(absl::StatusOr sor) { ABSL_DCHECK_OK(sor); use(*sor); } .EE .UNINDENT .UNINDENT .SS Ensuring that the status is ok, then accessing the value in a correlated branch .sp The check is aware of correlated branches in the code and can figure out when a \fBStatusOr\fP object is ensured to have ok status on all execution paths that lead to an access. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX void f(absl::StatusOr sor) { bool safe = false; if (sor.ok() && SomeOtherCondition()) { safe = true; } // ... more code... if (safe) { use(*sor); } } .EE .UNINDENT .UNINDENT .SS Accessing the value without checking the status .sp The check flags accesses to the value that are not locally guarded by a status check: .INDENT 0.0 .INDENT 3.5 .sp .EX void f1(absl::StatusOr sor) { use(*sor); // unsafe: it is unclear whether the status of \(gasor\(ga is ok. } void f2(absl::StatusOr sor) { use(sor\->member); // unsafe: it is unclear whether the status of \(gasor\(ga is ok. } void f3(absl::StatusOr sor) { use(sor.value()); // unsafe: it is unclear whether the status of \(gasor\(ga is ok. } .EE .UNINDENT .UNINDENT .sp Use \fBABSL_CHECK_OK\fP to signal that you knowingly want to crash on non\-OK values. .sp NOTE: Even though using \fB\&.value()\fP on a non\-\fBok()\fP \fBStatusOr\fP is defined to crash, it is often unintentional. That is why our checker flags those as well. .SS Accessing the value in the wrong branch .sp The check is aware of the state of a \fBStatusOr\fP object in different branches of the code. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX void f(absl::StatusOr sor) { if (sor.ok()) { } else { use(*sor); // unsafe: it is clear that the status of \(gasor\(ga is *not* ok. } } .EE .UNINDENT .UNINDENT .SS Assuming a function result to be stable .sp The check is aware that function results might not be stable. That is, consecutive calls to the same function might return different values. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX void f(Foo foo) { if (foo.sor().ok()) { use(*foo.sor()); // unsafe: it is unclear whether the status of \(gafoo.sor()\(ga is ok. } } .EE .UNINDENT .UNINDENT .sp In such cases it is best to store the result of the function call in a local variable and use it to access the value. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX void f(Foo foo) { if (const auto& foo_sor = foo.sor(); foo_sor.ok()) { use(*foo_sor); } } .EE .UNINDENT .UNINDENT .sp The check \fBdoes\fP assume that \fBconst\fP\-qualified accessor functions return a stable value if no non\-const function was called between the two calls: .INDENT 0.0 .INDENT 3.5 .sp .EX class Foo { const absl::StatusOr& get() const { [...]; } } void f(Foo foo) { if (foo.get().ok()) { use(*foo.get()); } } .EE .UNINDENT .UNINDENT .sp If there is a call to a non\-\fBconst\fP\-qualified function, the check assumes the return value of the accessor was mutated. .INDENT 0.0 .INDENT 3.5 .sp .EX class Foo { const absl::StatusOr& get() const { [...]; } void mutate(); } void f(Foo foo) { if (foo.get().ok()) { foo.mutate(); use(*foo.get()); // unsafe: mutate might have changed the state of the object } } .EE .UNINDENT .UNINDENT .SS Relying on invariants of uncommon APIs .sp The check is unaware of invariants of uncommon APIs. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX void f(Foo foo) { if (foo.HasProperty(\(dqbar\(dq)) { use(*foo.GetProperty(\(dqbar\(dq)); // unsafe: it is unclear whether the status of \(gafoo.GetProperty(\(dqbar\(dq)\(ga is ok. } } .EE .UNINDENT .UNINDENT .sp In such cases it is best to check explicitly that the status of the \fBStatusOr\fP object is ok. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX void f(Foo foo) { if (const auto& property = foo.GetProperty(\(dqbar\(dq); property.ok()) { use(*property); } } .EE .UNINDENT .UNINDENT .SS Checking if the status is ok, then passing the \fBStatusOr\fP to another function .sp The check relies on local reasoning. The check and value access must both happen in the same function. An access is considered unsafe even if the caller of the function performing the access ensures that the status of the \fBStatusOr\fP is ok. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX void g(absl::StatusOr sor) { use(*sor); // unsafe: it is unclear whether the status of \(gasor\(ga is ok. } void f(absl::StatusOr sor) { if (sor.ok()) { g(sor); } } .EE .UNINDENT .UNINDENT .sp In such cases it is best to either pass the value directly when calling a function or check that the status of the \fBStatusOr\fP is ok in the local scope of the callee. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX void g(int val) { use(val); } void f(absl::StatusOr sor) { if (sor.ok()) { g(*sor); } } .EE .UNINDENT .UNINDENT .SS Aliases created via \fBusing\fP declarations .sp The check is aware of aliases of \fBStatusOr\fP types that are created via \fBusing\fP declarations. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX using StatusOrInt = absl::StatusOr; void f(StatusOrInt sor) { use(*sor); // unsafe: it is unclear whether the status of \(gasor\(ga is ok. } .EE .UNINDENT .UNINDENT .SS Containers .sp The check is more strict than necessary when it comes to containers of \fBStatusOr\fP values. Simply checking that the status of an element of a container is ok is not sufficient to deem accessing it safe. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX void f(std::vector> sors) { if (sors[0].ok()) { use(*sors[0]); // unsafe: it is unclear whether the status of \(gasors[0]\(ga is ok. } } .EE .UNINDENT .UNINDENT .sp One needs to grab a reference to a particular object and use that instead: .INDENT 0.0 .INDENT 3.5 .sp .EX void f(std::vector> sors) { absl::StatusOr& sor0 = sors[0]; if (sor0.ok()) { use(*sor0); } } .EE .UNINDENT .UNINDENT .sp A future version could improve the understanding of more safe usage patterns that involve containers. .SS Lambdas .sp The check is capable of reporting unsafe \fBStatusOr\fP accesses in lambdas, but isn’t smart enough to propagate information from the surrounding context through the lambda. This means that the following pattern will be reported as an unsafe access: .INDENT 0.0 .INDENT 3.5 .sp .EX void f(absl::StatusOr sor) { if (sor.ok()) { [&sor]() { use(*sor); // unsafe: it is unclear whether the status of \(gasor\(ga is ok. } } } .EE .UNINDENT .UNINDENT .sp To avoid the issue, you should grab a reference to the contained object and capture that instead .INDENT 0.0 .INDENT 3.5 .sp .EX void f(absl::StatusOr sor) { if (sor.ok()) { auto& s = *sor; [&s]() { use(s); } } } .EE .UNINDENT .UNINDENT .sp Alternatively you could add a check inside the lambda where the value is accessed: .INDENT 0.0 .INDENT 3.5 .sp .EX void f(absl::StatusOr sor) { [&sor]() { if (sor.ok()) { use(*sor); } } } .EE .UNINDENT .UNINDENT .SS abseil\-upgrade\-duration\-conversions .sp Finds calls to \fBabsl::Duration\fP arithmetic operators and factories whose argument needs an explicit cast to continue compiling after upcoming API changes. .sp The operators \fB*=\fP, \fB/=\fP, \fB*\fP, and \fB/\fP for \fBabsl::Duration\fP currently accept an argument of class type that is convertible to an arithmetic type. Such a call currently converts the value to an \fBint64_t\fP, even in a case such as \fBstd::atomic\fP that would result in lossy conversion. .sp Additionally, the \fBabsl::Duration\fP factory functions (\fBabsl::Hours\fP, \fBabsl::Minutes\fP, etc) currently accept an \fBint64_t\fP or a floating\-point type. Similar to the arithmetic operators, calls with an argument of class type that is convertible to an arithmetic type go through the \fBint64_t\fP path. .sp These operators and factories will be changed to only accept arithmetic types to prevent unintended behavior. After these changes are released, passing an argument of class type will no longer compile, even if the type is implicitly convertible to an arithmetic type. .sp Here are example fixes created by this check: .INDENT 0.0 .INDENT 3.5 .sp .EX std::atomic a; absl::Duration d = absl::Milliseconds(a); d *= a; .EE .UNINDENT .UNINDENT .sp becomes .INDENT 0.0 .INDENT 3.5 .sp .EX std::atomic a; absl::Duration d = absl::Milliseconds(static_cast(a)); d *= static_cast(a); .EE .UNINDENT .UNINDENT .sp Note that this check always adds a cast to \fBint64_t\fP in order to preserve the current behavior of user code. It is possible that this uncovers unintended behavior due to types implicitly convertible to a floating\-point type. .SS altera\-id\-dependent\-backward\-branch .sp Finds ID\-dependent variables and fields that are used within loops. This causes branches to occur inside the loops, and thus leads to performance degradation. .INDENT 0.0 .INDENT 3.5 .sp .EX // The following code will produce a warning because this ID\-dependent // variable is used in a loop condition statement. int ThreadID = get_local_id(0); // The following loop will produce a warning because the loop condition // statement depends on an ID\-dependent variable. for (int i = 0; i < ThreadID; ++i) { std::cout << i << std::endl; } // The following loop will not produce a warning, because the ID\-dependent // variable is not used in the loop condition statement. for (int i = 0; i < 100; ++i) { std::cout << ThreadID << std::endl; } .EE .UNINDENT .UNINDENT .sp Based on the Altera SDK for OpenCL: Best Practices Guide \%\&. .SS altera\-kernel\-name\-restriction .sp Finds kernel files and include directives whose filename is \fIkernel.cl\fP, \fIVerilog.cl\fP, or \fIVHDL.cl\fP\&. The check is case insensitive. .sp Such kernel file names cause the offline compiler to generate intermediate design files that have the same names as certain internal files, which leads to a compilation error. .sp Based on the \fIGuidelines for Naming the Kernel\fP section in the Intel FPGA SDK for OpenCL Pro Edition: Programming Guide \%\&. .SS altera\-single\-work\-item\-barrier .sp Finds OpenCL kernel functions that call a barrier function but do not call an ID function (\fBget_local_id\fP, \fBget_local_id\fP, \fBget_group_id\fP, or \fBget_local_linear_id\fP). .sp These kernels may be viable single work\-item kernels, but will be forced to execute as NDRange kernels if using a newer version of the Altera Offline Compiler (>= v17.01). .sp If using an older version of the Altera Offline Compiler, these kernel functions will be treated as single work\-item kernels, which could be inefficient or lead to errors if NDRange semantics were intended. .sp Based on the Altera SDK for OpenCL: Best Practices Guide \%\&. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX // error: function calls barrier but does not call an ID function. void __kernel barrier_no_id(__global int * foo, int size) { for (int i = 0; i < 100; i++) { foo[i] += 5; } barrier(CLK_GLOBAL_MEM_FENCE); } // ok: function calls barrier and an ID function. void __kernel barrier_with_id(__global int * foo, int size) { for (int i = 0; i < 100; i++) { int tid = get_global_id(0); foo[tid] += 5; } barrier(CLK_GLOBAL_MEM_FENCE); } // ok with AOC Version 17.01: the reqd_work_group_size turns this into // an NDRange. __attribute__((reqd_work_group_size(2,2,2))) void __kernel barrier_with_id(__global int * foo, int size) { for (int i = 0; i < 100; i++) { foo[tid] += 5; } barrier(CLK_GLOBAL_MEM_FENCE); } .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B AOCVersion Defines the version of the Altera Offline Compiler. Defaults to \fB1600\fP (corresponding to version 16.00). .UNINDENT .SS altera\-struct\-pack\-align .sp Finds structs that are inefficiently packed or aligned, and recommends packing and/or aligning of said structs as needed. .sp Structs that are not packed take up more space than they should, and accessing structs that are not well aligned is inefficient. .sp Fix\-its are provided to fix both of these issues by inserting and/or amending relevant struct attributes. .sp Based on the Altera SDK for OpenCL: Best Practices Guide \%\&. .INDENT 0.0 .INDENT 3.5 .sp .EX // The following struct is originally aligned to 4 bytes, and thus takes up // 12 bytes of memory instead of 10. Packing the struct will make it use // only 10 bytes of memory, and aligning it to 16 bytes will make it // efficient to access. struct example { char a; // 1 byte double b; // 8 bytes char c; // 1 byte }; // The following struct is arranged in such a way that packing is not needed. // However, it is aligned to 4 bytes instead of 8, and thus needs to be // explicitly aligned. struct implicitly_packed_example { char a; // 1 byte char b; // 1 byte char c; // 1 byte char d; // 1 byte int e; // 4 bytes }; // The following struct is explicitly aligned and packed. struct good_example { char a; // 1 byte double b; // 8 bytes char c; // 1 byte } __attribute__((packed)) __attribute__((aligned(16)); // Explicitly aligning a struct to the wrong value will result in a warning. // The following example should be aligned to 16 bytes, not 32. struct badly_aligned_example { char a; // 1 byte double b; // 8 bytes char c; // 1 byte } __attribute__((packed)) __attribute__((aligned(32))); .EE .UNINDENT .UNINDENT .SS altera\-unroll\-loops .sp Finds inner loops that have not been unrolled, as well as fully unrolled loops with unknown loop bounds or a large number of iterations. .sp Unrolling inner loops could improve the performance of OpenCL kernels. However, if they have unknown loop bounds or a large number of iterations, they cannot be fully unrolled, and should be partially unrolled. .sp Notes: .INDENT 0.0 .IP \(bu 2 This check is unable to determine the number of iterations in a \fBwhile\fP or \fBdo..while\fP loop; hence if such a loop is fully unrolled, a note is emitted advising the user to partially unroll instead. .IP \(bu 2 In \fBfor\fP loops, our check only works with simple arithmetic increments ( \fB+\fP, \fB\-\fP, \fB*\fP, \fB/\fP). For all other increments, partial unrolling is advised. .IP \(bu 2 Depending on the exit condition, the calculations for determining if the number of iterations is large may be off by 1. This should not be an issue since the cut\-off is generally arbitrary. .UNINDENT .sp Based on the Altera SDK for OpenCL: Best Practices Guide \%\&. .INDENT 0.0 .INDENT 3.5 .sp .EX for (int i = 0; i < 10; i++) { // ok: outer loops should not be unrolled int j = 0; do { // warning: this inner do..while loop should be unrolled j++; } while (j < 15); int k = 0; #pragma unroll while (k < 20) { // ok: this inner loop is already unrolled k++; } } int A[1000]; #pragma unroll // warning: this loop is large and should be partially unrolled for (int a : A) { printf(\(dq%d\(dq, a); } #pragma unroll 5 // ok: this loop is large, but is partially unrolled for (int a : A) { printf(\(dq%d\(dq, a); } #pragma unroll // warning: this loop is large and should be partially unrolled for (int i = 0; i < 1000; ++i) { printf(\(dq%d\(dq, i); } #pragma unroll 5 // ok: this loop is large, but is partially unrolled for (int i = 0; i < 1000; ++i) { printf(\(dq%d\(dq, i); } #pragma unroll // warning: << operator not supported, recommend partial unrolling for (int i = 0; i < 1000; i<<1) { printf(\(dq%d\(dq, i); } std::vector someVector (100, 0); int i = 0; #pragma unroll // note: loop may be large, recommend partial unrolling while (i < someVector.size()) { someVector[i]++; } #pragma unroll // note: loop may be large, recommend partial unrolling while (true) { printf(\(dqIn loop\(dq); } #pragma unroll 5 // ok: loop may be large, but is partially unrolled while (i < someVector.size()) { someVector[i]++; } .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B MaxLoopIterations Defines the maximum number of loop iterations that a fully unrolled loop can have. By default, it is set to \fI100\fP\&. .sp In practice, this refers to the integer value of the upper bound within the loop statement\(aqs condition expression. .UNINDENT .SS android\-cloexec\-accept .sp The usage of \fBaccept()\fP is not recommended, it\(aqs better to use \fBaccept4()\fP\&. Without this flag, an opened sensitive file descriptor would remain open across a fork+exec to a lower\-privileged SELinux domain. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX accept(sockfd, addr, addrlen); // becomes accept4(sockfd, addr, addrlen, SOCK_CLOEXEC); .EE .UNINDENT .UNINDENT .SS android\-cloexec\-accept4 .sp \fBaccept4()\fP should include \fBSOCK_CLOEXEC\fP in its type argument to avoid the file descriptor leakage. Without this flag, an opened sensitive file would remain open across a fork+exec to a lower\-privileged SELinux domain. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX accept4(sockfd, addr, addrlen, SOCK_NONBLOCK); // becomes accept4(sockfd, addr, addrlen, SOCK_NONBLOCK | SOCK_CLOEXEC); .EE .UNINDENT .UNINDENT .SS android\-cloexec\-creat .sp The usage of \fBcreat()\fP is not recommended, it\(aqs better to use \fBopen()\fP\&. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX int fd = creat(path, mode); // becomes int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, mode); .EE .UNINDENT .UNINDENT .SS android\-cloexec\-dup .sp The usage of \fBdup()\fP is not recommended, it\(aqs better to use \fBfcntl()\fP, which can set the close\-on\-exec flag. Otherwise, an opened sensitive file would remain open across a fork+exec to a lower\-privileged SELinux domain. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX int fd = dup(oldfd); // becomes int fd = fcntl(oldfd, F_DUPFD_CLOEXEC); .EE .UNINDENT .UNINDENT .SS android\-cloexec\-epoll\-create .sp The usage of \fBepoll_create()\fP is not recommended, it\(aqs better to use \fBepoll_create1()\fP, which allows close\-on\-exec. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX epoll_create(size); // becomes epoll_create1(EPOLL_CLOEXEC); .EE .UNINDENT .UNINDENT .SS android\-cloexec\-epoll\-create1 .sp \fBepoll_create1()\fP should include \fBEPOLL_CLOEXEC\fP in its type argument to avoid the file descriptor leakage. Without this flag, an opened sensitive file would remain open across a fork+exec to a lower\-privileged SELinux domain. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX epoll_create1(0); // becomes epoll_create1(EPOLL_CLOEXEC); .EE .UNINDENT .UNINDENT .SS android\-cloexec\-fopen .sp \fBfopen()\fP should include \fBe\fP in their mode string; so \fBre\fP would be valid. This is equivalent to having set \fBFD_CLOEXEC on\fP that descriptor. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX fopen(\(dqfn\(dq, \(dqr\(dq); // becomes fopen(\(dqfn\(dq, \(dqre\(dq); .EE .UNINDENT .UNINDENT .SS android\-cloexec\-inotify\-init .sp The usage of \fBinotify_init()\fP is not recommended, it\(aqs better to use \fBinotify_init1()\fP\&. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX inotify_init(); // becomes inotify_init1(IN_CLOEXEC); .EE .UNINDENT .UNINDENT .SS android\-cloexec\-inotify\-init1 .sp \fBinotify_init1()\fP should include \fBIN_CLOEXEC\fP in its type argument to avoid the file descriptor leakage. Without this flag, an opened sensitive file would remain open across a fork+exec to a lower\-privileged SELinux domain. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX inotify_init1(IN_NONBLOCK); // becomes inotify_init1(IN_NONBLOCK | IN_CLOEXEC); .EE .UNINDENT .UNINDENT .SS android\-cloexec\-memfd\-create .sp \fBmemfd_create()\fP should include \fBMFD_CLOEXEC\fP in its type argument to avoid the file descriptor leakage. Without this flag, an opened sensitive file would remain open across a fork+exec to a lower\-privileged SELinux domain. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX memfd_create(name, MFD_ALLOW_SEALING); // becomes memfd_create(name, MFD_ALLOW_SEALING | MFD_CLOEXEC); .EE .UNINDENT .UNINDENT .SS android\-cloexec\-open .sp A common source of security bugs is code that opens a file without using the \fBO_CLOEXEC\fP flag. Without that flag, an opened sensitive file would remain open across a fork+exec to a lower\-privileged SELinux domain, leaking that sensitive data. Open\-like functions including \fBopen()\fP, \fBopenat()\fP, and \fBopen64()\fP should include \fBO_CLOEXEC\fP in their flags argument. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX open(\(dqfilename\(dq, O_RDWR); open64(\(dqfilename\(dq, O_RDWR); openat(0, \(dqfilename\(dq, O_RDWR); // becomes open(\(dqfilename\(dq, O_RDWR | O_CLOEXEC); open64(\(dqfilename\(dq, O_RDWR | O_CLOEXEC); openat(0, \(dqfilename\(dq, O_RDWR | O_CLOEXEC); .EE .UNINDENT .UNINDENT .SS android\-cloexec\-pipe .sp This check detects usage of \fBpipe()\fP\&. Using \fBpipe()\fP is not recommended, \fBpipe2()\fP is the suggested replacement. The check also adds the \fBO_CLOEXEC\fP flag that marks the file descriptor to be closed in child processes. Without this flag a sensitive file descriptor can be leaked to a child process, potentially into a lower\-privileged SELinux domain. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX pipe(pipefd); .EE .UNINDENT .UNINDENT .sp Suggested replacement: .INDENT 0.0 .INDENT 3.5 .sp .EX pipe2(pipefd, O_CLOEXEC); .EE .UNINDENT .UNINDENT .SS android\-cloexec\-pipe2 .sp This check ensures that \fBpipe2()\fP is called with the \fBO_CLOEXEC\fP flag. The check also adds the \fBO_CLOEXEC\fP flag that marks the file descriptor to be closed in child processes. Without this flag a sensitive file descriptor can be leaked to a child process, potentially into a lower\-privileged SELinux domain. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX pipe2(pipefd, O_NONBLOCK); .EE .UNINDENT .UNINDENT .sp Suggested replacement: .INDENT 0.0 .INDENT 3.5 .sp .EX pipe2(pipefd, O_NONBLOCK | O_CLOEXEC); .EE .UNINDENT .UNINDENT .SS android\-cloexec\-socket .sp \fBsocket()\fP should include \fBSOCK_CLOEXEC\fP in its type argument to avoid the file descriptor leakage. Without this flag, an opened sensitive file would remain open across a fork+exec to a lower\-privileged SELinux domain. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX socket(domain, type, SOCK_STREAM); // becomes socket(domain, type, SOCK_STREAM | SOCK_CLOEXEC); .EE .UNINDENT .UNINDENT .SS android\-comparison\-in\-temp\-failure\-retry .sp Diagnoses comparisons that appear to be incorrectly placed in the argument to the \fBTEMP_FAILURE_RETRY\fP macro. Having such a use is incorrect in the vast majority of cases, and will often silently defeat the purpose of the \fBTEMP_FAILURE_RETRY\fP macro. .sp For context, \fBTEMP_FAILURE_RETRY\fP is a convenience macro \% provided by both glibc and Bionic. Its purpose is to repeatedly run a syscall until it either succeeds, or fails for reasons other than being interrupted. .sp Example buggy usage looks like: .INDENT 0.0 .INDENT 3.5 .sp .EX char cs[1]; while (TEMP_FAILURE_RETRY(read(STDIN_FILENO, cs, sizeof(cs)) != 0)) { // Do something with cs. } .EE .UNINDENT .UNINDENT .sp Because \fBTEMP_FAILURE_RETRY\fP will check for whether the result \fIof the comparison\fP is \fB\-1\fP, and retry if so. .sp If you encounter this, the fix is simple: lift the comparison out of the \fBTEMP_FAILURE_RETRY\fP argument, like so: .INDENT 0.0 .INDENT 3.5 .sp .EX char cs[1]; while (TEMP_FAILURE_RETRY(read(STDIN_FILENO, cs, sizeof(cs))) != 0) { // Do something with cs. } .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B RetryMacros A comma\-separated list of the names of retry macros to be checked. Default is \fITEMP_FAILURE_RETRY\fP\&. .UNINDENT .SS boost\-use\-ranges .sp Detects calls to standard library iterator algorithms that could be replaced with a Boost ranges version instead. .SS Example .INDENT 0.0 .INDENT 3.5 .sp .EX auto Iter1 = std::find(Items.begin(), Items.end(), 0); auto AreSame = std::equal(Items1.cbegin(), Items1.cend(), std::begin(Items2), std::end(Items2)); .EE .UNINDENT .UNINDENT .sp Transforms to: .INDENT 0.0 .INDENT 3.5 .sp .EX auto Iter1 = boost::range::find(Items, 0); auto AreSame = boost::range::equal(Items1, Items2); .EE .UNINDENT .UNINDENT .SS Supported algorithms .sp Calls to the following std library algorithms are checked: .sp \fBstd::accumulate\fP, \fBstd::adjacent_difference\fP, \fBstd::adjacent_find\fP, \fBstd::all_of\fP, \fBstd::any_of\fP, \fBstd::binary_search\fP, \fBstd::copy_backward\fP, \fBstd::copy_if\fP, \fBstd::copy\fP, \fBstd::count_if\fP, \fBstd::count\fP, \fBstd::equal_range\fP, \fBstd::equal\fP, \fBstd::fill\fP, \fBstd::find_end\fP, \fBstd::find_first_of\fP, \fBstd::find_if_not\fP, \fBstd::find_if\fP, \fBstd::find\fP, \fBstd::for_each\fP, \fBstd::generate\fP, \fBstd::includes\fP, \fBstd::iota\fP, \fBstd::is_partitioned\fP, \fBstd::is_permutation\fP, \fBstd::is_sorted_until\fP, \fBstd::is_sorted\fP, \fBstd::lexicographical_compare\fP, \fBstd::lower_bound\fP, \fBstd::make_heap\fP, \fBstd::max_element\fP, \fBstd::merge\fP, \fBstd::min_element\fP, \fBstd::mismatch\fP, \fBstd::next_permutation\fP, \fBstd::none_of\fP, \fBstd::partial_sum\fP, \fBstd::partial_sort_copy\fP, \fBstd::partition_copy\fP, \fBstd::partition_point\fP, \fBstd::partition\fP, \fBstd::pop_heap\fP, \fBstd::prev_permutation\fP, \fBstd::push_heap\fP, \fBstd::random_shuffle\fP, \fBstd::reduce\fP, \fBstd::remove_copy_if\fP, \fBstd::remove_copy\fP, \fBstd::remove_if\fP, \fBstd::remove\fP, \fBstd::replace_copy_if\fP, \fBstd::replace_copy\fP, \fBstd::replace_if\fP, \fBstd::replace\fP, \fBstd::reverse_copy\fP, \fBstd::reverse\fP, \fBstd::search\fP, \fBstd::set_difference\fP, \fBstd::set_intersection\fP, \fBstd::set_symmetric_difference\fP, \fBstd::set_union\fP, \fBstd::sort_heap\fP, \fBstd::sort\fP, \fBstd::stable_partition\fP, \fBstd::stable_sort\fP, \fBstd::transform\fP, \fBstd::unique_copy\fP, \fBstd::unique\fP, \fBstd::upper_bound\fP\&. .sp The check will also look for the following functions from the \fBboost::algorithm\fP namespace: .sp \fBall_of_equal\fP, \fBany_of_equal\fP, \fBany_of\fP, \fBapply_permutation\fP, \fBapply_reverse_permutation\fP, \fBclamp_range\fP, \fBcopy_if_until\fP, \fBcopy_if_while\fP, \fBcopy_if\fP, \fBcopy_until\fP, \fBcopy_while\fP, \fBfind_backward\fP, \fBfind_if_backward\fP, \fBfind_if_not_backward\fP, \fBfind_if_not\fP, \fBfind_not_backward\fP, \fBhex_lower\fP, \fBhex\fP, \fBiota\fP, \fBall_of\fP, \fBis_decreasing\fP, \fBis_increasing\fP, \fBis_palindrome\fP, \fBis_partitioned_until\fP, \fBis_partitioned\fP, \fBis_permutation\fP, \fBis_sorted_until\fP, \fBis_sorted\fP, \fBis_strictly_decreasing\fP, \fBis_strictly_increasing\fP, \fBnone_of_equal\fP, \fBnone_of\fP, \fBone_of_equal\fP, \fBone_of\fP, \fBpartition_copy\fP, \fBpartition_point\fP, \fBreduce\fP, \fBunhex\fP\&. .SS Reverse Iteration .sp If calls are made using reverse iterators on containers, The code will be fixed using the \fBboost::adaptors::reverse\fP adaptor. .INDENT 0.0 .INDENT 3.5 .sp .EX auto AreSame = std::equal(Items1.rbegin(), Items1.rend(), std::crbegin(Items2), std::crend(Items2)); .EE .UNINDENT .UNINDENT .sp Transforms to: .INDENT 0.0 .INDENT 3.5 .sp .EX auto AreSame = boost::range::equal(boost::adaptors::reverse(Items1), boost::adaptors::reverse(Items2)); .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IncludeStyle A string specifying which include\-style is used, \fIllvm\fP or \fIgoogle\fP\&. Default is \fIllvm\fP\&. .UNINDENT .INDENT 0.0 .TP .B IncludeBoostSystem If \fItrue\fP (default value) the boost headers are included as system headers with angle brackets (\fI#include \fP), otherwise quotes are used (\fI#include \(dqboost.hpp\(dq\fP). .UNINDENT .INDENT 0.0 .TP .B UseReversePipe When \fItrue\fP (default \fIfalse\fP), fixes which involve reverse ranges will use the pipe adaptor syntax instead of the function syntax. .INDENT 7.0 .INDENT 3.5 .sp .EX std::find(Items.rbegin(), Items.rend(), 0); .EE .UNINDENT .UNINDENT .sp Transforms to: .INDENT 7.0 .INDENT 3.5 .sp .EX boost::range::find(Items | boost::adaptors::reversed, 0); .EE .UNINDENT .UNINDENT .UNINDENT .SS boost\-use\-to\-string .sp This check finds conversion from integer type like \fBint\fP to \fBstd::string\fP or \fBstd::wstring\fP using \fBboost::lexical_cast\fP, and replace it with calls to \fBstd::to_string\fP and \fBstd::to_wstring\fP\&. .sp It doesn\(aqt replace conversion from floating points despite the \fBto_string\fP overloads, because it would change the behavior. .INDENT 0.0 .INDENT 3.5 .sp .EX auto str = boost::lexical_cast(42); auto wstr = boost::lexical_cast(2137LL); // Will be changed to auto str = std::to_string(42); auto wstr = std::to_wstring(2137LL); .EE .UNINDENT .UNINDENT .SS bugprone\-argument\-comment .sp Checks that argument comments match parameter names. .sp The check understands argument comments in the form \fB/*parameter_name=*/\fP that are placed right before the argument. .INDENT 0.0 .INDENT 3.5 .sp .EX void f(bool foo); \&... f(/*bar=*/true); // warning: argument name \(aqbar\(aq in comment does not match parameter name \(aqfoo\(aq .EE .UNINDENT .UNINDENT .sp The check tries to detect typos and suggest automated fixes for them. .SS Options .INDENT 0.0 .TP .B StrictMode When \fIfalse\fP, the check will ignore leading and trailing underscores and case when comparing names \-\- otherwise they are taken into account. Default is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B IgnoreSingleArgument When \fItrue\fP, the check will ignore the single argument. Default is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B CommentBoolLiterals When \fItrue\fP, the check will add argument comments in the format \fB/*ParameterName=*/\fP right before the boolean literal argument. Default is \fIfalse\fP\&. .UNINDENT .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .EX void foo(bool TurnKey, bool PressButton); foo(true, false); .EE .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .EX void foo(bool TurnKey, bool PressButton); foo(/*TurnKey=*/true, /*PressButton=*/false); .EE .UNINDENT .UNINDENT .INDENT 0.0 .TP .B CommentIntegerLiterals When \fItrue\fP, the check will add argument comments in the format \fB/*ParameterName=*/\fP right before the integer literal argument. Default is \fIfalse\fP\&. .UNINDENT .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .EX void foo(int MeaningOfLife); foo(42); .EE .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .EX void foo(int MeaningOfLife); foo(/*MeaningOfLife=*/42); .EE .UNINDENT .UNINDENT .INDENT 0.0 .TP .B CommentFloatLiterals When \fItrue\fP, the check will add argument comments in the format \fB/*ParameterName=*/\fP right before the float/double literal argument. Default is \fIfalse\fP\&. .UNINDENT .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .EX void foo(float Pi); foo(3.14159); .EE .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .EX void foo(float Pi); foo(/*Pi=*/3.14159); .EE .UNINDENT .UNINDENT .INDENT 0.0 .TP .B CommentStringLiterals When \fItrue\fP, the check will add argument comments in the format \fB/*ParameterName=*/\fP right before the string literal argument. Default is \fIfalse\fP\&. .UNINDENT .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .EX void foo(const char *String); void foo(const wchar_t *WideString); foo(\(dqHello World\(dq); foo(L\(dqHello World\(dq); .EE .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .EX void foo(const char *String); void foo(const wchar_t *WideString); foo(/*String=*/\(dqHello World\(dq); foo(/*WideString=*/L\(dqHello World\(dq); .EE .UNINDENT .UNINDENT .INDENT 0.0 .TP .B CommentCharacterLiterals When \fItrue\fP, the check will add argument comments in the format \fB/*ParameterName=*/\fP right before the character literal argument. Default is \fIfalse\fP\&. .UNINDENT .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .EX void foo(char *Character); foo(\(aqA\(aq); .EE .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .EX void foo(char *Character); foo(/*Character=*/\(aqA\(aq); .EE .UNINDENT .UNINDENT .INDENT 0.0 .TP .B CommentUserDefinedLiterals When \fItrue\fP, the check will add argument comments in the format \fB/*ParameterName=*/\fP right before the user defined literal argument. Default is \fIfalse\fP\&. .UNINDENT .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .EX void foo(double Distance); double operator\(dq\(dq _km(long double); foo(402.0_km); .EE .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .EX void foo(double Distance); double operator\(dq\(dq _km(long double); foo(/*Distance=*/402.0_km); .EE .UNINDENT .UNINDENT .INDENT 0.0 .TP .B CommentNullPtrs When \fItrue\fP, the check will add argument comments in the format \fB/*ParameterName=*/\fP right before the nullptr literal argument. Default is \fIfalse\fP\&. .UNINDENT .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .EX void foo(A* Value); foo(nullptr); .EE .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .EX void foo(A* Value); foo(/*Value=*/nullptr); .EE .UNINDENT .UNINDENT .SS bugprone\-assert\-side\-effect .sp Finds \fBassert()\fP with side effect. .sp The condition of \fBassert()\fP is evaluated only in debug builds so a condition with side effect can cause different behavior in debug / release builds. .SS Options .INDENT 0.0 .TP .B AssertMacros A comma\-separated list of the names of assert macros to be checked. Default is \fIassert,NSAssert,NSCAssert\fP\&. .UNINDENT .INDENT 0.0 .TP .B CheckFunctionCalls Whether to treat non\-const member and non\-member functions as they produce side effects. Disabled by default because it can increase the number of false positive warnings. .UNINDENT .INDENT 0.0 .TP .B IgnoredFunctions A semicolon\-separated list of the names of functions or methods to be considered as not having side\-effects. Regular expressions are accepted, e.g. \fB[Rr]ef(erence)?$\fP matches every type with suffix \fBRef\fP, \fBref\fP, \fBReference\fP and \fBreference\fP\&. The default is empty. If a name in the list contains the sequence \fI::\fP it is matched against the qualified type name (i.e. \fBnamespace::Type\fP), otherwise it is matched against only the type name (i.e. \fBType\fP). .UNINDENT .SS bugprone\-assignment\-in\-if\-condition .sp Finds assignments within conditions of \fIif\fP statements. Such assignments are bug\-prone because they may have been intended as equality tests. .sp This check finds all assignments within \fIif\fP conditions, including ones that are not flagged by \fI\-Wparentheses\fP due to an extra set of parentheses, and including assignments that call an overloaded \fBoperator=()\fP\&. The identified assignments violate BARR group \(dqRule 8.2.c\(dq \%\&. .INDENT 0.0 .INDENT 3.5 .sp .EX int f = 3; if(f = 4) { // This is identified by both \(gaWparentheses\(ga and this check \- should it have been: \(gaif (f == 4)\(ga ? f = f + 1; } if((f == 5) || (f = 6)) { // the assignment here \(ga(f = 6)\(ga is identified by this check, but not by \(ga\-Wparentheses\(ga. Should it have been \(ga(f == 6)\(ga ? f = f + 2; } .EE .UNINDENT .UNINDENT .SS bugprone\-bad\-signal\-to\-kill\-thread .sp Finds \fBpthread_kill\fP function calls when a thread is terminated by raising \fBSIGTERM\fP signal and the signal kills the entire process, not just the individual thread. Use any signal except \fBSIGTERM\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .EX pthread_kill(thread, SIGTERM); .EE .UNINDENT .UNINDENT .sp This check corresponds to the CERT C Coding Standard rule POS44\-C. Do not use signals to terminate threads \%\&. .sp \fIcert\-pos44\-c\fP redirects here as an alias of this check. .SS bugprone\-bitwise\-pointer\-cast .sp Warns about code that tries to cast between pointers by means of \fBstd::bit_cast\fP or \fBmemcpy\fP\&. .sp The motivation is that \fBstd::bit_cast\fP is advertised as the safe alternative to type punning via \fBreinterpret_cast\fP in modern C++. However, one should not blindly replace \fBreinterpret_cast\fP with \fBstd::bit_cast\fP, as follows: .INDENT 0.0 .INDENT 3.5 .sp .EX int x{}; \-float y = *reinterpret_cast(&x); +float y = *std::bit_cast(&x); .EE .UNINDENT .UNINDENT .sp The drop\-in replacement behaves exactly the same as \fBreinterpret_cast\fP, and Undefined Behavior is still invoked. \fBstd::bit_cast\fP is copying the bytes of the input pointer, not the pointee, into an output pointer of a different type, which may violate the strict aliasing rules. However, simply looking at the code, it looks \(dqsafe\(dq, because it uses \fBstd::bit_cast\fP which is advertised as safe. .sp The solution to safe type punning is to apply \fBstd::bit_cast\fP on value types, not on pointer types: .INDENT 0.0 .INDENT 3.5 .sp .EX int x{}; float y = std::bit_cast(x); .EE .UNINDENT .UNINDENT .sp This way, the bytes of the input object are copied into the output object, which is much safer. Do note that Undefined Behavior can still occur, if there is no value of type \fBTo\fP corresponding to the value representation produced. Compilers may be able to optimize this copy and generate identical assembly to the original \fBreinterpret_cast\fP version. .sp Code before C++20 may backport \fBstd::bit_cast\fP by means of \fBmemcpy\fP, or simply call \fBmemcpy\fP directly, which is equally problematic. This is also detected by this check: .INDENT 0.0 .INDENT 3.5 .sp .EX int* x{}; float* y{}; std::memcpy(&y, &x, sizeof(x)); .EE .UNINDENT .UNINDENT .sp Alternatively, if a cast between pointers is truly wanted, \fBreinterpret_cast\fP should be used, to clearly convey the intent and enable warnings from compilers and linters, which should be addressed accordingly. .SS bugprone\-bool\-pointer\-implicit\-conversion .sp Checks for conditions based on implicit conversion from a \fBbool\fP pointer to \fBbool\fP\&. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX bool *p; if (p) { // Never used in a pointer\-specific way. } .EE .UNINDENT .UNINDENT .SS bugprone\-branch\-clone .sp Checks for repeated branches in \fBif/else if/else\fP chains, consecutive repeated branches in \fBswitch\fP statements and identical true and false branches in conditional operators. .INDENT 0.0 .INDENT 3.5 .sp .EX if (test_value(x)) { y++; do_something(x, y); } else { y++; do_something(x, y); } .EE .UNINDENT .UNINDENT .sp In this simple example (which could arise e.g. as a copy\-paste error) the \fBthen\fP and \fBelse\fP branches are identical and the code is equivalent the following shorter and cleaner code: .INDENT 0.0 .INDENT 3.5 .sp .EX test_value(x); // can be omitted unless it has side effects y++; do_something(x, y); .EE .UNINDENT .UNINDENT .sp If this is the intended behavior, then there is no reason to use a conditional statement; otherwise the issue can be solved by fixing the branch that is handled incorrectly. .sp The check detects repeated branches in longer \fBif/else if/else\fP chains where it would be even harder to notice the problem. .sp The check also detects repeated inner and outer \fBif\fP statements that may be a result of a copy\-paste error. This check cannot currently detect identical inner and outer \fBif\fP statements if code is between the \fBif\fP conditions. An example is as follows. .INDENT 0.0 .INDENT 3.5 .sp .EX void test_warn_inner_if_1(int x) { if (x == 1) { // warns, if with identical inner if if (x == 1) // inner if is here ; if (x == 1) { // does not warn, cannot detect int y = x; if (x == 1) ; } } .EE .UNINDENT .UNINDENT .sp In \fBswitch\fP statements the check only reports repeated branches when they are consecutive, because it is relatively common that the \fBcase:\fP labels have some natural ordering and rearranging them would decrease the readability of the code. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX switch (ch) { case \(aqa\(aq: return 10; case \(aqA\(aq: return 10; case \(aqb\(aq: return 11; case \(aqB\(aq: return 11; default: return 10; } .EE .UNINDENT .UNINDENT .sp Here the check reports that the \fB\(aqa\(aq\fP and \fB\(aqA\(aq\fP branches are identical (and that the \fB\(aqb\(aq\fP and \fB\(aqB\(aq\fP branches are also identical), but does not report that the \fBdefault:\fP branch is also identical to the first two branches. If this is indeed the correct behavior, then it could be implemented as: .INDENT 0.0 .INDENT 3.5 .sp .EX switch (ch) { case \(aqa\(aq: case \(aqA\(aq: return 10; case \(aqb\(aq: case \(aqB\(aq: return 11; default: return 10; } .EE .UNINDENT .UNINDENT .sp Here the check does not warn for the repeated \fBreturn 10;\fP, which is good if we want to preserve that \fB\(aqa\(aq\fP is before \fB\(aqb\(aq\fP and \fBdefault:\fP is the last branch. .sp Switch cases marked with the \fB[[fallthrough]]\fP attribute are ignored. .sp Finally, the check also examines conditional operators and reports code like: .INDENT 0.0 .INDENT 3.5 .sp .EX return test_value(x) ? x : x; .EE .UNINDENT .UNINDENT .sp Unlike if statements, the check does not detect chains of conditional operators. .sp Note: This check also reports situations where branches become identical only after preprocessing. .SS bugprone\-capturing\-this\-in\-member\-variable .sp Finds lambda captures that capture the \fBthis\fP pointer and store it as class members without handle the copy and move constructors and the assignments. .sp Capture this in a lambda and store it as a class member is dangerous because the lambda can outlive the object it captures. Especially when the object is copied or moved, the captured \fBthis\fP pointer will be implicitly propagated to the new object. Most of the time, people will believe that the captured \fBthis\fP pointer points to the new object, which will lead to bugs. .INDENT 0.0 .INDENT 3.5 .sp .EX struct C { C() : Captured([this]() \-> C const * { return this; }) {} std::function Captured; }; void foo() { C v1{}; C v2 = v1; // v2.Captured capture v1\(aqs \(aqthis\(aq pointer assert(v2.Captured() == v1.Captured()); // v2.Captured capture v1\(aqs \(aqthis\(aq pointer assert(v2.Captured() == &v2); // assertion failed. } .EE .UNINDENT .UNINDENT .INDENT 0.0 .TP .B Possible fixes: .INDENT 7.0 .IP \(bu 2 marking copy and move constructors and assignment operators deleted. .IP \(bu 2 using class member method instead of class member variable with function object types. .IP \(bu 2 passing \fBthis\fP pointer as parameter. .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B FunctionWrapperTypes A semicolon\-separated list of names of types. Used to specify function wrapper that can hold lambda expressions. Default is \fI::std::function;::std::move_only_function;::boost::function\fP\&. .UNINDENT .INDENT 0.0 .TP .B BindFunctions A semicolon\-separated list of fully qualified names of functions that can capture \fBthis\fP pointer. Default is \fI::std::bind;::boost::bind;::std::bind_front;::std::bind_back; ::boost::compat::bind_front;::boost::compat::bind_back\fP\&. .UNINDENT .SS bugprone\-casting\-through\-void .sp Detects unsafe or redundant two\-step casting operations involving \fBvoid*\fP, which is equivalent to \fBreinterpret_cast\fP as per the C++ Standard \%\&. .sp Two\-step type conversions via \fBvoid*\fP are discouraged for several reasons. .INDENT 0.0 .IP \(bu 2 They obscure code and impede its understandability, complicating maintenance. .IP \(bu 2 These conversions bypass valuable compiler support, erasing warnings related to pointer alignment. It may violate strict aliasing rule and leading to undefined behavior. .IP \(bu 2 In scenarios involving multiple inheritance, ambiguity and unexpected outcomes can arise due to the loss of type information, posing runtime issues. .UNINDENT .sp In summary, avoiding two\-step type conversions through \fBvoid*\fP ensures clearer code, maintains essential compiler warnings, and prevents ambiguity and potential runtime errors, particularly in complex inheritance scenarios. If such a cast is wanted, it shall be done via \fBreinterpret_cast\fP, to express the intent more clearly. .sp Note: it is expected that, after applying the suggested fix and using \fBreinterpret_cast\fP, the check cppcoreguidelines\-pro\-type\-reinterpret\-cast \%<> will emit a warning. This is intentional: \fBreinterpret_cast\fP is a dangerous operation that can easily break the strict aliasing rules when dereferencing the casted pointer, invoking Undefined Behavior. The warning is there to prompt users to carefully analyze whether the usage of \fBreinterpret_cast\fP is safe, in which case the warning may be suppressed. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX using IntegerPointer = int *; double *ptr; static_cast(static_cast(ptr)); // WRONG reinterpret_cast(reinterpret_cast(ptr)); // WRONG (IntegerPointer)(void *)ptr; // WRONG IntegerPointer(static_cast(ptr)); // WRONG reinterpret_cast(ptr); // OK, clearly expresses intent. // NOTE: dereferencing this pointer violates // the strict aliasing rules, invoking // Undefined Behavior. .EE .UNINDENT .UNINDENT .SS bugprone\-chained\-comparison .sp Check detects chained comparison operators that can lead to unintended behavior or logical errors. .sp Chained comparisons are expressions that use multiple comparison operators to compare three or more values. For example, the expression \fBa < b < c\fP compares the values of \fBa\fP, \fBb\fP, and \fBc\fP\&. However, this expression does not evaluate as \fB(a < b) && (b < c)\fP, which is probably what the developer intended. Instead, it evaluates as \fB(a < b) < c\fP, which may produce unintended results, especially when the types of \fBa\fP, \fBb\fP, and \fBc\fP are different. .sp To avoid such errors, the check will issue a warning when a chained comparison operator is detected, suggesting to use parentheses to specify the order of evaluation or to use a logical operator to separate comparison expressions. .sp Consider the following examples: .INDENT 0.0 .INDENT 3.5 .sp .EX int a = 2, b = 6, c = 4; if (a < b < c) { // This block will be executed } .EE .UNINDENT .UNINDENT .sp In this example, the developer intended to check if \fBa\fP is less than \fBb\fP and \fBb\fP is less than \fBc\fP\&. However, the expression \fBa < b < c\fP is equivalent to \fB(a < b) < c\fP\&. Since \fBa < b\fP is \fBtrue\fP, the expression \fB(a < b) < c\fP is evaluated as \fB1 < c\fP, which is equivalent to \fBtrue < c\fP and is invalid in this case as \fBb < c\fP is \fBfalse\fP\&. .sp Even that above issue could be detected as comparison of \fBint\fP to \fBbool\fP, there is more dangerous example: .INDENT 0.0 .INDENT 3.5 .sp .EX bool a = false, b = false, c = true; if (a == b == c) { // This block will be executed } .EE .UNINDENT .UNINDENT .sp In this example, the developer intended to check if \fBa\fP, \fBb\fP, and \fBc\fP are all equal. However, the expression \fBa == b == c\fP is evaluated as \fB(a == b) == c\fP\&. Since \fBa == b\fP is true, the expression \fB(a == b) == c\fP is evaluated as \fBtrue == c\fP, which is equivalent to \fBtrue == true\fP\&. This comparison yields \fBtrue\fP, even though \fBa\fP and \fBb\fP are \fBfalse\fP, and are not equal to \fBc\fP\&. .sp To avoid this issue, the developer can use a logical operator to separate the comparison expressions, like this: .INDENT 0.0 .INDENT 3.5 .sp .EX if (a == b && b == c) { // This block will not be executed } .EE .UNINDENT .UNINDENT .sp Alternatively, use of parentheses in the comparison expressions can make the developer\(aqs intention more explicit and help avoid misunderstanding. .INDENT 0.0 .INDENT 3.5 .sp .EX if ((a == b) == c) { // This block will be executed } .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IgnoreMacros If \fItrue\fP, the check will not warn on chained comparisons inside macros. Default is \fIfalse\fP\&. .UNINDENT .SS bugprone\-command\-processor .sp Flags calls to \fBsystem()\fP, \fBpopen()\fP, and \fB_popen()\fP, which execute a command processor. It does not flag calls to \fBsystem()\fP with a null pointer argument, as such a call checks for the presence of a command processor but does not actually attempt to execute a command. .SS References .sp This check corresponds to the CERT C Coding Standard rule ENV33\-C. Do not call system() \%\&. .SS bugprone\-compare\-pointer\-to\-member\-virtual\-function .sp Detects unspecified behavior about equality comparison between pointer to member virtual function and anything other than null\-pointer\-constant. .INDENT 0.0 .INDENT 3.5 .sp .EX struct A { void f1(); void f2(); virtual void f3(); virtual void f4(); void g1(int); }; void fn() { bool r1 = (&A::f1 == &A::f2); // ok bool r2 = (&A::f1 == &A::f3); // bugprone bool r3 = (&A::f1 != &A::f3); // bugprone bool r4 = (&A::f3 == nullptr); // ok bool r5 = (&A::f3 == &A::f4); // bugprone void (A::*v1)() = &A::f3; bool r6 = (v1 == &A::f1); // bugprone bool r6 = (v1 == nullptr); // ok void (A::*v2)() = &A::f2; bool r7 = (v2 == &A::f1); // false positive, but potential risk if assigning other value to v2. void (A::*v3)(int) = &A::g1; bool r8 = (v3 == &A::g1); // ok, no virtual function match void(A::*)(int) signature. } .EE .UNINDENT .UNINDENT .sp Provide warnings on equality comparisons involve pointers to member virtual function or variables which is potential pointer to member virtual function and any entity other than a null\-pointer constant. .sp In certain compilers, virtual function addresses are not conventional pointers but instead consist of offsets and indexes within a virtual function table (vtable). Consequently, these pointers may vary between base and derived classes, leading to unpredictable behavior when compared directly. This issue becomes particularly challenging when dealing with pointers to pure virtual functions, as they may not even have a valid address, further complicating comparisons. .sp Instead, it is recommended to utilize the \fBtypeid\fP operator or other appropriate mechanisms for comparing objects to ensure robust and predictable behavior in your codebase. By heeding this detection and adopting a more reliable comparison method, you can mitigate potential issues related to unspecified behavior, especially when dealing with pointers to member virtual functions or pure virtual functions, thereby improving the overall stability and maintainability of your code. In scenarios involving pointers to member virtual functions, it\(aqs only advisable to employ \fBnullptr\fP for comparisons. .SS Limitations .sp Does not analyze values stored in a variable. For variable, only analyze all virtual methods in the same \fBclass\fP or \fBstruct\fP and diagnose when assigning a pointer to member virtual function to this variable is possible. .SS bugprone\-copy\-constructor\-init .sp Finds copy constructors where the constructor doesn\(aqt call the copy constructor of the base class. .INDENT 0.0 .INDENT 3.5 .sp .EX class Copyable { public: Copyable() = default; Copyable(const Copyable &) = default; int memberToBeCopied = 0; }; class X2 : public Copyable { X2(const X2 &other) {} // Copyable(other) is missing }; .EE .UNINDENT .UNINDENT .sp Also finds copy constructors where the constructor of the base class don\(aqt have parameter. .INDENT 0.0 .INDENT 3.5 .sp .EX class X3 : public Copyable { X3(const X3 &other) : Copyable() {} // other is missing }; .EE .UNINDENT .UNINDENT .sp Failure to properly initialize base class sub\-objects during copy construction can result in undefined behavior, crashes, data corruption, or other unexpected outcomes. The check ensures that the copy constructor of a derived class properly calls the copy constructor of the base class, helping to prevent bugs and improve code quality. .SS Limitations .INDENT 0.0 .IP \(bu 2 It won\(aqt generate warnings for empty classes, as there are no class members (including base class sub\-objects) to worry about. .IP \(bu 2 It won\(aqt generate warnings for base classes that have copy constructor private or deleted. .IP \(bu 2 It won\(aqt generate warnings for base classes that are initialized using other non\-default constructor, as this could be intentional. .UNINDENT .sp The check also suggests a fix\-its in some cases. .SS bugprone\-copy\-constructor\-mutates\-argument .sp Finds assignments to the copied object and its direct or indirect members in copy constructors and copy assignment operators. .sp This check corresponds to the CERT C Coding Standard rule OOP58\-CPP. Copy operations must not mutate the source object \%\&. .SS bugprone\-crtp\-constructor\-accessibility .sp Detects error\-prone Curiously Recurring Template Pattern usage, when the CRTP can be constructed outside itself and the derived class. .sp The CRTP is an idiom, in which a class derives from a template class, where itself is the template argument. It should be ensured that if a class is intended to be a base class in this idiom, it can only be instantiated if the derived class is its template argument. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX template class CRTP { private: CRTP() = default; friend T; }; class Derived : CRTP {}; .EE .UNINDENT .UNINDENT .sp Below can be seen some common mistakes that will allow the breaking of the idiom. .sp If the constructor of a class intended to be used in a CRTP is public, then it allows users to construct that class on its own. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX template class CRTP { public: CRTP() = default; }; class Good : CRTP {}; Good GoodInstance; CRTP BadInstance; .EE .UNINDENT .UNINDENT .sp If the constructor is protected, the possibility of an accidental instantiation is prevented, however it can fade an error, when a different class is used as the template parameter instead of the derived one. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX template class CRTP { protected: CRTP() = default; }; class Good : CRTP {}; Good GoodInstance; class Bad : CRTP {}; Bad BadInstance; .EE .UNINDENT .UNINDENT .sp To ensure that no accidental instantiation happens, the best practice is to make the constructor private and declare the derived class as friend. Note that as a tradeoff, this also gives the derived class access to every other private members of the CRTP. However, constructors can still be public or protected if they are deleted. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX template class CRTP { CRTP() = default; friend T; }; class Good : CRTP {}; Good GoodInstance; class Bad : CRTP {}; Bad CompileTimeError; CRTP AlsoCompileTimeError; .EE .UNINDENT .UNINDENT .SS Limitations .INDENT 0.0 .IP \(bu 2 The check is not supported below C++11 .IP \(bu 2 The check does not handle when the derived class is passed as a variadic template argument .IP \(bu 2 Accessible functions that can construct the CRTP, like factory functions are not checked .UNINDENT .sp The check also suggests a fix\-its in some cases. .SS bugprone\-dangling\-handle .sp Detect dangling references in value handles like \fBstd::string_view\fP\&. These dangling references can be a result of constructing handles from temporary values, where the temporary is destroyed soon after the handle is created. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX string_view View = string(); // View will dangle. string A; View = A + \(dqA\(dq; // still dangle. vector V; V.push_back(string()); // V[0] is dangling. V.resize(3, string()); // V[1] and V[2] will also dangle. string_view f() { // All these return values will dangle. return string(); string S; return S; char Array[10]{}; return Array; } span g() { array V; return {V}; int Array[10]{}; return {Array}; } .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B HandleClasses A semicolon\-separated list of class names that should be treated as handles. By default only \fBstd::basic_string_view\fP, \fBstd::experimental::basic_string_view\fP and \fBstd::span\fP are considered. .UNINDENT .SS bugprone\-default\-operator\-new\-on\-overaligned\-type .sp Flags uses of default \fBoperator new\fP where the type has extended alignment (an alignment greater than the fundamental alignment). .sp The default \fBoperator new\fP is guaranteed to provide the correct alignment if the requested alignment is less or equal to the fundamental alignment. Only cases are detected (by design) where the \fBoperator new\fP is not user\-defined and is not a placement new (the reason is that in these cases we assume that the user provided the correct memory allocation). .SS References .sp This check corresponds to the CERT C++ Coding Standard rule MEM57\-CPP. Avoid using default operator new for over\-aligned types \%\&. .SS bugprone\-derived\-method\-shadowing\-base\-method .sp Finds derived class methods that shadow a (non\-virtual) base class method. .sp In order to be considered \(dqshadowing\(dq, methods must have the same signature (i.e. the same name, same number of parameters, same parameter types, etc). Only checks public, non\-templated methods. .sp The below example is bugprone because consumers of the \fBDerived\fP class will expect the \fBreset\fP method to do the work of \fBBase::reset()\fP in addition to extra work required to reset the \fBDerived\fP class. Common fixes include: .INDENT 0.0 .IP \(bu 2 Making the \fBreset\fP method polymorphic .IP \(bu 2 Re\-naming \fBDerived::reset\fP if it\(aqs not meant to intersect with \fBBase::reset\fP .IP \(bu 2 Using \fBusing Base::reset\fP to change the access specifier .UNINDENT .sp This is also a violation of the Liskov Substitution Principle. .INDENT 0.0 .INDENT 3.5 .sp .EX struct Base { void reset() {/* reset the base class */}; }; struct Derived : public Base { void reset() {/* reset the derived class, but not the base class */}; }; .EE .UNINDENT .UNINDENT .SS bugprone\-dynamic\-static\-initializers .sp Finds instances of static variables that are dynamically initialized in header files. .sp This can pose problems in certain multithreaded contexts. For example, when disabling compiler generated synchronization instructions for static variables initialized at runtime (e.g. by \fB\-fno\-threadsafe\-statics\fP), even if a particular project takes the necessary precautions to prevent race conditions during initialization by providing their own synchronization, header files included from other projects may not. Therefore, such a check is helpful for ensuring that disabling compiler generated synchronization for static variable initialization will not cause problems. .sp Consider the following code: .INDENT 0.0 .INDENT 3.5 .sp .EX int foo() { static int k = bar(); return k; } .EE .UNINDENT .UNINDENT .sp When synchronization of static initialization is disabled, if two threads both call \fIfoo\fP for the first time, there is the possibility that \fIk\fP will be double initialized, creating a race condition. .SS bugprone\-easily\-swappable\-parameters .sp Finds function definitions where parameters of convertible types follow each other directly, making call sites prone to calling the function with swapped (or badly ordered) arguments. .INDENT 0.0 .INDENT 3.5 .sp .EX void drawPoint(int X, int Y) { /* ... */ } FILE *open(const char *Dir, const char *Name, Flags Mode) { /* ... */ } .EE .UNINDENT .UNINDENT .sp A potential call like \fBdrawPoint(\-2, 5)\fP or \fBopenPath(\(dqa.txt\(dq, \(dqtmp\(dq, Read)\fP is perfectly legal from the language\(aqs perspective, but might not be what the developer of the function intended. .sp More elaborate and type\-safe constructs, such as opaque typedefs or strong types should be used instead, to prevent a mistaken order of arguments. .INDENT 0.0 .INDENT 3.5 .sp .EX struct Coord2D { int X; int Y; }; void drawPoint(const Coord2D Pos) { /* ... */ } FILE *open(const Path &Dir, const Filename &Name, Flags Mode) { /* ... */ } .EE .UNINDENT .UNINDENT .sp Due to the potentially elaborate refactoring and API\-breaking that is necessary to strengthen the type safety of a project, no automatic fix\-its are offered. .SS Options .SS Extension/relaxation options .sp Relaxation (or extension) options can be used to broaden the scope of the analysis and fine\-tune the enabling of more mixes between types. Some mixes may depend on coding style or preference specific to a project, however, it should be noted that enabling \fIall\fP of these relaxations model the way of mixing at call sites the most. These options are expected to make the check report for more functions, and report longer mixable ranges. .INDENT 0.0 .TP .B QualifiersMix Whether to consider parameters of some \fIcvr\-qualified\fP \fBT\fP and a differently \fIcvr\-qualified\fP \fBT\fP (i.e. \fBT\fP and \fBconst T\fP, \fBconst T\fP and \fBvolatile T\fP, etc.) mixable between one another. If \fIfalse\fP, the check will consider differently qualified types unmixable. \fITrue\fP turns the warnings on. Defaults to \fIfalse\fP\&. .sp The following example produces a diagnostic only if \fIQualifiersMix\fP is enabled: .INDENT 7.0 .INDENT 3.5 .sp .EX void *memcpy(const void *Destination, void *Source, std::size_t N) { /* ... */ } .EE .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B ModelImplicitConversions Whether to consider parameters of type \fBT\fP and \fBU\fP mixable if there exists an implicit conversion from \fBT\fP to \fBU\fP and \fBU\fP to \fBT\fP\&. If \fIfalse\fP, the check will not consider implicitly convertible types for mixability. \fITrue\fP turns warnings for implicit conversions on. Defaults to \fItrue\fP\&. .sp The following examples produce a diagnostic only if \fIModelImplicitConversions\fP is enabled: .INDENT 7.0 .INDENT 3.5 .sp .EX void fun(int Int, double Double) { /* ... */ } void compare(const char *CharBuf, std::string String) { /* ... */ } .EE .UNINDENT .UNINDENT .sp \fBNote:\fP .INDENT 7.0 .INDENT 3.5 Changing the qualifiers of an expression\(aqs type (e.g. from \fBint\fP to \fBconst int\fP) is defined as an \fIimplicit conversion\fP in the C++ Standard. However, the check separates this decision\-making on the mixability of differently qualified types based on whether \fIQualifiersMix\fP was enabled. .sp For example, the following code snippet will only produce a diagnostic if \fBboth\fP \fIQualifiersMix\fP and \fIModelImplicitConversions\fP are enabled: .INDENT 0.0 .INDENT 3.5 .sp .EX void fun2(int Int, const double Double) { /* ... */ } .EE .UNINDENT .UNINDENT .UNINDENT .UNINDENT .UNINDENT .SS Filtering options .sp Filtering options can be used to lessen the size of the diagnostics emitted by the checker, whether the aim is to ignore certain constructs or dampen the noisiness. .INDENT 0.0 .TP .B MinimumLength The minimum length required from an adjacent parameter sequence to be diagnosed. Defaults to \fI2\fP\&. Might be any positive integer greater or equal to \fI2\fP\&. If \fI0\fP or \fI1\fP is given, the default value \fI2\fP will be used instead. .sp For example, if \fI3\fP is specified, the examples above will not be matched. .UNINDENT .INDENT 0.0 .TP .B IgnoredParameterNames The list of parameter \fBnames\fP that should never be considered part of a swappable adjacent parameter sequence. The value is a \fI;\fP\-separated list of names. To ignore unnamed parameters, add \fI\(dq\(dq\fP to the list verbatim (not the empty string, but the two quotes, potentially escaped!). \fBThis option is case\-sensitive!\fP .sp By default, the following parameter names, and their Uppercase\-initial variants are ignored: \fI\(dq\(dq\fP (unnamed parameters), \fIiterator\fP, \fIbegin\fP, \fIend\fP, \fIfirst\fP, \fIlast\fP, \fIlhs\fP, \fIrhs\fP\&. .UNINDENT .INDENT 0.0 .TP .B IgnoredParameterTypeSuffixes The list of parameter \fBtype name suffixes\fP that should never be considered part of a swappable adjacent parameter sequence. Parameters which type, as written in the source code, end with an element of this option will be ignored. The value is a \fI;\fP\-separated list of names. \fBThis option is case\-sensitive!\fP .sp By default, the following, and their lowercase\-initial variants are ignored: \fIbool\fP, \fIIt\fP, \fIIterator\fP, \fIInputIt\fP, \fIForwardIt\fP, \fIBidirIt\fP, \fIRandomIt\fP, \fIrandom_iterator\fP, \fIReverseIt\fP, \fIreverse_iterator\fP, \fIreverse_const_iterator\fP, \fIRandomIt\fP, \fIrandom_iterator\fP, \fIReverseIt\fP, \fIreverse_iterator\fP, \fIreverse_const_iterator\fP, \fIConst_Iterator\fP, \fIConstIterator\fP, \fIconst_reverse_iterator\fP, \fIConstReverseIterator\fP\&. In addition, \fI_Bool\fP (but not \fI_bool\fP) is also part of the default value. .UNINDENT .INDENT 0.0 .TP .B SuppressParametersUsedTogether Suppresses diagnostics about parameters that are used together or in a similar fashion inside the function\(aqs body. Defaults to \fItrue\fP\&. Specifying \fIfalse\fP will turn off the heuristics. .sp Currently, the following heuristics are implemented which will suppress the warning about the parameter pair involved: .INDENT 7.0 .IP \(bu 2 The parameters are used in the same expression, e.g. \fBf(a, b)\fP or \fBa < b\fP\&. .IP \(bu 2 The parameters are further passed to the same function to the same parameter of that function, of the same overload. E.g. \fBf(a, 1)\fP and \fBf(b, 2)\fP to some \fBf(T, int)\fP\&. .sp \fBNote:\fP .INDENT 2.0 .INDENT 3.5 The check does not perform path\-sensitive analysis, and as such, \(dqsame function\(dq in this context means the same function declaration. If the same member function of a type on two distinct instances are called with the parameters, it will still be regarded as \(dqsame function\(dq. .UNINDENT .UNINDENT .IP \(bu 2 The same member field is accessed, or member method is called of the two parameters, e.g. \fBa.foo()\fP and \fBb.foo()\fP\&. .IP \(bu 2 Separate \fBreturn\fP statements return either of the parameters on different code paths. .UNINDENT .UNINDENT .INDENT 0.0 .TP .B NamePrefixSuffixSilenceDissimilarityThreshold The number of characters two parameter names might be different on \fIeither\fP the head or the tail end with the rest of the name the same so that the warning about the two parameters are silenced. Defaults to \fI1\fP\&. Might be any positive integer. If \fI0\fP, the filtering heuristic based on the parameters\(aq names is turned off. .sp This option can be used to silence warnings about parameters where the naming scheme indicates that the order of those parameters do not matter. .sp For example, the parameters \fBLHS\fP and \fBRHS\fP are 1\-dissimilar suffixes of each other: \fBL\fP and \fBR\fP is the different character, while \fBHS\fP is the common suffix. Similarly, parameters \fBtext1, text2, text3\fP are 1\-dissimilar prefixes of each other, with the numbers at the end being the dissimilar part. If the value is at least \fI1\fP, such cases will not be reported. .UNINDENT .SS Limitations .sp \fBThis check is designed to check function signatures!\fP .sp The check does not investigate functions that are generated by the compiler in a context that is only determined from a call site. These cases include variadic functions, functions in C code that do not have an argument list, and C++ template instantiations. Most of these cases, which are otherwise swappable from a caller\(aqs standpoint, have no way of getting \(dqfixed\(dq at the definition point. In the case of C++ templates, only primary template definitions and explicit specializations are matched and analyzed. .sp None of the following cases produce a diagnostic: .INDENT 0.0 .INDENT 3.5 .sp .EX int printf(const char *Format, ...) { /* ... */ } int someOldCFunction() { /* ... */ } template int add(T X, U Y) { return X + Y }; void theseAreNotWarnedAbout() { printf(\(dq%d %d\en\(dq, 1, 2); // Two ints passed, they could be swapped. someOldCFunction(1, 2, 3); // Similarly, multiple ints passed. add(1, 2); // Instantiates \(aqadd\(aq, but that\(aqs not a user\-defined function. } .EE .UNINDENT .UNINDENT .sp Due to the limitation above, parameters which type are further dependent upon template instantiations to \fIprove\fP that they mix with another parameter\(aqs is not diagnosed. .INDENT 0.0 .INDENT 3.5 .sp .EX template struct Vector { typedef T element_type; }; // Diagnosed: Explicit instantiation was done by the user, we can prove it // is the same type. void instantiated(int A, Vector::element_type B) { /* ... */ } // Diagnosed: The two parameter types are exactly the same. template void exact(typename Vector::element_type A, typename Vector::element_type B) { /* ... */ } // Skipped: The two parameters are both \(aqT\(aq but we cannot prove this // without actually instantiating. template void falseNegative(T A, typename Vector::element_type B) { /* ... */ } .EE .UNINDENT .UNINDENT .sp In the context of \fIimplicit conversions\fP (when \fIModelImplicitConversions\fP is enabled), the modelling performed by the check warns if the parameters are swappable and the swapped order matches implicit conversions. It does not model whether there exists an unrelated third type from which \fIboth\fP parameters can be given in a function call. This means that in the following example, even while \fBstrs()\fP clearly carries the possibility to be called with swapped arguments (as long as the arguments are string literals), will not be warned about. .INDENT 0.0 .INDENT 3.5 .sp .EX struct String { String(const char *Buf); }; struct StringView { StringView(const char *Buf); operator const char *() const; }; // Skipped: Directly swapping expressions of the two type cannot mix. // (Note: StringView \-> const char * \-> String would be **two** // user\-defined conversions, which is disallowed by the language.) void strs(String Str, StringView SV) { /* ... */ } // Diagnosed: StringView implicitly converts to and from a buffer. void cStr(StringView SV, const char *Buf() { /* ... */ } .EE .UNINDENT .UNINDENT .SS bugprone\-empty\-catch .sp Detects and suggests addressing issues with empty catch statements. .INDENT 0.0 .INDENT 3.5 .sp .EX try { // Some code that can throw an exception } catch(const std::exception&) { } .EE .UNINDENT .UNINDENT .sp Having empty catch statements in a codebase can be a serious problem that developers should be aware of. Catch statements are used to handle exceptions that are thrown during program execution. When an exception is thrown, the program jumps to the nearest catch statement that matches the type of the exception. .sp Empty catch statements, also known as \(dqswallowing\(dq exceptions, catch the exception but do nothing with it. This means that the exception is not handled properly, and the program continues to run as if nothing happened. This can lead to several issues, such as: .INDENT 0.0 .IP \(bu 2 \fIHidden Bugs\fP: If an exception is caught and ignored, it can lead to hidden bugs that are difficult to diagnose and fix. The root cause of the problem may not be apparent, and the program may continue to behave in unexpected ways. .IP \(bu 2 \fISecurity Issues\fP: Ignoring exceptions can lead to security issues, such as buffer overflows or null pointer dereferences. Hackers can exploit these vulnerabilities to gain access to sensitive data or execute malicious code. .IP \(bu 2 \fIPoor Code Quality\fP: Empty catch statements can indicate poor code quality and a lack of attention to detail. This can make the codebase difficult to maintain and update, leading to longer development cycles and increased costs. .IP \(bu 2 \fIUnreliable Code\fP: Code that ignores exceptions is often unreliable and can lead to unpredictable behavior. This can cause frustration for users and erode trust in the software. .UNINDENT .sp To avoid these issues, developers should always handle exceptions properly. This means either fixing the underlying issue that caused the exception or propagating the exception up the call stack to a higher\-level handler. If an exception is not important, it should still be logged or reported in some way so that it can be tracked and addressed later. .sp If the exception is something that can be handled locally, then it should be handled within the catch block. This could involve logging the exception or taking other appropriate action to ensure that the exception is not ignored. .sp Here is an example: .INDENT 0.0 .INDENT 3.5 .sp .EX try { // Some code that can throw an exception } catch (const std::exception& ex) { // Properly handle the exception, e.g.: std::cerr << \(dqException caught: \(dq << ex.what() << std::endl; } .EE .UNINDENT .UNINDENT .sp If the exception cannot be handled locally and needs to be propagated up the call stack, it should be re\-thrown or new exception should be thrown. .sp Here is an example: .INDENT 0.0 .INDENT 3.5 .sp .EX try { // Some code that can throw an exception } catch (const std::exception& ex) { // Re\-throw the exception throw; } .EE .UNINDENT .UNINDENT .sp In some cases, catching the exception at this level may not be necessary, and it may be appropriate to let the exception propagate up the call stack. This can be done simply by not using \fBtry/catch\fP block. .sp Here is an example: .INDENT 0.0 .INDENT 3.5 .sp .EX void function() { // Some code that can throw an exception } void callerFunction() { try { function(); } catch (const std::exception& ex) { // Handling exception on higher level std::cerr << \(dqException caught: \(dq << ex.what() << std::endl; } } .EE .UNINDENT .UNINDENT .sp Other potential solution to avoid empty catch statements is to modify the code to avoid throwing the exception in the first place. This can be achieved by using a different API, checking for error conditions beforehand, or handling errors in a different way that does not involve exceptions. By eliminating the need for try\-catch blocks, the code becomes simpler and less error\-prone. .sp Here is an example: .INDENT 0.0 .INDENT 3.5 .sp .EX // Old code: try { mapContainer[\(dqKey\(dq].callFunction(); } catch(const std::out_of_range&) { } // New code if (auto it = mapContainer.find(\(dqKey\(dq); it != mapContainer.end()) { it\->second.callFunction(); } .EE .UNINDENT .UNINDENT .sp In conclusion, empty catch statements are a bad practice that can lead to hidden bugs, security issues, poor code quality, and unreliable code. By handling exceptions properly, developers can ensure that their code is robust, secure, and maintainable. .SS Options .INDENT 0.0 .TP .B IgnoreCatchWithKeywords This option can be used to ignore specific catch statements containing certain keywords. If a \fBcatch\fP statement body contains (case\-insensitive) any of the keywords listed in this semicolon\-separated option, then the catch will be ignored, and no warning will be raised. Default value: \fI@TODO;@FIXME\fP\&. .UNINDENT .INDENT 0.0 .TP .B AllowEmptyCatchForExceptions This option can be used to ignore empty catch statements for specific exception types. By default, the check will raise a warning if an empty catch statement is detected, regardless of the type of exception being caught. However, in certain situations, such as when a developer wants to intentionally ignore certain exceptions or handle them in a different way, it may be desirable to allow empty catch statements for specific exception types. To configure this option, a semicolon\-separated list of exception type names should be provided. If an exception type name in the list is caught in an empty catch statement, no warning will be raised. Default value: empty string. .UNINDENT .SS bugprone\-exception\-copy\-constructor\-throws .sp Checks whether a thrown object\(aqs copy constructor can throw. .sp Exception objects are required to be copy constructible in C++. However, an exception\(aqs copy constructor should not throw to avoid potential issues when unwinding the stack. If an exception is thrown during stack unwinding (such as from a copy constructor of an exception object), the program will terminate via \fBstd::terminate\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .EX class SomeException { public: SomeException() = default; SomeException(const SomeException&) { /* may throw */ } }; void f() { throw SomeException(); // warning: thrown exception type\(aqs copy constructor can throw } .EE .UNINDENT .UNINDENT .SS References .sp This check corresponds to the CERT C++ Coding Standard rule ERR60\-CPP. Exception objects must be nothrow copy constructible \%\&. .SS bugprone\-exception\-escape .sp Finds functions which may throw an exception directly or indirectly, but they should not. The functions which should not throw exceptions are the following: .INDENT 0.0 .IP \(bu 2 Destructors .IP \(bu 2 Move constructors .IP \(bu 2 Move assignment operators .IP \(bu 2 The \fBmain()\fP functions .IP \(bu 2 \fBswap()\fP functions .IP \(bu 2 \fBiter_swap()\fP functions .IP \(bu 2 \fBiter_move()\fP functions .IP \(bu 2 Functions marked with \fBthrow()\fP or \fBnoexcept\fP .IP \(bu 2 Other functions given as option .UNINDENT .sp A destructor throwing an exception may result in undefined behavior, resource leaks or unexpected termination of the program. Throwing move constructor or move assignment also may result in undefined behavior or resource leak. The \fBswap()\fP operations expected to be non throwing most of the cases and they are always possible to implement in a non throwing way. Non throwing \fBswap()\fP operations are also used to create move operations. A throwing \fBmain()\fP function also results in unexpected termination. .sp Functions declared explicitly with \fBnoexcept(false)\fP or \fBthrow(exception)\fP will be excluded from the analysis, as even though it is not recommended for functions like \fBswap()\fP, \fBmain()\fP, move constructors, move assignment operators and destructors, it is a clear indication of the developer\(aqs intention and should be respected. .sp WARNING! This check may be expensive on large source files. .SS Options .INDENT 0.0 .TP .B CheckDestructors When \fItrue\fP, destructors are analyzed to not throw exceptions. Default value is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B CheckMoveMemberFunctions When \fItrue\fP, move constructors and move assignment operators are analyzed to not throw exceptions. Default value is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B CheckMain When \fItrue\fP, the \fBmain()\fP function is analyzed to not throw exceptions. Default value is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B CheckNothrowFunctions When \fItrue\fP, functions marked with \fBnoexcept\fP or \fBthrow()\fP exception specifications are analyzed to not throw exceptions. Default value is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B CheckedSwapFunctions Comma\-separated list of swap function names which should not throw exceptions. Default value is \fIswap,iter_swap,iter_move\fP\&. .UNINDENT .INDENT 0.0 .TP .B FunctionsThatShouldNotThrow Comma separated list containing function names which should not throw. An example value for this parameter can be \fBWinMain\fP which adds function \fBWinMain()\fP in the Windows API to the list of the functions which should not throw. Default value is an empty string. .UNINDENT .INDENT 0.0 .TP .B IgnoredExceptions Comma separated list containing type names which are not counted as thrown exceptions in the check. Default value is an empty string. .UNINDENT .SS bugprone\-float\-loop\-counter .sp Flags \fBfor\fP loops where the induction expression has a floating\-point type. .SS References .sp This check corresponds to the CERT C Coding Standard rule FLP30\-C. Do not use floating\-point variables as loop counters \%\&. .SS bugprone\-fold\-init\-type .sp The check flags type mismatches in folds \% like \fBstd::accumulate\fP that might result in loss of precision. \fBstd::accumulate\fP folds an input range into an initial value using the type of the latter, with \fBoperator+\fP by default. This can cause loss of precision through: .INDENT 0.0 .IP \(bu 2 Truncation: The following code uses a floating point range and an int initial value, so truncation will happen at every application of \fBoperator+\fP and the result will be \fI0\fP, which might not be what the user expected. .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .EX auto a = {0.5f, 0.5f, 0.5f, 0.5f}; return std::accumulate(std::begin(a), std::end(a), 0); .EE .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 Overflow: The following code also returns \fI0\fP\&. .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .EX auto a = {65536LL * 65536 * 65536}; return std::accumulate(std::begin(a), std::end(a), 0); .EE .UNINDENT .UNINDENT .SS bugprone\-forward\-declaration\-namespace .sp Checks if an unused forward declaration is in a wrong namespace. .sp The check inspects all unused forward declarations and checks if there is any declaration/definition with the same name existing, which could indicate that the forward declaration is in a potentially wrong namespace. .INDENT 0.0 .INDENT 3.5 .sp .EX namespace na { struct A; } namespace nb { struct A {}; } nb::A a; // warning : no definition found for \(aqA\(aq, but a definition with the same name // \(aqA\(aq found in another namespace \(aqnb::\(aq .EE .UNINDENT .UNINDENT .sp This check can only generate warnings, but it can\(aqt suggest a fix at this point. .SS bugprone\-forwarding\-reference\-overload .sp The check looks for perfect forwarding constructors that can hide copy or move constructors. If a non const lvalue reference is passed to the constructor, the forwarding reference parameter will be a better match than the const reference parameter of the copy constructor, so the perfect forwarding constructor will be called, which can be confusing. For detailed description of this issue see: Scott Meyers, Effective Modern C++, Item 26. .sp Consider the following example: .INDENT 0.0 .INDENT 3.5 .sp .EX class Person { public: // C1: perfect forwarding ctor template explicit Person(T&& n) {} // C2: perfect forwarding ctor with parameter default value template explicit Person(T&& n, int x = 1) {} // C3: perfect forwarding ctor guarded with enable_if template, void>> explicit Person(T&& n) {} // C4: variadic perfect forwarding ctor guarded with enable_if template, A&&...>, int> = 0> explicit Person(A&&... a) {} // C5: perfect forwarding ctor guarded with requires expression template requires requires { is_special; } explicit Person(T&& n) {} // C6: perfect forwarding ctor guarded with concept requirement template explicit Person(T&& n) {} // (possibly compiler generated) copy ctor Person(const Person& rhs); }; .EE .UNINDENT .UNINDENT .sp The check warns for constructors C1 and C2, because those can hide copy and move constructors. We suppress warnings if the copy and the move constructors are both disabled (deleted or private), because there is nothing the perfect forwarding constructor could hide in this case. We also suppress warnings for constructors like C3\-C6 that are guarded with an \fBenable_if\fP or a concept, assuming the programmer was aware of the possible hiding. .SS Background .sp For deciding whether a constructor is guarded with enable_if, we consider the types of the constructor parameters, the default values of template type parameters and the types of non\-type template parameters with a default literal value. If any part of these types is \fBstd::enable_if\fP or \fBstd::enable_if_t\fP, we assume the constructor is guarded. .SS bugprone\-implicit\-widening\-of\-multiplication\-result .sp The check diagnoses instances where a result of a multiplication is implicitly widened, and suggests (with fix\-it) to either silence the code by making widening explicit, or to perform the multiplication in a wider type, to avoid the widening afterwards. .sp This is mainly useful when operating on very large buffers. For example, consider: .INDENT 0.0 .INDENT 3.5 .sp .EX void zeroinit(char* base, unsigned width, unsigned height) { for(unsigned row = 0; row != height; ++row) { for(unsigned col = 0; col != width; ++col) { char* ptr = base + row * width + col; *ptr = 0; } } } .EE .UNINDENT .UNINDENT .sp This is fine in general, but if \fBwidth * height\fP overflows, you end up wrapping back to the beginning of \fBbase\fP instead of processing the entire requested buffer. .sp Indeed, this only matters for pretty large buffers (4GB+), but that can happen very easily for example in image processing, where for that to happen you \(dqonly\(dq need a ~269MPix image. .SS Options .INDENT 0.0 .TP .B UseCXXStaticCastsInCppSources When suggesting fix\-its for C++ code, should C++\-style \fBstatic_cast<>()\fP\(aqs be suggested, or C\-style casts. Defaults to \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B UseCXXHeadersInCppSources When suggesting to include the appropriate header in C++ code, should \fB\fP header be suggested, or \fB\fP\&. Defaults to \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B IgnoreConstantIntExpr If the multiplication operands are compile\-time constants (like literals or are \fBconstexpr\fP) and fit within the source expression type, do not emit a diagnostic or suggested fix. Only considers expressions where the source expression is a signed integer type. Defaults to \fIfalse\fP\&. .UNINDENT .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX long mul(int a, int b) { return a * b; // warning: performing an implicit widening conversion to type \(aqlong\(aq of a multiplication performed in type \(aqint\(aq } char* ptr_add(char *base, int a, int b) { return base + a * b; // warning: result of multiplication in type \(aqint\(aq is used as a pointer offset after an implicit widening conversion to type \(aqssize_t\(aq } char ptr_subscript(char *base, int a, int b) { return base[a * b]; // warning: result of multiplication in type \(aqint\(aq is used as a pointer offset after an implicit widening conversion to type \(aqssize_t\(aq } .EE .UNINDENT .UNINDENT .SS bugprone\-inaccurate\-erase .sp Checks for inaccurate use of the \fBerase()\fP method. .sp Algorithms like \fBremove()\fP do not actually remove any element from the container but return an iterator to the first redundant element at the end of the container. These redundant elements must be removed using the \fBerase()\fP method. This check warns when not all of the elements will be removed due to using an inappropriate overload. .sp For example, the following code erases only one element: .INDENT 0.0 .INDENT 3.5 .sp .EX std::vector xs; \&... xs.erase(std::remove(xs.begin(), xs.end(), 10)); .EE .UNINDENT .UNINDENT .sp Call the two\-argument overload of \fBerase()\fP to remove the subrange: .INDENT 0.0 .INDENT 3.5 .sp .EX std::vector xs; \&... xs.erase(std::remove(xs.begin(), xs.end(), 10), xs.end()); .EE .UNINDENT .UNINDENT .SS bugprone\-inc\-dec\-in\-conditions .sp Detects when a variable is both incremented/decremented and referenced inside a complex condition and suggests moving them outside to avoid ambiguity in the variable\(aqs value. .sp When a variable is modified and also used in a complex condition, it can lead to unexpected behavior. The side\-effect of changing the variable\(aqs value within the condition can make the code difficult to reason about. Additionally, the developer\(aqs intended timing for the modification of the variable may not be clear, leading to misunderstandings and errors. This can be particularly problematic when the condition involves logical operators like \fB&&\fP and \fB||\fP, where the order of evaluation can further complicate the situation. .sp Consider the following example: .INDENT 0.0 .INDENT 3.5 .sp .EX int i = 0; // ... if (i++ < 5 && i > 0) { // do something } .EE .UNINDENT .UNINDENT .sp In this example, the result of the expression may not be what the developer intended. The original intention of the developer could be to increment \fBi\fP after the entire condition is evaluated, but in reality, i will be incremented before \fBi > 0\fP is executed. This can lead to unexpected behavior and bugs in the code. To fix this issue, the developer should separate the increment operation from the condition and perform it separately. For example, they can increment \fBi\fP in a separate statement before or after the condition is evaluated. This ensures that the value of \fBi\fP is predictable and consistent throughout the code. .INDENT 0.0 .INDENT 3.5 .sp .EX int i = 0; // ... i++; if (i <= 5 && i > 0) { // do something } .EE .UNINDENT .UNINDENT .sp Another common issue occurs when multiple increments or decrements are performed on the same variable inside a complex condition. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX int i = 4; // ... if (i++ < 5 || \-\-i > 2) { // do something } .EE .UNINDENT .UNINDENT .sp There is a potential issue with this code due to the order of evaluation in C++. The \fB||\fP operator used in the condition statement guarantees that if the first operand evaluates to \fBtrue\fP, the second operand will not be evaluated. This means that if \fBi\fP were initially \fB4\fP, the first operand \fBi < 5\fP would evaluate to \fBtrue\fP and the second operand \fBi > 2\fP would not be evaluated. As a result, the decrement operation \fB\-\-i\fP would not be executed and \fBi\fP would hold value \fB5\fP, which may not be the intended behavior for the developer. .sp To avoid this potential issue, the both increment and decrement operation on \fBi\fP should be moved outside the condition statement. .SS bugprone\-incorrect\-enable\-if .sp Detects incorrect usages of \fBstd::enable_if\fP that don\(aqt name the nested \fBtype\fP type. .sp In C++11 introduced \fBstd::enable_if\fP as a convenient way to leverage SFINAE. One form of using \fBstd::enable_if\fP is to declare an unnamed template type parameter with a default type equal to \fBtypename std::enable_if::type\fP\&. If the author forgets to name the nested type \fBtype\fP, then the code will always consider the candidate template even if the condition is not met. .sp Below are some examples of code using \fBstd::enable_if\fP correctly and incorrect examples that this check flags. .INDENT 0.0 .INDENT 3.5 .sp .EX template ::type> void valid_usage() { ... } template > void valid_usage_with_trait_helpers() { ... } // The below code is not a correct application of SFINAE. Even if // T::some_trait is not true, the function will still be considered in the // set of function candidates. It can either incorrectly select the function // when it should not be a candidates, and/or lead to hard compile errors // if the body of the template does not compile if the condition is not // satisfied. template > void invalid_usage() { ... } // The tool suggests the following replacement for \(aqinvalid_usage\(aq: template ::type> void fixed_invalid_usage() { ... } .EE .UNINDENT .UNINDENT .sp C++14 introduced the trait helper \fBstd::enable_if_t\fP which reduces the likelihood of this error. C++20 introduces constraints, which generally supersede the use of \fBstd::enable_if\fP\&. See modernize\-type\-traits \%<> for another tool that will replace \fBstd::enable_if\fP with \fBstd::enable_if_t\fP, and see modernize\-use\-constraints \%<> for another tool that replaces \fBstd::enable_if\fP with C++20 constraints. Consider these newer mechanisms where possible. .SS bugprone\-incorrect\-enable\-shared\-from\-this .sp Detect classes or structs that do not publicly inherit from \fBstd::enable_shared_from_this\fP, because unintended behavior will otherwise occur when calling \fBshared_from_this\fP\&. .sp Consider the following code: .INDENT 0.0 .INDENT 3.5 .sp .EX #include // private inheritance class BadExample : std::enable_shared_from_this { // \(ga\(gashared_from_this\(ga\(ga\(ga unintended behaviour // \(galibstdc++\(ga implementation returns uninitialized \(ga\(gaweak_ptr\(ga\(ga public: BadExample* foo() { return shared_from_this().get(); } void bar() { return; } }; void using_not_public() { auto bad_example = std::make_shared(); auto* b_ex = bad_example\->foo(); b_ex\->bar(); } .EE .UNINDENT .UNINDENT .sp Using \fIlibstdc++\fP implementation, \fBshared_from_this\fP will throw \fBstd::bad_weak_ptr\fP\&. When \fBusing_not_public()\fP is called, this code will crash without exception handling. .SS bugprone\-incorrect\-roundings .sp Checks the usage of patterns known to produce incorrect rounding. Programmers often use: .INDENT 0.0 .INDENT 3.5 .sp .EX (int)(double_expression + 0.5) .EE .UNINDENT .UNINDENT .sp to round the double expression to an integer. The problem with this: .INDENT 0.0 .IP 1. 3 It is unnecessarily slow. .IP 2. 3 It is incorrect. The number 0.499999975 (smallest representable float number below 0.5) rounds to 1.0. Even worse behavior for negative numbers where both \-0.5f and \-1.4f both round to 0.0. .UNINDENT .SS bugprone\-infinite\-loop .sp Finds obvious infinite loops (loops where the condition variable is not changed at all). .sp Finding infinite loops is well\-known to be impossible (halting problem). However, it is possible to detect some obvious infinite loops, for example, if the loop condition is not changed. This check detects such loops. A loop is considered infinite if it does not have any loop exit statement (\fBbreak\fP, \fBcontinue\fP, \fBgoto\fP, \fBreturn\fP, \fBthrow\fP or a call to a function called as \fB[[noreturn]]\fP) and all of the following conditions hold for every variable in the condition: .INDENT 0.0 .IP \(bu 2 It is a local variable. .IP \(bu 2 It has no reference or pointer aliases. .IP \(bu 2 It is not a structure or class member. .UNINDENT .sp Furthermore, the condition must not contain a function call to consider the loop infinite since functions may return different values for different calls. .sp For example, the following loop is considered infinite \fIi\fP is not changed in the body: .INDENT 0.0 .INDENT 3.5 .sp .EX int i = 0, j = 0; while (i < 10) { ++j; } .EE .UNINDENT .UNINDENT .SS bugprone\-integer\-division .sp Finds cases where integer division in a floating point context is likely to cause unintended loss of precision. .sp No reports are made if divisions are part of the following expressions: .INDENT 0.0 .IP \(bu 2 operands of operators expecting integral or bool types, .IP \(bu 2 call expressions of integral or bool types, and .IP \(bu 2 explicit cast expressions to integral or bool types, .UNINDENT .sp as these are interpreted as signs of deliberateness from the programmer. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX float floatFunc(float); int intFunc(int); double d; int i = 42; // Warn, floating\-point values expected. d = 32 * 8 / (2 + i); d = 8 * floatFunc(1 + 7 / 2); d = i / (1 << 4); // OK, no integer division. d = 32 * 8.0 / (2 + i); d = 8 * floatFunc(1 + 7.0 / 2); d = (double)i / (1 << 4); // OK, there are signs of deliberateness. d = 1 << (i / 2); d = 9 + intFunc(6 * i / 32); d = (int)(i / 32) \- 8; .EE .UNINDENT .UNINDENT .SS bugprone\-invalid\-enum\-default\-initialization .sp Detects default initialization (to 0) of variables with \fBenum\fP type where the enum has no enumerator with value of 0. .sp In C++ a default initialization is performed if a variable is initialized with initializer list or in other implicit ways, and no value is specified at the initialization. In such cases the value 0 is used for the initialization. This also applies to enumerations even if it does not have an enumerator with value 0. In this way a variable with the \fBenum\fP type may contain initially an invalid value (if the program expects that it contains only the listed enumerator values). .sp The check emits a warning only if an \fBenum\fP variable is default\-initialized (contrary to not initialized) and the \fBenum\fP does not have an enumerator with value of 0. The type can be a scoped or non\-scoped \fBenum\fP\&. Unions are not handled by the check (if it contains a member of enumeration type). .sp Note that the \fBenum\fP \fBstd::errc\fP is always ignored because it is expected to be default initialized, despite not defining an enumerator with the value 0. .INDENT 0.0 .INDENT 3.5 .sp .EX enum class Enum1: int { A = 1, B }; enum class Enum0: int { A = 0, B }; void f() { Enum1 X1{}; // warn: \(aqX1\(aq is initialized to 0 Enum1 X2 = Enum1(); // warn: \(aqX2\(aq is initialized to 0 Enum1 X3; // no warning: \(aqX3\(aq is not initialized Enum0 X4{}; // no warning: type has an enumerator with value of 0 } struct S1 { Enum1 A; S(): A() {} // warn: \(aqA\(aq is initialized to 0 }; struct S2 { int A; Enum1 B; }; S2 VarS2{}; // warn: member \(aqB\(aq is initialized to 0 .EE .UNINDENT .UNINDENT .sp The check applies to initialization of arrays or structures with initialization lists in C code too. In these cases elements not specified in the list (and have enum type) are set to 0. .INDENT 0.0 .INDENT 3.5 .sp .EX enum Enum1 { Enum1_A = 1, Enum1_B }; struct Struct1 { int a; enum Enum1 b; }; enum Enum1 Array1[2] = {Enum1_A}; // warn: omitted elements are initialized to 0 enum Enum1 Array2[2][2] = {{Enum1_A}, {Enum1_A}}; // warn: last element of both nested arrays is initialized to 0 enum Enum1 Array3[2][2] = {{Enum1_A, Enum1_A}}; // warn: elements of second array are initialized to 0 struct Struct1 S1 = {1}; // warn: element \(aqb\(aq is initialized to 0 .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IgnoredEnums Semicolon\-separated list of regexes specifying enums for which this check won\(aqt be enforced. Default is \fI::std::errc\fP\&. .UNINDENT .SS bugprone\-lambda\-function\-name .sp Checks for attempts to get the name of a function from within a lambda expression. The name of a lambda is always something like \fBoperator()\fP, which is almost never what was intended. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX void FancyFunction() { [] { printf(\(dqCalled from %s\en\(dq, __func__); }(); [] { printf(\(dqNow called from %s\en\(dq, __FUNCTION__); }(); } .EE .UNINDENT .UNINDENT .sp Output: .INDENT 0.0 .INDENT 3.5 .sp .EX Called from operator() Now called from operator() .EE .UNINDENT .UNINDENT .sp Likely intended output: .INDENT 0.0 .INDENT 3.5 .sp .EX Called from FancyFunction Now called from FancyFunction .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IgnoreMacros The value \fItrue\fP specifies that attempting to get the name of a function from within a macro should not be diagnosed. The default value is \fIfalse\fP\&. .UNINDENT .SS bugprone\-macro\-parentheses .sp Finds macros that can have unexpected behavior due to missing parentheses. .sp Macros are expanded by the preprocessor as\-is. As a result, there can be unexpected behavior; operators may be evaluated in unexpected order and unary operators may become binary operators, etc. .sp When the replacement list has an expression, it is recommended to surround it with parentheses. This ensures that the macro result is evaluated completely before it is used. .sp It is also recommended to surround macro arguments in the replacement list with parentheses. This ensures that the argument value is calculated properly. .sp This check corresponds to the CERT C Coding Standard rule PRE02\-C. Macro replacement lists should be parenthesized. \% .SS bugprone\-macro\-repeated\-side\-effects .sp Checks for repeated argument with side effects in macros. .SS bugprone\-misleading\-setter\-of\-reference .sp Finds setter\-like member functions that take a pointer parameter and set a reference member of the same class with the pointed value. .sp The check detects member functions that take a single pointer parameter, and contain a single expression statement that dereferences the parameter and assigns the result to a data member with a reference type. .sp The fact that a setter function takes a pointer might cause the belief that an internal reference (if it would be a pointer) is changed instead of the pointed\-to (or referenced) value. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX class MyClass { int &InternalRef; // non\-const reference member public: MyClass(int &Value) : InternalRef(Value) {} // Warning: This setter could lead to unintended behaviour. void setRef(int *Value) { InternalRef = *Value; // This assigns to the referenced value, not changing what InternalRef references. } }; int main() { int Value1 = 42; int Value2 = 100; MyClass X(Value1); // This might look like it changes what InternalRef references to, // but it actually modifies Value1 to be 100. X.setRef(&Value2); } .EE .UNINDENT .UNINDENT .INDENT 0.0 .TP .B Possible fixes: .INDENT 7.0 .IP \(bu 2 Change the parameter type of the \(dqset\(dq function to non\-pointer type (for example, a const reference). .IP \(bu 2 Change the type of the member variable to a pointer and in the \(dqset\(dq function assign a value to the pointer (without dereference). .UNINDENT .UNINDENT .SS bugprone\-misplaced\-operator\-in\-strlen\-in\-alloc .sp Finds cases where \fB1\fP is added to the string in the argument to \fBstrlen()\fP, \fBstrnlen()\fP, \fBstrnlen_s()\fP, \fBwcslen()\fP, \fBwcsnlen()\fP, and \fBwcsnlen_s()\fP instead of the result and the value is used as an argument to a memory allocation function (\fBmalloc()\fP, \fBcalloc()\fP, \fBrealloc()\fP, \fBalloca()\fP) or the \fBnew[]\fP operator in \fIC++\fP\&. The check detects error cases even if one of these functions (except the \fBnew[]\fP operator) is called by a constant function pointer. Cases where \fB1\fP is added both to the parameter and the result of the \fBstrlen()\fP\-like function are ignored, as are cases where the whole addition is surrounded by extra parentheses. .sp \fIC\fP example code: .INDENT 0.0 .INDENT 3.5 .sp .EX void bad_malloc(char *str) { char *c = (char*) malloc(strlen(str + 1)); } .EE .UNINDENT .UNINDENT .sp The suggested fix is to add \fB1\fP to the return value of \fBstrlen()\fP and not to its argument. In the example above the fix would be .INDENT 0.0 .INDENT 3.5 .sp .EX char *c = (char*) malloc(strlen(str) + 1); .EE .UNINDENT .UNINDENT .sp \fIC++\fP example code: .INDENT 0.0 .INDENT 3.5 .sp .EX void bad_new(char *str) { char *c = new char[strlen(str + 1)]; } .EE .UNINDENT .UNINDENT .sp As in the \fIC\fP code with the \fBmalloc()\fP function, the suggested fix is to add \fB1\fP to the return value of \fBstrlen()\fP and not to its argument. In the example above the fix would be .INDENT 0.0 .INDENT 3.5 .sp .EX char *c = new char[strlen(str) + 1]; .EE .UNINDENT .UNINDENT .sp Example for silencing the diagnostic: .INDENT 0.0 .INDENT 3.5 .sp .EX void bad_malloc(char *str) { char *c = (char*) malloc(strlen((str + 1))); } .EE .UNINDENT .UNINDENT .SS bugprone\-misplaced\-pointer\-arithmetic\-in\-alloc .sp Finds cases where an integer expression is added to or subtracted from the result of a memory allocation function (\fBmalloc()\fP, \fBcalloc()\fP, \fBrealloc()\fP, \fBalloca()\fP) instead of its argument. The check detects error cases even if one of these functions is called by a constant function pointer. .sp Example code: .INDENT 0.0 .INDENT 3.5 .sp .EX void bad_malloc(int n) { char *p = (char*) malloc(n) + 10; } .EE .UNINDENT .UNINDENT .sp The suggested fix is to add the integer expression to the argument of \fBmalloc\fP and not to its result. In the example above the fix would be .INDENT 0.0 .INDENT 3.5 .sp .EX char *p = (char*) malloc(n + 10); .EE .UNINDENT .UNINDENT .SS bugprone\-misplaced\-widening\-cast .sp This check will warn when there is a cast of a calculation result to a bigger type. If the intention of the cast is to avoid loss of precision then the cast is misplaced, and there can be loss of precision. Otherwise the cast is ineffective. .sp Example code: .INDENT 0.0 .INDENT 3.5 .sp .EX long f(int x) { return (long)(x * 1000); } .EE .UNINDENT .UNINDENT .sp The result \fBx * 1000\fP is first calculated using \fBint\fP precision. If the result exceeds \fBint\fP precision there is loss of precision. Then the result is casted to \fBlong\fP\&. .sp If there is no loss of precision then the cast can be removed or you can explicitly cast to \fBint\fP instead. .sp If you want to avoid loss of precision then put the cast in a proper location, for instance: .INDENT 0.0 .INDENT 3.5 .sp .EX long f(int x) { return (long)x * 1000; } .EE .UNINDENT .UNINDENT .SS Implicit casts .sp Forgetting to place the cast at all is at least as dangerous and at least as common as misplacing it. If \fBCheckImplicitCasts\fP is enabled the check also detects these cases, for instance: .INDENT 0.0 .INDENT 3.5 .sp .EX long f(int x) { return x * 1000; } .EE .UNINDENT .UNINDENT .SS Floating point .sp Currently warnings are only written for integer conversion. No warning is written for this code: .INDENT 0.0 .INDENT 3.5 .sp .EX double f(float x) { return (double)(x * 10.0f); } .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B CheckImplicitCasts If \fItrue\fP, enables detection of implicit casts. Default is \fIfalse\fP\&. .UNINDENT .SS bugprone\-move\-forwarding\-reference .sp Warns if \fBstd::move\fP is called on a forwarding reference, for example: .INDENT 0.0 .INDENT 3.5 .sp .EX template void foo(T&& t) { bar(std::move(t)); } .EE .UNINDENT .UNINDENT .sp Forwarding references \% should typically be passed to \fBstd::forward\fP instead of \fBstd::move\fP, and this is the fix that will be suggested. .sp (A forwarding reference is an rvalue reference of a type that is a deduced function template argument.) .sp In this example, the suggested fix would be .INDENT 0.0 .INDENT 3.5 .sp .EX bar(std::forward(t)); .EE .UNINDENT .UNINDENT .SS Background .sp Code like the example above is sometimes written with the expectation that \fBT&&\fP will always end up being an rvalue reference, no matter what type is deduced for \fBT\fP, and that it is therefore not possible to pass an lvalue to \fBfoo()\fP\&. However, this is not true. Consider this example: .INDENT 0.0 .INDENT 3.5 .sp .EX std::string s = \(dqHello, world\(dq; foo(s); .EE .UNINDENT .UNINDENT .sp This code compiles and, after the call to \fBfoo()\fP, \fBs\fP is left in an indeterminate state because it has been moved from. This may be surprising to the caller of \fBfoo()\fP because no \fBstd::move\fP was used when calling \fBfoo()\fP\&. .sp The reason for this behavior lies in the special rule for template argument deduction on function templates like \fBfoo()\fP \-\- i.e. on function templates that take an rvalue reference argument of a type that is a deduced function template argument. (See section [temp.deduct.call]/3 in the C++11 standard.) .sp If \fBfoo()\fP is called on an lvalue (as in the example above), then \fBT\fP is deduced to be an lvalue reference. In the example, \fBT\fP is deduced to be \fBstd::string &\fP\&. The type of the argument \fBt\fP therefore becomes \fBstd::string& &&\fP; by the reference collapsing rules, this collapses to \fBstd::string&\fP\&. .sp This means that the \fBfoo(s)\fP call passes \fBs\fP as an lvalue reference, and \fBfoo()\fP ends up moving \fBs\fP and thereby placing it into an indeterminate state. .SS bugprone\-multi\-level\-implicit\-pointer\-conversion .sp Detects implicit conversions between pointers of different levels of indirection. .sp Conversions between pointer types of different levels of indirection can be dangerous and may lead to undefined behavior, particularly if the converted pointer is later cast to a type with a different level of indirection. For example, converting a pointer to a pointer to an \fBint\fP (\fBint**\fP) to a \fBvoid*\fP can result in the loss of information about the original level of indirection, which can cause problems when attempting to use the converted pointer. If the converted pointer is later cast to a type with a different level of indirection and dereferenced, it may lead to access violations, memory corruption, or other undefined behavior. .sp Consider the following example: .INDENT 0.0 .INDENT 3.5 .sp .EX void foo(void* ptr); int main() { int x = 42; int* ptr = &x; int** ptr_ptr = &ptr; foo(ptr_ptr); // warning will trigger here return 0; } .EE .UNINDENT .UNINDENT .sp In this example, \fBfoo()\fP is called with \fBptr_ptr\fP as its argument. However, \fBptr_ptr\fP is a \fBint**\fP pointer, while \fBfoo()\fP expects a \fBvoid*\fP pointer. This results in an implicit pointer level conversion, which could cause issues if \fBfoo()\fP dereferences the pointer assuming it\(aqs a \fBint*\fP pointer. .sp Using an explicit cast is a recommended solution to prevent issues caused by implicit pointer level conversion, as it allows the developer to explicitly state their intention and show their reasoning for the type conversion. Additionally, it is recommended that developers thoroughly check and verify the safety of the conversion before using an explicit cast. This extra level of caution can help catch potential issues early on in the development process, improving the overall reliability and maintainability of the code. .SS Options .INDENT 0.0 .TP .B EnableInC If \fItrue\fP, enables the check in C code (it is always enabled in C++ code). Default is \fItrue\fP\&. .UNINDENT .SS bugprone\-multiple\-new\-in\-one\-expression .sp Finds multiple \fBnew\fP operator calls in a single expression, where the allocated memory by the first \fBnew\fP may leak if the second allocation fails and throws exception. .sp C++ does often not specify the exact order of evaluation of the operands of an operator or arguments of a function. Therefore if a first allocation succeeds and a second fails, in an exception handler it is not possible to tell which allocation has failed and free the memory. Even if the order is fixed the result of a first \fBnew\fP may be stored in a temporary location that is not reachable at the time when a second allocation fails. It is best to avoid any expression that contains more than one \fBoperator new\fP call, if exception handling is used to check for allocation errors. .sp Different rules apply for are the short\-circuit operators \fB||\fP and \fB&&\fP and the \fB,\fP operator, where evaluation of one side must be completed before the other starts. Expressions of a list\-initialization (initialization or construction using \fB{\fP and \fB}\fP characters) are evaluated in fixed order. Similarly, condition of a \fB?\fP operator is evaluated before the branches are evaluated. .sp The check reports warning if two \fBnew\fP calls appear in one expression at different sides of an operator, or if \fBnew\fP calls appear in different arguments of a function call (that can be an object construction with \fB()\fP syntax). These \fBnew\fP calls can be nested at any level. For any warning to be emitted the \fBnew\fP calls should be in a code block where exception handling is used with catch for \fBstd::bad_alloc\fP or \fBstd::exception\fP\&. At \fB||\fP, \fB&&\fP, \fB,\fP, \fB?\fP (condition and one branch) operators no warning is emitted. No warning is emitted if both of the memory allocations are not assigned to a variable or not passed directly to a function. The reason is that in this case the memory may be intentionally not freed or the allocated objects can be self\-destructing objects. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX struct A { int Var; }; struct B { B(); B(A *); int Var; }; struct C { int *X1; int *X2; }; void f(A *, B *); int f1(A *); int f1(B *); bool f2(A *); void foo() { A *PtrA; B *PtrB; try { // Allocation of \(aqB\(aq/\(aqA\(aq may fail after memory for \(aqA\(aq/\(aqB\(aq was allocated. f(new A, new B); // warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception; order of these allocations is undefined // List (aggregate) initialization is used. C C1{new int, new int}; // no warning // Allocation of \(aqB\(aq/\(aqA\(aq may fail after memory for \(aqA\(aq/\(aqB\(aq was allocated but not yet passed to function \(aqf1\(aq. int X = f1(new A) + f1(new B); // warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception; order of these allocations is undefined // Allocation of \(aqB\(aq may fail after memory for \(aqA\(aq was allocated. // From C++17 on memory for \(aqB\(aq is allocated first but still may leak if allocation of \(aqA\(aq fails. PtrB = new B(new A); // warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception // \(aqnew A\(aq and \(aqnew B\(aq may be performed in any order. // \(aqnew B\(aq/\(aqnew A\(aq may fail after memory for \(aqA\(aq/\(aqB\(aq was allocated but not assigned to \(aqPtrA\(aq/\(aqPtrB\(aq. (PtrA = new A)\->Var = (PtrB = new B)\->Var; // warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception; order of these allocations is undefined // Evaluation of \(aqf2(new A)\(aq must be finished before \(aqf1(new B)\(aq starts. // If \(aqnew B\(aq fails the allocated memory for \(aqA\(aq is supposedly handled correctly because function \(aqf2\(aq could take the ownership. bool Z = f2(new A) || f1(new B); // no warning X = (f2(new A) ? f1(new A) : f1(new B)); // no warning // No warning if the result of both allocations is not passed to a function // or stored in a variable. (new A)\->Var = (new B)\->Var; // no warning // No warning if at least one non\-throwing allocation is used. f(new(std::nothrow) A, new B); // no warning } catch(std::bad_alloc) { } // No warning if the allocation is outside a try block (or no catch handler exists for std::bad_alloc). // (The fact if exceptions can escape from \(aqfoo\(aq is not taken into account.) f(new A, new B); // no warning } .EE .UNINDENT .UNINDENT .SS bugprone\-multiple\-statement\-macro .sp Detect multiple statement macros that are used in unbraced conditionals. Only the first statement of the macro will be inside the conditional and the other ones will be executed unconditionally. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX #define INCREMENT_TWO(x, y) (x)++; (y)++ if (do_increment) INCREMENT_TWO(a, b); // (b)++ will be executed unconditionally. .EE .UNINDENT .UNINDENT .SS bugprone\-narrowing\-conversions .sp \fIcppcoreguidelines\-narrowing\-conversions\fP redirects here as an alias for this check. .sp Checks for silent narrowing conversions, e.g: \fBint i = 0; i += 0.1;\fP\&. While the issue is obvious in this former example, it might not be so in the following: \fBvoid MyClass::f(double d) { int_member_ += d; }\fP\&. .INDENT 0.0 .TP .B We flag narrowing conversions from: .INDENT 7.0 .IP \(bu 2 an integer to a narrower integer (e.g. \fBchar\fP to \fBunsigned char\fP) if WarnOnIntegerNarrowingConversion Option is set, .IP \(bu 2 an integer to a narrower floating\-point (e.g. \fBuint64_t\fP to \fBfloat\fP) if WarnOnIntegerToFloatingPointNarrowingConversion Option is set, .IP \(bu 2 a floating\-point to an integer (e.g. \fBdouble\fP to \fBint\fP), .IP \(bu 2 a floating\-point to a narrower floating\-point (e.g. \fBdouble\fP to \fBfloat\fP) if WarnOnFloatingPointNarrowingConversion Option is set. .UNINDENT .TP .B This check will flag: .INDENT 7.0 .IP \(bu 2 All narrowing conversions that are not marked by an explicit cast (c\-style or \fBstatic_cast\fP). For example: \fBint i = 0; i += 0.1;\fP, \fBvoid f(int); f(0.1);\fP, .IP \(bu 2 All applications of binary operators with a narrowing conversions. For example: \fBint i; i+= 0.1;\fP\&. .UNINDENT .UNINDENT .sp Arithmetic with smaller integer types than \fBint\fP trigger implicit conversions, as explained under \(dqIntegral Promotion\(dq on cppreference.com \%\&. This check diagnoses more instances of narrowing than the compiler warning \fI\-Wconversion\fP does. The example below demonstrates this behavior. .INDENT 0.0 .INDENT 3.5 .sp .EX // The following function definition demonstrates usage of arithmetic with // integer types smaller than \(gaint\(ga and how the narrowing conversion happens // implicitly. void computation(short argument1, short argument2) { // Arithmetic written by humans: short result = argument1 + argument2; // Arithmetic actually performed by C++: short result = static_cast(static_cast(argument1) + static_cast(argument2)); } void recommended_resolution(short argument1, short argument2) { short result = argument1 + argument2; // ^ warning: narrowing conversion from \(aqint\(aq to signed type \(aqshort\(aq is implementation\-defined // The cppcoreguidelines recommend to resolve this issue by using the GSL // in one of two ways. Either by a cast that throws if a loss of precision // would occur. short result = gsl::narrow(argument1 + argument2); // Or it can be resolved without checking the result risking invalid results. short result = gsl::narrow_cast(argument1 + argument2); // A classical \(gastatic_cast\(ga will silence the warning as well if the GSL // is not available. short result = static_cast(argument1 + argument2); } .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B WarnOnIntegerNarrowingConversion When \fItrue\fP, the check will warn on narrowing integer conversion (e.g. \fBint\fP to \fBsize_t\fP). \fItrue\fP by default. .UNINDENT .INDENT 0.0 .TP .B WarnOnIntegerToFloatingPointNarrowingConversion When \fItrue\fP, the check will warn on narrowing integer to floating\-point conversion (e.g. \fBsize_t\fP to \fBdouble\fP). \fItrue\fP by default. .UNINDENT .INDENT 0.0 .TP .B WarnOnFloatingPointNarrowingConversion When \fItrue\fP, the check will warn on narrowing floating point conversion (e.g. \fBdouble\fP to \fBfloat\fP). \fItrue\fP by default. .UNINDENT .INDENT 0.0 .TP .B WarnWithinTemplateInstantiation When \fItrue\fP, the check will warn on narrowing conversions within template instantiations. \fIfalse\fP by default. .UNINDENT .INDENT 0.0 .TP .B WarnOnEquivalentBitWidth When \fItrue\fP, the check will warn on narrowing conversions that arise from casting between types of equivalent bit width. (e.g. \fIint n = uint(0);\fP or \fIlong long n = double(0);\fP) \fItrue\fP by default. .UNINDENT .INDENT 0.0 .TP .B IgnoreConversionFromTypes Narrowing conversions from any type in this semicolon\-separated list will be ignored. This may be useful to weed out commonly occurring, but less commonly problematic assignments such as \fIint n = std::vector().size();\fP or \fIint n = std::difference(it1, it2);\fP\&. The default list is empty, but one suggested list for a legacy codebase would be \fIsize_t;ptrdiff_t;size_type;difference_type\fP\&. .UNINDENT .INDENT 0.0 .TP .B PedanticMode When \fItrue\fP, the check will warn on assigning a floating point constant to an integer value even if the floating point value is exactly representable in the destination type (e.g. \fBint i = 1.0;\fP). \fIfalse\fP by default. .UNINDENT .SS FAQ .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 What does \(dqnarrowing conversion from \(aqint\(aq to \(aqfloat\(aq\(dq mean? .UNINDENT .UNINDENT .UNINDENT .sp An IEEE754 Floating Point number can represent all integer values in the range [\-2^PrecisionBits, 2^PrecisionBits] where PrecisionBits is the number of bits in the mantissa. .sp For \fBfloat\fP this would be [\-2^23, 2^23], where \fBint\fP can represent values in the range [\-2^31, 2^31\-1]. .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 What does \(dqimplementation\-defined\(dq mean? .UNINDENT .UNINDENT .UNINDENT .sp You may have encountered messages like \(dqnarrowing conversion from \(aqunsigned int\(aq to signed type \(aqint\(aq is implementation\-defined\(dq. The C/C++ standard does not mandate two\(aqs complement for signed integers, and so the compiler is free to define what the semantics are for converting an unsigned integer to signed integer. Clang\(aqs implementation uses the two\(aqs complement format. .SS bugprone\-no\-escape .sp Finds pointers with the \fBnoescape\fP attribute that are captured by an asynchronously\-executed block. The block arguments in \fBdispatch_async()\fP and \fBdispatch_after()\fP are guaranteed to escape, so it is an error if a pointer with the \fBnoescape\fP attribute is captured by one of these blocks. .sp The following is an example of an invalid use of the \fBnoescape\fP attribute. .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .INDENT 3.5 .sp .EX void foo(__attribute__((noescape)) int *p) { dispatch_async(queue, ^{ *p = 123; }); }); .EE .UNINDENT .UNINDENT .UNINDENT .UNINDENT .SS bugprone\-non\-zero\-enum\-to\-bool\-conversion .sp Detect implicit and explicit casts of \fBenum\fP type into \fBbool\fP where \fBenum\fP type doesn\(aqt have a zero\-value enumerator. If the \fBenum\fP is used only to hold values equal to its enumerators, then conversion to \fBbool\fP will always result in \fBtrue\fP value. This can lead to unnecessary code that reduces readability and maintainability and can result in bugs. .sp May produce false positives if the \fBenum\fP is used to store other values (used as a bit\-mask or zero\-initialized on purpose). To deal with them, \fB// NOLINT\fP or casting first to the underlying type before casting to \fBbool\fP can be used. .sp It is important to note that this check will not generate warnings if the definition of the enumeration type is not available. Additionally, C++11 enumeration classes are supported by this check. .sp Overall, this check serves to improve code quality and readability by identifying and flagging instances where implicit or explicit casts from enumeration types to boolean could cause potential issues. .SS Example .INDENT 0.0 .INDENT 3.5 .sp .EX enum EStatus { OK = 1, NOT_OK, UNKNOWN }; void process(EStatus status) { if (!status) { // this true\-branch won\(aqt be executed return; } // proceed with \(dqvalid data\(dq } .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B EnumIgnoreList Option is used to ignore certain enum types when checking for implicit/explicit casts to bool. It accepts a semicolon\-separated list of (fully qualified) enum type names or regular expressions that match the enum type names. The default value is an empty string, which means no enums will be ignored. .UNINDENT .SS bugprone\-nondeterministic\-pointer\-iteration\-order .sp Finds nondeterministic usages of pointers in unordered containers. .sp One canonical example is iteration across a container of pointers. .INDENT 0.0 .INDENT 3.5 .sp .EX { int a = 1, b = 2; std::unordered_set UnorderedPtrSet = {&a, &b}; for (auto i : UnorderedPtrSet) f(i); } .EE .UNINDENT .UNINDENT .sp Another such example is sorting a container of pointers. .INDENT 0.0 .INDENT 3.5 .sp .EX { int a = 1, b = 2; std::vector VectorOfPtr = {&a, &b}; std::sort(VectorOfPtr.begin(), VectorOfPtr.end()); } .EE .UNINDENT .UNINDENT .sp Iteration of a containers of pointers may present the order of different pointers differently across different runs of a program. In some cases this may be acceptable behavior, in others this may be unexpected behavior. This check is advisory for this reason. .sp This check only detects range\-based for loops over unordered sets and maps. It also detects calls sorting\-like algorithms on containers holding pointers. Other similar usages will not be found and are false negatives. .SS Limitations .INDENT 0.0 .IP \(bu 2 This check currently does not check if a nondeterministic iteration order is likely to be a mistake, and instead marks all such iterations as bugprone. .IP \(bu 2 std::reference_wrapper is not considered yet. .IP \(bu 2 Only for loops are considered, other iterators can be included in improvements. .UNINDENT .SS bugprone\-not\-null\-terminated\-result .sp Finds function calls where it is possible to cause a not null\-terminated result. Usually the proper length of a string is \fBstrlen(src) + 1\fP or equal length of this expression, because the null terminator needs an extra space. Without the null terminator it can result in undefined behavior when the string is read. .sp The following and their respective \fBwchar_t\fP based functions are checked: .sp \fBmemcpy\fP, \fBmemcpy_s\fP, \fBmemchr\fP, \fBmemmove\fP, \fBmemmove_s\fP, \fBstrerror_s\fP, \fBstrncmp\fP, \fBstrxfrm\fP .sp The following is a real\-world example where the programmer forgot to increase the passed third argument, which is \fBsize_t length\fP\&. That is why the length of the allocated memory is not enough to hold the null terminator. .INDENT 0.0 .INDENT 3.5 .sp .EX static char *stringCpy(const std::string &str) { char *result = reinterpret_cast(malloc(str.size())); memcpy(result, str.data(), str.size()); return result; } .EE .UNINDENT .UNINDENT .sp In addition to issuing warnings, fix\-it rewrites all the necessary code. It also tries to adjust the capacity of the destination array: .INDENT 0.0 .INDENT 3.5 .sp .EX static char *stringCpy(const std::string &str) { char *result = reinterpret_cast(malloc(str.size() + 1)); strcpy(result, str.data()); return result; } .EE .UNINDENT .UNINDENT .sp Note: It cannot guarantee to rewrite every of the path\-sensitive memory allocations. .SS Transformation rules of \(aqmemcpy()\(aq .sp It is possible to rewrite the \fBmemcpy()\fP and \fBmemcpy_s()\fP calls as the following four functions: \fBstrcpy()\fP, \fBstrncpy()\fP, \fBstrcpy_s()\fP, \fBstrncpy_s()\fP, where the latter two are the safer versions of the former two. It rewrites the \fBwchar_t\fP based memory handler functions respectively. .SS Rewrite based on the destination array .INDENT 0.0 .IP \(bu 2 If copy to the destination array cannot overflow [1] the new function should be the older copy function (ending with \fBcpy\fP), because it is more efficient than the safe version. .IP \(bu 2 If copy to the destination array can overflow [1] and \fBWantToUseSafeFunctions\fP is set to \fItrue\fP and it is possible to obtain the capacity of the destination array then the new function could be the safe version (ending with \fBcpy_s\fP). .IP \(bu 2 If the new function is could be safe version and C++ files are analyzed and the destination array is plain \fBchar\fP/\fBwchar_t\fP without \fBun/signed\fP then the length of the destination array can be omitted. .IP \(bu 2 If the new function is could be safe version and the destination array is \fBun/signed\fP it needs to be casted to plain \fBchar *\fP/\fBwchar_t *\fP\&. .UNINDENT .INDENT 0.0 .TP .B [1] It is possible to overflow: .INDENT 7.0 .IP \(bu 2 If the capacity of the destination array is unknown. .IP \(bu 2 If the given length is equal to the destination array\(aqs capacity. .UNINDENT .UNINDENT .SS Rewrite based on the length of the source string .INDENT 0.0 .IP \(bu 2 If the given length is \fBstrlen(source)\fP or equal length of this expression then the new function should be the older copy function (ending with \fBcpy\fP), as it is more efficient than the safe version (ending with \fBcpy_s\fP). .IP \(bu 2 Otherwise we assume that the programmer wanted to copy \(aqN\(aq characters, so the new function is \fBncpy\fP\-like which copies \(aqN\(aq characters. .UNINDENT .SS Transformations with \(aqstrlen()\(aq or equal length of this expression .sp It transforms the \fBwchar_t\fP based memory and string handler functions respectively (where only \fBstrerror_s\fP does not have \fBwchar_t\fP based alias). .SS Memory handler functions .sp \fBmemcpy\fP Please visit the Transformation rules of \(aqmemcpy()\(aq section. .sp \fBmemchr\fP Usually there is a C\-style cast and it is needed to be removed, because the new function \fBstrchr\fP\(aqs return type is correct. The given length is going to be removed. .sp \fBmemmove\fP If safe functions are available the new function is \fBmemmove_s\fP, which has a new second argument which is the length of the destination array, it is adjusted, and the length of the source string is incremented by one. If safe functions are not available the given length is incremented by one. .sp \fBmemmove_s\fP The given length is incremented by one. .SS String handler functions .sp \fBstrerror_s\fP The given length is incremented by one. .sp \fBstrncmp\fP If the third argument is the first or the second argument\(aqs \fBlength + 1\fP it has to be truncated without the \fB+ 1\fP operation. .sp \fBstrxfrm\fP The given length is incremented by one. .SS Options .INDENT 0.0 .TP .B WantToUseSafeFunctions The value \fItrue\fP specifies that the target environment is considered to implement \(aq_s\(aq suffixed memory and string handler functions which are safer than older versions (e.g. \(aqmemcpy_s()\(aq). The default value is \fItrue\fP\&. .UNINDENT .SS bugprone\-optional\-value\-conversion .sp Detects potentially unintentional and redundant conversions where a value is extracted from an optional\-like type and then used to create a new instance of the same optional\-like type. .sp These conversions might be the result of developer oversight, leftovers from code refactoring, or other situations that could lead to unintended exceptions or cases where the resulting optional is always initialized, which might be unexpected behavior. .sp To illustrate, consider the following problematic code snippet: .INDENT 0.0 .INDENT 3.5 .sp .EX #include void print(std::optional); int main() { std::optional opt; // ... // Unintentional conversion from std::optional to int and back to // std::optional: print(opt.value()); // ... } .EE .UNINDENT .UNINDENT .sp A better approach would be to directly pass \fBopt\fP to the \fBprint\fP function without extracting its value: .INDENT 0.0 .INDENT 3.5 .sp .EX #include void print(std::optional); int main() { std::optional opt; // ... // Proposed code: Directly pass the std::optional to the print // function. print(opt); // ... } .EE .UNINDENT .UNINDENT .sp By passing \fBopt\fP directly to the print function, unnecessary conversions are avoided, and potential unintended behavior or exceptions are minimized. .sp Value extraction using \fBoperator *\fP is matched by default. The support for non\-standard optional types such as \fBboost::optional\fP or \fBabsl::optional\fP may be limited. .SS Options: .INDENT 0.0 .TP .B OptionalTypes Semicolon\-separated list of (fully qualified) optional type names or regular expressions that match the optional types. Default value is \fI::std::optional;::absl::optional;::boost::optional\fP\&. .UNINDENT .INDENT 0.0 .TP .B ValueMethods Semicolon\-separated list of (fully qualified) method names or regular expressions that match the methods. Default value is \fI::value$;::get$\fP\&. .UNINDENT .SS bugprone\-parent\-virtual\-call .sp Detects and fixes calls to grand\-...parent virtual methods instead of calls to overridden parent\(aqs virtual methods. .INDENT 0.0 .INDENT 3.5 .sp .EX struct A { int virtual foo() {...} }; struct B: public A { int foo() override {...} }; struct C: public B { int foo() override { A::foo(); } // ^^^^^^^^ // warning: qualified name A::foo refers to a member overridden in subclass; did you mean \(aqB\(aq? [bugprone\-parent\-virtual\-call] }; .EE .UNINDENT .UNINDENT .SS bugprone\-pointer\-arithmetic\-on\-polymorphic\-object .sp Finds pointer arithmetic performed on classes that contain a virtual function. .sp Pointer arithmetic on polymorphic objects where the pointer\(aqs static type is different from its dynamic type is undefined behavior, as the two types could have different sizes, and thus the vtable pointer could point to an invalid address. .sp Finding pointers where the static type contains a virtual member function is a good heuristic, as the pointer is likely to point to a different, derived object. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX struct Base { virtual ~Base(); int i; }; struct Derived : public Base {}; void foo(Base* b) { b += 1; // warning: pointer arithmetic on class that declares a virtual function can // result in undefined behavior if the dynamic type differs from the // pointer type } int bar(const Derived d[]) { return d[1].i; // warning due to pointer arithmetic on polymorphic object } // Making Derived final suppresses the warning struct FinalDerived final : public Base {}; int baz(const FinalDerived d[]) { return d[1].i; // no warning as FinalDerived is final } .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IgnoreInheritedVirtualFunctions When \fItrue\fP, objects that only inherit a virtual function are not checked. Classes that do not declare a new virtual function are excluded by default, as they make up the majority of false positives. Default: \fIfalse\fP\&. .INDENT 7.0 .INDENT 3.5 .sp .EX void bar(Base b[], Derived d[]) { b += 1; // warning, as Base declares a virtual destructor d += 1; // warning only if IgnoreVirtualDeclarationsOnly is set to false } .EE .UNINDENT .UNINDENT .UNINDENT .SS References .sp This check corresponds to the SEI Cert rule CTR56\-CPP. Do not use pointer arithmetic on polymorphic objects \%\&. .SS bugprone\-posix\-return .sp Checks if any calls to \fBpthread_*\fP or \fBposix_*\fP functions (except \fBposix_openpt\fP) expect negative return values. These functions return either \fB0\fP on success or an \fBerrno\fP on failure, which is positive only. .sp Example buggy usage looks like: .INDENT 0.0 .INDENT 3.5 .sp .EX if (posix_fadvise(...) < 0) { .EE .UNINDENT .UNINDENT .sp This will never happen as the return value is always non\-negative. A simple fix could be: .INDENT 0.0 .INDENT 3.5 .sp .EX if (posix_fadvise(...) > 0) { .EE .UNINDENT .UNINDENT .SS bugprone\-random\-generator\-seed .sp Flags all pseudo\-random number engines, engine adaptor instantiations and \fBsrand()\fP when initialized or seeded with default argument, constant expression or any user\-configurable type. Pseudo\-random number engines seeded with a predictable value may cause vulnerabilities e.g. in security protocols. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX void foo() { std::mt19937 engine1; // Diagnose, always generate the same sequence std::mt19937 engine2(1); // Diagnose engine1.seed(); // Diagnose engine2.seed(1); // Diagnose std::time_t t; engine1.seed(std::time(&t)); // Diagnose, system time might be controlled by user int x = atoi(argv[1]); std::mt19937 engine3(x); // Will not warn } .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B DisallowedSeedTypes A comma\-separated list of the type names which are disallowed. Default value is \fItime_t,std::time_t\fP\&. .UNINDENT .SS References .sp This check corresponds to the CERT C++ Coding Standard rules MSC51\-CPP. Ensure your random number generator is properly seeded \% and MSC32\-C. Properly seed pseudorandom number generators \%\&. .SS bugprone\-raw\-memory\-call\-on\-non\-trivial\-type .sp Flags use of the C standard library functions \fBmemset\fP, \fBmemcpy\fP and \fBmemcmp\fP and similar derivatives on non\-trivial types. .sp The check will detect the following functions: \fBmemset\fP, \fBstd::memset\fP, \fBstd::memcpy\fP, \fBmemcpy\fP, \fBstd::memmove\fP, \fBmemmove\fP, \fBstd::strcpy\fP, \fBstrcpy\fP, \fBmemccpy\fP, \fBstpncpy\fP, \fBstrncpy\fP, \fBstd::memcmp\fP, \fBmemcmp\fP, \fBstd::strcmp\fP, \fBstrcmp\fP, \fBstrncmp\fP\&. .SS Options .INDENT 0.0 .TP .B MemSetNames Specify extra functions to flag that act similarly to \fBmemset\fP\&. Specify names in a semicolon\-delimited list. Default is an empty string. .UNINDENT .INDENT 0.0 .TP .B MemCpyNames Specify extra functions to flag that act similarly to \fBmemcpy\fP\&. Specify names in a semicolon\-delimited list. Default is an empty string. .UNINDENT .INDENT 0.0 .TP .B MemCmpNames Specify extra functions to flag that act similarly to \fBmemcmp\fP\&. Specify names in a semicolon\-delimited list. Default is an empty string. .UNINDENT .sp This check corresponds to the CERT C++ Coding Standard rule OOP57\-CPP. Prefer special member functions and overloaded operators to C Standard Library functions \%\&. .SS bugprone\-redundant\-branch\-condition .sp Finds condition variables in nested \fBif\fP statements that were also checked in the outer \fBif\fP statement and were not changed. .sp Simple example: .INDENT 0.0 .INDENT 3.5 .sp .EX bool onFire = isBurning(); if (onFire) { if (onFire) scream(); } .EE .UNINDENT .UNINDENT .sp Here \fIonFire\fP is checked both in the outer \fBif\fP and the inner \fBif\fP statement without a possible change between the two checks. The check warns for this code and suggests removal of the second checking of variable \fIonFire\fP\&. .sp The checker also detects redundant condition checks if the condition variable is an operand of a logical \(dqand\(dq (\fB&&\fP) or a logical \(dqor\(dq (\fB||\fP) operator: .INDENT 0.0 .INDENT 3.5 .sp .EX bool onFire = isBurning(); if (onFire) { if (onFire && peopleInTheBuilding > 0) scream(); } .EE .UNINDENT .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .EX bool onFire = isBurning(); if (onFire) { if (onFire || isCollapsing()) scream(); } .EE .UNINDENT .UNINDENT .sp In the first case (logical \(dqand\(dq) the suggested fix is to remove the redundant condition variable and keep the other side of the \fB&&\fP\&. In the second case (logical \(dqor\(dq) the whole \fBif\fP is removed similarly to the simple case on the top. .sp The condition of the outer \fBif\fP statement may also be a logical \(dqand\(dq (\fB&&\fP) expression: .INDENT 0.0 .INDENT 3.5 .sp .EX bool onFire = isBurning(); if (onFire && fireFighters < 10) { if (someOtherCondition()) { if (onFire) scream(); } } .EE .UNINDENT .UNINDENT .sp The error is also detected if both the outer statement is a logical \(dqand\(dq (\fB&&\fP) and the inner statement is a logical \(dqand\(dq (\fB&&\fP) or \(dqor\(dq (\fB||\fP). The inner \fBif\fP statement does not have to be a direct descendant of the outer one. .sp No error is detected if the condition variable may have been changed between the two checks: .INDENT 0.0 .INDENT 3.5 .sp .EX bool onFire = isBurning(); if (onFire) { tryToExtinguish(onFire); if (onFire && peopleInTheBuilding > 0) scream(); } .EE .UNINDENT .UNINDENT .sp Every possible change is considered, thus if the condition variable is not a local variable of the function, it is a volatile or it has an alias (pointer or reference) then no warning is issued. .SS Limitations .sp The \fBelse\fP branch is not checked currently for negated condition variable: .INDENT 0.0 .INDENT 3.5 .sp .EX bool onFire = isBurning(); if (onFire) { scream(); } else { if (!onFire) { continueWork(); } } .EE .UNINDENT .UNINDENT .sp The checker currently only detects redundant checking of single condition variables. More complex expressions are not checked: .INDENT 0.0 .INDENT 3.5 .sp .EX if (peopleInTheBuilding == 1) { if (peopleInTheBuilding == 1) { doSomething(); } } .EE .UNINDENT .UNINDENT .SS bugprone\-reserved\-identifier .sp \fIcert\-dcl37\-c\fP and \fIcert\-dcl51\-cpp\fP redirect here as an alias for this check. .sp Checks for usages of identifiers reserved for use by the implementation. .sp The C and C++ standards both reserve the following names for such use: .INDENT 0.0 .IP \(bu 2 identifiers that begin with an underscore followed by an uppercase letter; .IP \(bu 2 identifiers in the global namespace that begin with an underscore. .UNINDENT .sp The C standard additionally reserves names beginning with a double underscore, while the C++ standard strengthens this to reserve names with a double underscore occurring anywhere. .sp Violating the naming rules above results in undefined behavior. .INDENT 0.0 .INDENT 3.5 .sp .EX namespace NS { void __f(); // name is not allowed in user code using _Int = int; // same with this #define cool__macro // also this } int _g(); // disallowed in global namespace only .EE .UNINDENT .UNINDENT .sp The check can also be inverted, i.e. it can be configured to flag any identifier that is \fInot\fP a reserved identifier. This mode is for use by e.g. standard library implementors, to ensure they don\(aqt infringe on the user namespace. .sp This check does not (yet) check for other reserved names, e.g. macro names identical to language keywords, and names specifically reserved by language standards, e.g. C++ \(aqzombie names\(aq and C future library directions. .sp This check corresponds to CERT C Coding Standard rule DCL37\-C. Do not declare or define a reserved identifier \% as well as its C++ counterpart, DCL51\-CPP. Do not declare or define a reserved identifier \%\&. .SS Options .INDENT 0.0 .TP .B Invert If \fItrue\fP, inverts the check, i.e. flags names that are not reserved. Default is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B AllowedIdentifiers Semicolon\-separated list of regular expressions that the check ignores. Default is an empty list. .UNINDENT .SS bugprone\-return\-const\-ref\-from\-parameter .sp Detects return statements that return a constant reference parameter as constant reference. This may cause use\-after\-free errors if the caller uses xvalues as arguments. .sp In C++, constant reference parameters can accept xvalues which will be destructed after the call. When the function returns such a parameter also as constant reference, then the returned reference can be used after the object it refers to has been destroyed. .SS Example .INDENT 0.0 .INDENT 3.5 .sp .EX struct S { int v; S(int); ~S(); }; const S &fn(const S &a) { return a; } const S& s = fn(S{1}); s.v; // use after free .EE .UNINDENT .UNINDENT .sp This issue can be resolved by declaring an overload of the problematic function where the \fBconst &\fP parameter is instead declared as \fB&&\fP\&. The developer has to ensure that the implementation of that function does not produce a use\-after\-free, the exact error that this check is warning against. Marking such an \fB&&\fP overload as \fBdeleted\fP, will silence the warning as well. In the case of different \fBconst &\fP parameters being returned depending on the control flow of the function, an overload where all problematic \fBconst &\fP parameters have been declared as \fB&&\fP will resolve the issue. .sp This issue can also be resolved by adding \fB[[clang::lifetimebound]]\fP\&. Clang enable \fB\-Wdangling\fP warning by default which can detect mis\-uses of the annotated function. See lifetimebound attribute \% for details. .INDENT 0.0 .INDENT 3.5 .sp .EX const int &f(const int &a [[clang::lifetimebound]]) { return a; } // no warning const int &v = f(1); // warning: temporary bound to local reference \(aqv\(aq will be destroyed at the end of the full\-expression [\-Wdangling] .EE .UNINDENT .UNINDENT .SS bugprone\-shared\-ptr\-array\-mismatch .sp Finds initializations of C++ shared pointers to non\-array type that are initialized with an array. .sp If a shared pointer \fBstd::shared_ptr\fP is initialized with a new\-expression \fBnew T[]\fP the memory is not deallocated correctly. The pointer uses plain \fBdelete\fP in this case to deallocate the target memory. Instead a \fBdelete[]\fP call is needed. A \fBstd::shared_ptr\fP calls the correct delete operator. .sp The check offers replacement of \fBshared_ptr\fP to \fBshared_ptr\fP if it is used at a single variable declaration (one variable in one statement). .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX std::shared_ptr x(new Foo[10]); // \-> std::shared_ptr x(new Foo[10]); // ^ warning: shared pointer to non\-array is initialized with array [bugprone\-shared\-ptr\-array\-mismatch] std::shared_ptr x1(new Foo), x2(new Foo[10]); // no replacement // ^ warning: shared pointer to non\-array is initialized with array [bugprone\-shared\-ptr\-array\-mismatch] std::shared_ptr x3(new Foo[10], [](const Foo *ptr) { delete[] ptr; }); // no warning struct S { std::shared_ptr x(new Foo[10]); // no replacement in this case // ^ warning: shared pointer to non\-array is initialized with array [bugprone\-shared\-ptr\-array\-mismatch] }; .EE .UNINDENT .UNINDENT .sp This check partially covers the CERT C++ Coding Standard rule MEM51\-CPP. Properly deallocate dynamically allocated resources \% However, only the \fBstd::shared_ptr\fP case is detected by this check. .SS bugprone\-signal\-handler .sp Finds specific constructs in signal handler functions that can cause undefined behavior. The rules for what is allowed differ between C++ language versions. .sp Checked signal handler rules for C: .INDENT 0.0 .IP \(bu 2 Calls to non\-asynchronous\-safe functions are not allowed. .UNINDENT .sp Checked signal handler rules for up to and including C++14: .INDENT 0.0 .IP \(bu 2 Calls to non\-asynchronous\-safe functions are not allowed. .IP \(bu 2 C++\-specific code constructs are not allowed in signal handlers. In other words, only the common subset of C and C++ is allowed to be used. .IP \(bu 2 Calls to functions with non\-C linkage are not allowed (including the signal handler itself). .UNINDENT .sp The check is disabled on C++17 and later. .sp Asynchronous\-safety is determined by comparing the function\(aqs name against a set of known functions. In addition, the function must come from a system header include and in a global namespace. The (possible) arguments passed to the function are not checked. Any function that cannot be determined to be asynchronous\-safe is assumed to be non\-asynchronous\-safe by the check, including user functions for which only the declaration is visible. Calls to user\-defined functions with visible definitions are checked recursively. .sp This check implements the CERT C Coding Standard rule SIG30\-C. Call only asynchronous\-safe functions within signal handlers \% and the rule MSC54\-CPP. A signal handler must be a plain old function \%\&. It has the alias names \fBcert\-sig30\-c\fP and \fBcert\-msc54\-cpp\fP\&. .SS Options .INDENT 0.0 .TP .B AsyncSafeFunctionSet Selects which set of functions is considered as asynchronous\-safe (and therefore allowed in signal handlers). It can be set to the following values: .INDENT 7.0 .IP \(bu 2 .INDENT 2.0 .TP .B \fIminimal\fP Selects a minimal set that is defined in the CERT SIG30\-C rule. and includes functions \fBabort()\fP, \fB_Exit()\fP, \fBquick_exit()\fP and \fBsignal()\fP\&. .UNINDENT .IP \(bu 2 .INDENT 2.0 .TP .B \fIPOSIX\fP Selects a larger set of functions that is listed in POSIX.1\-2017 (see this link \% for more information). The following functions are included: \fB_Exit\fP, \fB_exit\fP, \fBabort\fP, \fBaccept\fP, \fBaccess\fP, \fBaio_error\fP, \fBaio_return\fP, \fBaio_suspend\fP, \fBalarm\fP, \fBbind\fP, \fBcfgetispeed\fP, \fBcfgetospeed\fP, \fBcfsetispeed\fP, \fBcfsetospeed\fP, \fBchdir\fP, \fBchmod\fP, \fBchown\fP, \fBclock_gettime\fP, \fBclose\fP, \fBconnect\fP, \fBcreat\fP, \fBdup\fP, \fBdup2\fP, \fBexecl\fP, \fBexecle\fP, \fBexecv\fP, \fBexecve\fP, \fBfaccessat\fP, \fBfchdir\fP, \fBfchmod\fP, \fBfchmodat\fP, \fBfchown\fP, \fBfchownat\fP, \fBfcntl\fP, \fBfdatasync\fP, \fBfexecve\fP, \fBffs\fP, \fBfork\fP, \fBfstat\fP, \fBfstatat\fP, \fBfsync\fP, \fBftruncate\fP, \fBfutimens\fP, \fBgetegid\fP, \fBgeteuid\fP, \fBgetgid\fP, \fBgetgroups\fP, \fBgetpeername\fP, \fBgetpgrp\fP, \fBgetpid\fP, \fBgetppid\fP, \fBgetsockname\fP, \fBgetsockopt\fP, \fBgetuid\fP, \fBhtonl\fP, \fBhtons\fP, \fBkill\fP, \fBlink\fP, \fBlinkat\fP, \fBlisten\fP, \fBlongjmp\fP, \fBlseek\fP, \fBlstat\fP, \fBmemccpy\fP, \fBmemchr\fP, \fBmemcmp\fP, \fBmemcpy\fP, \fBmemmove\fP, \fBmemset\fP, \fBmkdir\fP, \fBmkdirat\fP, \fBmkfifo\fP, \fBmkfifoat\fP, \fBmknod\fP, \fBmknodat\fP, \fBntohl\fP, \fBntohs\fP, \fBopen\fP, \fBopenat\fP, \fBpause\fP, \fBpipe\fP, \fBpoll\fP, \fBposix_trace_event\fP, \fBpselect\fP, \fBpthread_kill\fP, \fBpthread_self\fP, \fBpthread_sigmask\fP, \fBquick_exit\fP, \fBraise\fP, \fBread\fP, \fBreadlink\fP, \fBreadlinkat\fP, \fBrecv\fP, \fBrecvfrom\fP, \fBrecvmsg\fP, \fBrename\fP, \fBrenameat\fP, \fBrmdir\fP, \fBselect\fP, \fBsem_post\fP, \fBsend\fP, \fBsendmsg\fP, \fBsendto\fP, \fBsetgid\fP, \fBsetpgid\fP, \fBsetsid\fP, \fBsetsockopt\fP, \fBsetuid\fP, \fBshutdown\fP, \fBsigaction\fP, \fBsigaddset\fP, \fBsigdelset\fP, \fBsigemptyset\fP, \fBsigfillset\fP, \fBsigismember\fP, \fBsiglongjmp\fP, \fBsignal\fP, \fBsigpause\fP, \fBsigpending\fP, \fBsigprocmask\fP, \fBsigqueue\fP, \fBsigset\fP, \fBsigsuspend\fP, \fBsleep\fP, \fBsockatmark\fP, \fBsocket\fP, \fBsocketpair\fP, \fBstat\fP, \fBstpcpy\fP, \fBstpncpy\fP, \fBstrcat\fP, \fBstrchr\fP, \fBstrcmp\fP, \fBstrcpy\fP, \fBstrcspn\fP, \fBstrlen\fP, \fBstrncat\fP, \fBstrncmp\fP, \fBstrncpy\fP, \fBstrnlen\fP, \fBstrpbrk\fP, \fBstrrchr\fP, \fBstrspn\fP, \fBstrstr\fP, \fBstrtok_r\fP, \fBsymlink\fP, \fBsymlinkat\fP, \fBtcdrain\fP, \fBtcflow\fP, \fBtcflush\fP, \fBtcgetattr\fP, \fBtcgetpgrp\fP, \fBtcsendbreak\fP, \fBtcsetattr\fP, \fBtcsetpgrp\fP, \fBtime\fP, \fBtimer_getoverrun\fP, \fBtimer_gettime\fP, \fBtimer_settime\fP, \fBtimes\fP, \fBumask\fP, \fBuname\fP, \fBunlink\fP, \fBunlinkat\fP, \fButime\fP, \fButimensat\fP, \fButimes\fP, \fBwait\fP, \fBwaitpid\fP, \fBwcpcpy\fP, \fBwcpncpy\fP, \fBwcscat\fP, \fBwcschr\fP, \fBwcscmp\fP, \fBwcscpy\fP, \fBwcscspn\fP, \fBwcslen\fP, \fBwcsncat\fP, \fBwcsncmp\fP, \fBwcsncpy\fP, \fBwcsnlen\fP, \fBwcspbrk\fP, \fBwcsrchr\fP, \fBwcsspn\fP, \fBwcsstr\fP, \fBwcstok\fP, \fBwmemchr\fP, \fBwmemcmp\fP, \fBwmemcpy\fP, \fBwmemmove\fP, \fBwmemset\fP, \fBwrite\fP .sp The function \fBquick_exit\fP is not included in the POSIX list but it is included here in the set of safe functions. .UNINDENT .UNINDENT .sp The default value is \fIPOSIX\fP\&. .UNINDENT .SS bugprone\-signed\-char\-misuse .sp \fIcert\-str34\-c\fP redirects here as an alias for this check. For the CERT alias, the \fIDiagnoseSignedUnsignedCharComparisons\fP option is set to \fIfalse\fP\&. .sp Finds those \fBsigned char\fP \-> integer conversions which might indicate a programming error. The basic problem with the \fBsigned char\fP, that it might store the non\-ASCII characters as negative values. This behavior can cause a misunderstanding of the written code both when an explicit and when an implicit conversion happens. .sp When the code contains an explicit \fBsigned char\fP \-> integer conversion, the human programmer probably expects that the converted value matches with the character code (a value from [0..255]), however, the actual value is in [\-128..127] interval. To avoid this kind of misinterpretation, the desired way of converting from a \fBsigned char\fP to an integer value is converting to \fBunsigned char\fP first, which stores all the characters in the positive [0..255] interval which matches the known character codes. .sp In case of implicit conversion, the programmer might not actually be aware that a conversion happened and char value is used as an integer. There are some use cases when this unawareness might lead to a functionally imperfect code. For example, checking the equality of a \fBsigned char\fP and an \fBunsigned char\fP variable is something we should avoid in C++ code. During this comparison, the two variables are converted to integers which have different value ranges. For \fBsigned char\fP, the non\-ASCII characters are stored as a value in [\-128..\-1] interval, while the same characters are stored in the [128..255] interval for an \fBunsigned char\fP\&. .sp It depends on the actual platform whether plain \fBchar\fP is handled as \fBsigned char\fP by default and so it is caught by this check or not. To change the default behavior you can use \fB\-funsigned\-char\fP and \fB\-fsigned\-char\fP compilation options. .sp Currently, this check warns in the following cases: .INDENT 0.0 .IP \(bu 2 \fBsigned char\fP is assigned to an integer variable .IP \(bu 2 \fBsigned char\fP and \fBunsigned char\fP are compared with equality/inequality operator .IP \(bu 2 \fBsigned char\fP is converted to an integer in the array subscript .UNINDENT .sp See also: STR34\-C. Cast characters to unsigned char before converting to larger integer sizes \% .sp A good example from the CERT description when a \fBchar\fP variable is used to read from a file that might contain non\-ASCII characters. The problem comes up when the code uses the \fB\-1\fP integer value as EOF, while the 255 character code is also stored as \fB\-1\fP in two\(aqs complement form of char type. See a simple example of this below. This code stops not only when it reaches the end of the file, but also when it gets a character with the 255 code. .INDENT 0.0 .INDENT 3.5 .sp .EX #define EOF (\-1) int read(void) { char CChar; int IChar = EOF; if (readChar(CChar)) { IChar = CChar; } return IChar; } .EE .UNINDENT .UNINDENT .sp A proper way to fix the code above is converting the \fBchar\fP variable to an \fBunsigned char\fP value first. .INDENT 0.0 .INDENT 3.5 .sp .EX #define EOF (\-1) int read(void) { char CChar; int IChar = EOF; if (readChar(CChar)) { IChar = static_cast(CChar); } return IChar; } .EE .UNINDENT .UNINDENT .sp Another use case is checking the equality of two \fBchar\fP variables with different signedness. Inside the non\-ASCII value range this comparison between a \fBsigned char\fP and an \fBunsigned char\fP always returns \fBfalse\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .EX bool compare(signed char SChar, unsigned char USChar) { if (SChar == USChar) return true; return false; } .EE .UNINDENT .UNINDENT .sp The easiest way to fix this kind of comparison is casting one of the arguments, so both arguments will have the same type. .INDENT 0.0 .INDENT 3.5 .sp .EX bool compare(signed char SChar, unsigned char USChar) { if (static_cast(SChar) == USChar) return true; return false; } .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B CharTypedefsToIgnore A semicolon\-separated list of typedef names. In this list, we can list typedefs for \fBchar\fP or \fBsigned char\fP, which will be ignored by the check. This is useful when a typedef introduces an integer alias like \fBsal_Int8\fP or \fBint8_t\fP\&. In this case, human misinterpretation is not an issue. Default is an empty string. .UNINDENT .INDENT 0.0 .TP .B DiagnoseSignedUnsignedCharComparisons When \fItrue\fP, the check will warn on \fBsigned char\fP/\fBunsigned char\fP comparisons, otherwise these comparisons are ignored. By default, this option is set to \fItrue\fP\&. .UNINDENT .SS bugprone\-sizeof\-container .sp The check finds usages of \fBsizeof\fP on expressions of STL container types. Most likely the user wanted to use \fB\&.size()\fP instead. .sp All class/struct types declared in namespace \fBstd::\fP having a const \fBsize()\fP method are considered containers, with the exception of \fBstd::bitset\fP and \fBstd::array\fP\&. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX std::string s; int a = 47 + sizeof(s); // warning: sizeof() doesn\(aqt return the size of the container. Did you mean .size()? int b = sizeof(std::string); // no warning, probably intended. std::string array_of_strings[10]; int c = sizeof(array_of_strings) / sizeof(array_of_strings[0]); // no warning, definitely intended. std::array std_array; int d = sizeof(std_array); // no warning, probably intended. .EE .UNINDENT .UNINDENT .SS bugprone\-sizeof\-expression .sp The check finds usages of \fBsizeof\fP expressions which are most likely errors. .sp The \fBsizeof\fP operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. Misuse of this operator may be leading to errors and possible software vulnerabilities. .SS Suspicious usage of \(aqsizeof(K)\(aq .sp A common mistake is to query the \fBsizeof\fP of an integer literal. This is equivalent to query the size of its type (probably \fBint\fP). The intent of the programmer was probably to simply get the integer and not its size. .INDENT 0.0 .INDENT 3.5 .sp .EX #define BUFLEN 42 char buf[BUFLEN]; memset(buf, 0, sizeof(BUFLEN)); // sizeof(42) ==> sizeof(int) .EE .UNINDENT .UNINDENT .SS Suspicious usage of \(aqsizeof(expr)\(aq .sp In cases, where there is an enum or integer to represent a type, a common mistake is to query the \fBsizeof\fP on the integer or enum that represents the type that should be used by \fBsizeof\fP\&. This results in the size of the integer and not of the type the integer represents: .INDENT 0.0 .INDENT 3.5 .sp .EX enum data_type { FLOAT_TYPE, DOUBLE_TYPE }; struct data { data_type type; void* buffer; data_type get_type() { return type; } }; void f(data d, int numElements) { // should be sizeof(float) or sizeof(double), depending on d.get_type() int numBytes = numElements * sizeof(d.get_type()); ... } .EE .UNINDENT .UNINDENT .SS Suspicious usage of \(aqsizeof(this)\(aq .sp The \fBthis\fP keyword is evaluated to a pointer to an object of a given type. The expression \fBsizeof(this)\fP is returning the size of a pointer. The programmer most likely wanted the size of the object and not the size of the pointer. .INDENT 0.0 .INDENT 3.5 .sp .EX class Point { [...] size_t size() { return sizeof(this); } // should probably be sizeof(*this) [...] }; .EE .UNINDENT .UNINDENT .SS Suspicious usage of \(aqsizeof(char*)\(aq .sp There is a subtle difference between declaring a string literal with \fBchar* A = \(dq\(dq\fP and \fBchar A[] = \(dq\(dq\fP\&. The first case has the type \fBchar*\fP instead of the aggregate type \fBchar[]\fP\&. Using \fBsizeof\fP on an object declared with \fBchar*\fP type is returning the size of a pointer instead of the number of characters (bytes) in the string literal. .INDENT 0.0 .INDENT 3.5 .sp .EX const char* kMessage = \(dqHello World!\(dq; // const char kMessage[] = \(dq...\(dq; void getMessage(char* buf) { memcpy(buf, kMessage, sizeof(kMessage)); // sizeof(char*) } .EE .UNINDENT .UNINDENT .SS Suspicious usage of \(aqsizeof(A*)\(aq .sp A common mistake is to compute the size of a pointer instead of its pointee. These cases may occur because of explicit cast or implicit conversion. .INDENT 0.0 .INDENT 3.5 .sp .EX int A[10]; memset(A, 0, sizeof(A + 0)); struct Point point; memset(point, 0, sizeof(&point)); .EE .UNINDENT .UNINDENT .SS Suspicious usage of \(aqsizeof(...)/sizeof(...)\(aq .sp Dividing \fBsizeof\fP expressions is typically used to retrieve the number of elements of an aggregate. This check warns on incompatible or suspicious cases. .sp In the following example, the entity has 10\-bytes and is incompatible with the type \fBint\fP which has 4 bytes. .INDENT 0.0 .INDENT 3.5 .sp .EX char buf[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; // sizeof(buf) => 10 void getMessage(char* dst) { memcpy(dst, buf, sizeof(buf) / sizeof(int)); // sizeof(int) => 4 [incompatible sizes] } .EE .UNINDENT .UNINDENT .sp In the following example, the expression \fBsizeof(Values)\fP is returning the size of \fBchar*\fP\&. One can easily be fooled by its declaration, but in parameter declaration the size \(aq10\(aq is ignored and the function is receiving a \fBchar*\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .EX char OrderedValues[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; return CompareArray(char Values[10]) { return memcmp(OrderedValues, Values, sizeof(Values)) == 0; // sizeof(Values) ==> sizeof(char*) [implicit cast to char*] } .EE .UNINDENT .UNINDENT .SS Suspicious \(aqsizeof\(aq by \(aqsizeof\(aq expression .sp Multiplying \fBsizeof\fP expressions typically makes no sense and is probably a logic error. In the following example, the programmer used \fB*\fP instead of \fB/\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .EX const char kMessage[] = \(dqHello World!\(dq; void getMessage(char* buf) { memcpy(buf, kMessage, sizeof(kMessage) * sizeof(char)); // sizeof(kMessage) / sizeof(char) } .EE .UNINDENT .UNINDENT .sp This check may trigger on code using the arraysize macro. The following code is working correctly but should be simplified by using only the \fBsizeof\fP operator. .INDENT 0.0 .INDENT 3.5 .sp .EX extern Object objects[100]; void InitializeObjects() { memset(objects, 0, arraysize(objects) * sizeof(Object)); // sizeof(objects) } .EE .UNINDENT .UNINDENT .SS Suspicious usage of \(aqsizeof(sizeof(...))\(aq .sp Getting the \fBsizeof\fP of a \fBsizeof\fP makes no sense and is typically an error hidden through macros. .INDENT 0.0 .INDENT 3.5 .sp .EX #define INT_SZ sizeof(int) int buf[] = { 42 }; void getInt(int* dst) { memcpy(dst, buf, sizeof(INT_SZ)); // sizeof(sizeof(int)) is suspicious. } .EE .UNINDENT .UNINDENT .SS Suspicious usages of \(aqsizeof(...)\(aq in pointer arithmetic .sp Arithmetic operators on pointers automatically scale the result with the size of the pointed typed. Further use of \fBsizeof\fP around pointer arithmetic will typically result in an unintended result. .SS Scaling the result of pointer difference .sp Subtracting two pointers results in an integer expression (of type \fBptrdiff_t\fP) which expresses the distance between the two pointed objects in \(dqnumber of objects between\(dq. A common mistake is to think that the result is \(dqnumber of bytes between\(dq, and scale the difference with \fBsizeof\fP, such as \fBP1 \- P2 == N * sizeof(T)\fP (instead of \fBP1 \- P2 == N\fP) or \fB(P1 \- P2) / sizeof(T)\fP instead of \fBP1 \- P2\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .EX void splitFour(const Obj* Objs, size_t N, Obj Delimiter) { const Obj *P = Objs; while (P < Objs + N) { if (*P == Delimiter) { break; } } if (P \- Objs != 4 * sizeof(Obj)) { // Expecting a distance multiplied by sizeof is suspicious. error(); } } .EE .UNINDENT .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .EX void iterateIfEvenLength(int *Begin, int *End) { auto N = (Begin \- End) / sizeof(int); // Dividing by sizeof() is suspicious. if (N % 2) return; // ... } .EE .UNINDENT .UNINDENT .SS Stepping a pointer with a scaled integer .sp Conversely, when performing pointer arithmetics to add or subtract from a pointer, the arithmetic operator implicitly scales the value actually added to the pointer with the size of the pointee, as \fBPtr + N\fP expects \fBN\fP to be \(dqnumber of objects to step\(dq, and not \(dqnumber of bytes to step\(dq. .sp Seeing the calculation of a pointer where \fBsizeof\fP appears is suspicious, and the result is typically unintended, often out of bounds. \fBPtr + sizeof(T)\fP will offset the pointer by \fBsizeof(T)\fP elements, effectively exponentiating the scaling factor to the power of 2. .sp Similarly, multiplying or dividing a numeric value with the \fBsizeof\fP of an element or the whole buffer is suspicious, because the dimensional connection between the numeric value and the actual \fBsizeof\fP result can not always be deduced. While scaling an integer up (multiplying) with \fBsizeof\fP is likely \fBalways\fP an issue, a scaling down (division) is not always inherently dangerous, in case the developer is aware that the division happens between an appropriate number of _bytes_ and a \fBsizeof\fP value. Turning \fBWarnOnOffsetDividedBySizeOf\fP off will restrict the warnings to the multiplication case. .sp This case also checks suspicious \fBalignof\fP and \fBoffsetof\fP usages in pointer arithmetic, as both return the \(dqsize\(dq in bytes and not elements, potentially resulting in doubly\-scaled offsets. .INDENT 0.0 .INDENT 3.5 .sp .EX void printEveryEvenIndexElement(int *Array, size_t N) { int *P = Array; while (P <= Array + N * sizeof(int)) { // Suspicious pointer arithmetic using sizeof()! printf(\(dq%d \(dq, *P); P += 2 * sizeof(int); // Suspicious pointer arithmetic using sizeof()! } } .EE .UNINDENT .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .EX struct Message { /* ... */; char Flags[8]; }; void clearFlags(Message *Array, size_t N) { const Message *End = Array + N; while (Array < End) { memset(Array + offsetof(Message, Flags), // Suspicious pointer arithmetic using offsetof()! 0, sizeof(Message::Flags)); ++Array; } } .EE .UNINDENT .UNINDENT .sp For this checked bogus pattern, \fIcert\-arr39\-c\fP redirects here as an alias of this check. .sp This check corresponds to the CERT C Coding Standard rule ARR39\-C. Do not add or subtract a scaled integer to a pointer \%\&. .SS Limitations .sp Cases where the pointee type has a size of \fI1\fP byte (such as, and most importantly, \fBchar\fP) are excluded. .SS Options .INDENT 0.0 .TP .B WarnOnSizeOfConstant When \fItrue\fP, the check will warn on an expression like \fBsizeof(CONSTANT)\fP\&. Default is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B WarnOnSizeOfIntegerExpression When \fItrue\fP, the check will warn on an expression like \fBsizeof(expr)\fP where the expression results in an integer. Default is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B WarnOnSizeOfThis When \fItrue\fP, the check will warn on an expression like \fBsizeof(this)\fP\&. Default is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B WarnOnSizeOfCompareToConstant When \fItrue\fP, the check will warn on an expression like \fBsizeof(expr) <= k\fP for a suspicious constant \fIk\fP while \fIk\fP is \fI0\fP or greater than \fI0x8000\fP\&. Default is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B WarnOnSizeOfPointerToAggregate When \fItrue\fP, the check will warn when the argument of \fBsizeof\fP is either a pointer\-to\-aggregate type, an expression returning a pointer\-to\-aggregate value or an expression that returns a pointer from an array\-to\-pointer conversion (that may be implicit or explicit, for example \fBarray + 2\fP or \fB(int *)array\fP). Default is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B WarnOnSizeOfPointer When \fItrue\fP, the check will report all expressions where the argument of \fBsizeof\fP is an expression that produces a pointer (except for a few idiomatic expressions that are probably intentional and correct). This detects occurrences of CWE 467. Default is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B WarnOnOffsetDividedBySizeOf When \fItrue\fP, the check will warn on pointer arithmetic where the element count is obtained from a division with \fBsizeof(...)\fP, e.g., \fBPtr + Bytes / sizeof(*T)\fP\&. Default is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B WarnOnSizeOfInLoopTermination When \fItrue\fP, the check will warn about incorrect use of sizeof expression in loop termination condition. The warning triggers if the \fBsizeof\fP expression appears to be incorrectly used to determine the number of array/buffer elements. e.g, \fBlong arr[10]; for(int i = 0; i < sizeof(arr); i++) { ... }\fP\&. Default is \fItrue\fP\&. .UNINDENT .SS bugprone\-spuriously\-wake\-up\-functions .sp Finds \fBcnd_wait\fP, \fBcnd_timedwait\fP, \fBwait\fP, \fBwait_for\fP, or \fBwait_until\fP function calls when the function is not invoked from a loop that checks whether a condition predicate holds or the function has a condition parameter. .INDENT 0.0 .INDENT 3.5 .sp .EX if (condition_predicate) { condition.wait(lk); } .EE .UNINDENT .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .EX if (condition_predicate) { if (thrd_success != cnd_wait(&condition, &lock)) { } } .EE .UNINDENT .UNINDENT .sp This check corresponds to the CERT C++ Coding Standard rule CON54\-CPP. Wrap functions that can spuriously wake up in a loop \%\&. and CERT C Coding Standard rule CON36\-C. Wrap functions that can spuriously wake up in a loop \%\&. .SS bugprone\-standalone\-empty .sp Warns when \fBempty()\fP is used on a range and the result is ignored. Suggests \fBclear()\fP if it is an existing member function. .sp The \fBempty()\fP method on several common ranges returns a Boolean indicating whether or not the range is empty, but is often mistakenly interpreted as a way to clear the contents of a range. Some ranges offer a \fBclear()\fP method for this purpose. This check warns when a call to empty returns a result that is ignored, and suggests replacing it with a call to \fBclear()\fP if it is available as a member function of the range. .sp For example, the following code could be used to indicate whether a range is empty or not, but the result is ignored: .INDENT 0.0 .INDENT 3.5 .sp .EX std::vector v; \&... v.empty(); .EE .UNINDENT .UNINDENT .sp A call to \fBclear()\fP would appropriately clear the contents of the range: .INDENT 0.0 .INDENT 3.5 .sp .EX std::vector v; \&... v.clear(); .EE .UNINDENT .UNINDENT .SS Limitations .INDENT 0.0 .IP \(bu 2 Doesn\(aqt warn if \fBempty()\fP is defined and used with the ignore result in the class template definition (for example in the library implementation). These error cases can be caught with \fB[[nodiscard]]\fP attribute. .UNINDENT .SS bugprone\-std\-namespace\-modification .sp Warns on modifications of the \fBstd\fP or \fBposix\fP namespaces which can result in undefined behavior. .sp The \fBstd\fP (or \fBposix\fP) namespace is allowed to be extended with (class or function) template specializations that depend on an user\-defined type (a type that is not defined in the standard system headers). .sp The check detects the following (user provided) declarations in namespace \fBstd\fP or \fBposix\fP: .INDENT 0.0 .IP \(bu 2 Anything that is not a template specialization. .IP \(bu 2 Explicit specializations of any standard library function template or class template, if it does not have any user\-defined type as template argument. .IP \(bu 2 Explicit specializations of any member function of a standard library class template. .IP \(bu 2 Explicit specializations of any member function template of a standard library class or class template. .IP \(bu 2 Explicit or partial specialization of any member class template of a standard library class or class template. .UNINDENT .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX namespace std { int x; // warning: modification of \(aqstd\(aq namespace can result in undefined behavior [bugprone\-dont\-modify\-std\-namespace] } namespace posix::a { // warning: modification of \(aqposix\(aq namespace can result in undefined behavior } template <> struct ::std::hash { // warning: modification of \(aqstd\(aq namespace can result in undefined behavior unsigned long operator()(const long &K) const { return K; } }; struct MyData { long data; }; template <> struct ::std::hash { // no warning: specialization with user\-defined type unsigned long operator()(const MyData &K) const { return K.data; } }; namespace std { template <> void swap(bool &a, bool &b); // warning: modification of \(aqstd\(aq namespace can result in undefined behavior template <> bool less::operator()(MyData &&, MyData &&) const { // warning: modification of \(aqstd\(aq namespace can result in undefined behavior return true; } } .EE .UNINDENT .UNINDENT .SS References .sp This check corresponds to the CERT C++ Coding Standard rule DCL58\-CPP. Do not modify the standard namespaces \%\&. .SS bugprone\-string\-constructor .sp Finds string constructors that are suspicious and probably errors. .sp A common mistake is to swap parameters to the \(aqfill\(aq string\-constructor. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX std::string str(\(aqx\(aq, 50); // should be str(50, \(aqx\(aq) .EE .UNINDENT .UNINDENT .sp Calling the string\-literal constructor with a length bigger than the literal is suspicious and adds extra random characters to the string. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX std::string(\(dqtest\(dq, 200); // Will include random characters after \(dqtest\(dq. std::string(\(dqtest\(dq, 2, 5); // Will include random characters after \(dqst\(dq. std::string_view(\(dqtest\(dq, 200); .EE .UNINDENT .UNINDENT .sp Creating an empty string from constructors with parameters is considered suspicious. The programmer should use the empty constructor instead. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX std::string(\(dqtest\(dq, 0); // Creation of an empty string. std::string(\(dqtest\(dq, 1, 0); std::string_view(\(dqtest\(dq, 0); .EE .UNINDENT .UNINDENT .sp Passing an invalid first character position parameter to constructor will cause \fBstd::out_of_range\fP exception at runtime. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX std::string(\(dqtest\(dq, \-1, 10); // Negative first character position. std::string(\(dqtest\(dq, 10, 10); // First character position is bigger than string literal character range\(dq. .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B WarnOnLargeLength When \fItrue\fP, the check will warn on a string with a length greater than \fBLargeLengthThreshold\fP\&. Default is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B LargeLengthThreshold An integer specifying the large length threshold. Default is \fI0x800000\fP\&. .UNINDENT .INDENT 0.0 .TP .B StringNames Default is \fI::std::basic_string;::std::basic_string_view\fP\&. .sp Semicolon\-delimited list of class names to apply this check to. By default \fI::std::basic_string\fP applies to \fBstd::string\fP and \fBstd::wstring\fP\&. Set to e.g. \fI::std::basic_string;llvm::StringRef;QString\fP to perform this check on custom classes. .UNINDENT .SS bugprone\-string\-integer\-assignment .sp The check finds assignments of an integer to \fBstd::basic_string\fP (\fBstd::string\fP, \fBstd::wstring\fP, etc.). The source of the problem is the following assignment operator of \fBstd::basic_string\fP: .INDENT 0.0 .INDENT 3.5 .sp .EX basic_string& operator=( CharT ch ); .EE .UNINDENT .UNINDENT .sp Numeric types can be implicitly casted to character types. .INDENT 0.0 .INDENT 3.5 .sp .EX std::string s; int x = 5965; s = 6; s = x; .EE .UNINDENT .UNINDENT .sp Use the appropriate conversion functions or character literals. .INDENT 0.0 .INDENT 3.5 .sp .EX std::string s; int x = 5965; s = \(aq6\(aq; s = std::to_string(x); .EE .UNINDENT .UNINDENT .sp In order to suppress false positives, use an explicit cast. .INDENT 0.0 .INDENT 3.5 .sp .EX std::string s; s = static_cast(6); .EE .UNINDENT .UNINDENT .SS bugprone\-string\-literal\-with\-embedded\-nul .sp Finds occurrences of string literal with embedded NUL character and validates their usage. .SS Invalid escaping .sp Special characters can be escaped within a string literal by using their hexadecimal encoding like \fB\ex42\fP\&. A common mistake is to escape them like this \fB\e0x42\fP where the \fB\e0\fP stands for the NUL character. .INDENT 0.0 .INDENT 3.5 .sp .EX const char* Example[] = \(dqInvalid character: \e0x12 should be \ex12\(dq; const char* Bytes[] = \(dq\ex03\e0x02\e0x01\e0x00\e0xFF\e0xFF\e0xFF\(dq; .EE .UNINDENT .UNINDENT .SS Truncated literal .sp String\-like classes can manipulate strings with embedded NUL as they are keeping track of the bytes and the length. This is not the case for a \fBchar*\fP (NUL\-terminated) string. .sp A common mistake is to pass a string\-literal with embedded NUL to a string constructor expecting a NUL\-terminated string. The bytes after the first NUL character are truncated. .INDENT 0.0 .INDENT 3.5 .sp .EX std::string str(\(dqabc\e0def\(dq); // \(dqdef\(dq is truncated str += \(dq\e0\(dq; // This statement is doing nothing if (str == \(dq\e0abc\(dq) return; // This expression is always true .EE .UNINDENT .UNINDENT .SS bugprone\-stringview\-nullptr .sp Checks for various ways that the \fBconst CharT*\fP constructor of \fBstd::basic_string_view\fP can be passed a null argument and replaces them with the default constructor in most cases. For the comparison operators, braced initializer list does not compile so instead a call to \fB\&.empty()\fP or the empty string literal are used, where appropriate. .sp This prevents code from invoking behavior which is unconditionally undefined. The single\-argument \fBconst CharT*\fP constructor does not check for the null case before dereferencing its input. The standard is slated to add an explicitly\-deleted overload to catch some of these cases: wg21.link/p2166 .sp To catch the additional cases of \fBNULL\fP (which expands to \fB__null\fP) and \fB0\fP, first run the \fBmodernize\-use\-nullptr\fP check to convert the callers to \fBnullptr\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .EX std::string_view sv = nullptr; sv = nullptr; bool is_empty = sv == nullptr; bool isnt_empty = sv != nullptr; accepts_sv(nullptr); accepts_sv({{}}); // A accepts_sv({nullptr, 0}); // B .EE .UNINDENT .UNINDENT .sp is translated into... .INDENT 0.0 .INDENT 3.5 .sp .EX std::string_view sv = {}; sv = {}; bool is_empty = sv.empty(); bool isnt_empty = !sv.empty(); accepts_sv(\(dq\(dq); accepts_sv(\(dq\(dq); // A accepts_sv({nullptr, 0}); // B .EE .UNINDENT .UNINDENT .sp \fBNote:\fP .INDENT 0.0 .INDENT 3.5 The source pattern with trailing comment \(dqA\(dq selects the \fB(const CharT*)\fP constructor overload and then value\-initializes the pointer, causing a null dereference. It happens to not include the \fBnullptr\fP literal, but it is still within the scope of this ClangTidy check. .UNINDENT .UNINDENT .sp \fBNote:\fP .INDENT 0.0 .INDENT 3.5 The source pattern with trailing comment \(dqB\(dq selects the \fB(const CharT*, size_type)\fP constructor which is perfectly valid, since the length argument is \fB0\fP\&. It is not changed by this ClangTidy check. .UNINDENT .UNINDENT .SS bugprone\-suspicious\-enum\-usage .sp The checker detects various cases when an enum is probably misused (as a bitmask). .INDENT 0.0 .IP 1. 3 When \(dqADD\(dq or \(dqbitwise OR\(dq is used between two enum which come from different types and these types value ranges are not disjoint. .UNINDENT .sp The following cases will be investigated only using \fBStrictMode\fP \%<#\:cmdoption-arg-StrictMode>\&. We regard the enum as a (suspicious) bitmask if the three conditions below are true at the same time: .INDENT 0.0 .IP \(bu 2 at most half of the elements of the enum are non pow\-of\-2 numbers (because of short enumerations) .IP \(bu 2 there is another non pow\-of\-2 number than the enum constant representing all choices (the result \(dqbitwise OR\(dq operation of all enum elements) .IP \(bu 2 enum type variable/enumconstant is used as an argument of a \fI+\fP or \(dqbitwise OR\(dq operator .UNINDENT .sp So whenever the non pow\-of\-2 element is used as a bitmask element we diagnose a misuse and give a warning. .INDENT 0.0 .IP 2. 3 Investigating the right hand side of \fB+=\fP and \fB|=\fP operator. .IP 3. 3 Check only the enum value side of a \fB|\fP and \fB+\fP operator if one of them is not enum val. .IP 4. 3 Check both side of \fB|\fP or \fB+\fP operator where the enum values are from the same enum type. .UNINDENT .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX enum { A, B, C }; enum { D, E, F = 5 }; enum { G = 10, H = 11, I = 12 }; unsigned flag; flag = A | H; // OK, disjoint value intervals in the enum types \->probably good use. flag = B | F; // Warning, have common values so they are probably misused. // Case 2: enum Bitmask { A = 0, B = 1, C = 2, D = 4, E = 8, F = 16, G = 31 // OK, real bitmask. }; enum Almostbitmask { AA = 0, BB = 1, CC = 2, DD = 4, EE = 8, FF = 16, GG // Problem, forgot to initialize. }; unsigned flag = 0; flag |= E; // OK. flag |= EE; // Warning at the decl, and note that it was used here as a bitmask. .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B StrictMode Default value: 0. When non\-null the suspicious bitmask usage will be investigated additionally to the different enum usage check. .UNINDENT .SS bugprone\-suspicious\-include .sp The check detects various cases when an include refers to what appears to be an implementation file, which often leads to hard\-to\-track\-down ODR violations. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX #include \(dqDinosaur.hpp\(dq // OK, .hpp files tend not to have definitions. #include \(dqPterodactyl.h\(dq // OK, .h files tend not to have definitions. #include \(dqVelociraptor.cpp\(dq // Warning, filename is suspicious. #include_next // Warning, filename is suspicious. .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IgnoredRegex A regular expression for the file name to be ignored by the check. Default is empty string. .UNINDENT .SS bugprone\-suspicious\-memory\-comparison .sp Finds potentially incorrect calls to \fBmemcmp()\fP based on properties of the arguments. The following cases are covered: .sp \fBCase 1: Non\-standard\-layout type\fP .sp Comparing the object representations of non\-standard\-layout objects may not properly compare the value representations. .sp \fBCase 2: Types with no unique object representation\fP .sp Objects with the same value may not have the same object representation. This may be caused by padding or floating\-point types. .sp See also: EXP42\-C. Do not compare padding data \% and FLP37\-C. Do not use object representations to compare floating\-point values \% .sp This check is also related to and partially overlaps the CERT C++ Coding Standard rules OOP57\-CPP. Prefer special member functions and overloaded operators to C Standard Library functions \% and EXP62\-CPP. Do not access the bits of an object representation that are not part of the object\(aqs value representation \% .sp \fIcert\-exp42\-c\fP redirects here as an alias of this check. .SS bugprone\-suspicious\-memset\-usage .sp This check finds \fBmemset()\fP calls with potential mistakes in their arguments. Considering the function as \fBvoid* memset(void* destination, int fill_value, size_t byte_count)\fP, the following cases are covered: .sp \fBCase 1: Fill value is a character \(ga\(ga\(aq0\(aq\(ga\(ga\fP .sp Filling up a memory area with ASCII code 48 characters is not customary, possibly integer zeroes were intended instead. The check offers a replacement of \fB\(aq0\(aq\fP with \fB0\fP\&. Memsetting character pointers with \fB\(aq0\(aq\fP is allowed. .sp \fBCase 2: Fill value is truncated\fP .sp Memset converts \fBfill_value\fP to \fBunsigned char\fP before using it. If \fBfill_value\fP is out of unsigned character range, it gets truncated and memory will not contain the desired pattern. .sp \fBCase 3: Byte count is zero\fP .sp Calling memset with a literal zero in its \fBbyte_count\fP argument is likely to be unintended and swapped with \fBfill_value\fP\&. The check offers to swap these two arguments. .sp Corresponding cpplint.py check name: \fBruntime/memset\fP\&. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX void foo() { int i[5] = {1, 2, 3, 4, 5}; int *ip = i; char c = \(aq1\(aq; char *cp = &c; int v = 0; // Case 1 memset(ip, \(aq0\(aq, 1); // suspicious memset(cp, \(aq0\(aq, 1); // OK // Case 2 memset(ip, 0xabcd, 1); // fill value gets truncated memset(ip, 0x00, 1); // OK // Case 3 memset(ip, sizeof(int), v); // zero length, potentially swapped memset(ip, 0, 1); // OK } .EE .UNINDENT .UNINDENT .SS bugprone\-suspicious\-missing\-comma .sp String literals placed side\-by\-side are concatenated at translation phase 6 (after the preprocessor). This feature is used to represent long string literal on multiple lines. .sp For instance, the following declarations are equivalent: .INDENT 0.0 .INDENT 3.5 .sp .EX const char* A[] = \(dqThis is a test\(dq; const char* B[] = \(dqThis\(dq \(dq is a \(dq \(dqtest\(dq; .EE .UNINDENT .UNINDENT .sp A common mistake done by programmers is to forget a comma between two string literals in an array initializer list. .INDENT 0.0 .INDENT 3.5 .sp .EX const char* Test[] = { \(dqline 1\(dq, \(dqline 2\(dq // Missing comma! \(dqline 3\(dq, \(dqline 4\(dq, \(dqline 5\(dq }; .EE .UNINDENT .UNINDENT .sp The array contains the string \(dqline 2line3\(dq at offset 1 (i.e. Test[1]). Clang won\(aqt generate warnings at compile time. .sp This check may warn incorrectly on cases like: .INDENT 0.0 .INDENT 3.5 .sp .EX const char* SupportedFormat[] = { \(dqError %s\(dq, \(dqCode \(dq PRIu64, // May warn here. \(dqWarning %s\(dq, }; .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B SizeThreshold An unsigned integer specifying the minimum size of a string literal to be considered by the check. Default is \fB5U\fP\&. .UNINDENT .INDENT 0.0 .TP .B RatioThreshold A string specifying the maximum threshold ratio [0, 1.0] of suspicious string literals to be considered. Default is \fB\(dq.2\(dq\fP\&. .UNINDENT .INDENT 0.0 .TP .B MaxConcatenatedTokens An unsigned integer specifying the maximum number of concatenated tokens. Default is \fB5U\fP\&. .UNINDENT .SS bugprone\-suspicious\-realloc\-usage .sp This check finds usages of \fBrealloc\fP where the return value is assigned to the same expression as passed to the first argument: \fBp = realloc(p, size);\fP The problem with this construct is that if \fBrealloc\fP fails it returns a null pointer but does not deallocate the original memory. If no other variable is pointing to it, the original memory block is not available any more for the program to use or free. In either case \fBp = realloc(p, size);\fP indicates bad coding style and can be replaced by \fBq = realloc(p, size);\fP\&. .sp The pointer expression (used at \fBrealloc\fP) can be a variable or a field member of a data structure, but can not contain function calls or unresolved types. .sp In obvious cases when the pointer used at realloc is assigned to another variable before the \fBrealloc\fP call, no warning is emitted. This happens only if a simple expression in form of \fBq = p\fP or \fBvoid *q = p\fP is found in the same function where \fBp = realloc(p, ...)\fP is found. The assignment has to be before the call to realloc (but otherwise at any place) in the same function. This suppression works only if \fBp\fP is a single variable. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX struct A { void *p; }; A &getA(); void foo(void *p, A *a, int new_size) { p = realloc(p, new_size); // warning: \(aqp\(aq may be set to null if \(aqrealloc\(aq fails, which may result in a leak of the original buffer a\->p = realloc(a\->p, new_size); // warning: \(aqa\->p\(aq may be set to null if \(aqrealloc\(aq fails, which may result in a leak of the original buffer getA().p = realloc(getA().p, new_size); // no warning } void foo1(void *p, int new_size) { void *p1 = p; p = realloc(p, new_size); // no warning } .EE .UNINDENT .UNINDENT .SS bugprone\-suspicious\-semicolon .sp Finds most instances of stray semicolons that unexpectedly alter the meaning of the code. More specifically, it looks for \fBif\fP, \fBwhile\fP, \fBfor\fP and \fBfor\-range\fP statements whose body is a single semicolon, and then analyzes the context of the code (e.g. indentation) in an attempt to determine whether that is intentional. .INDENT 0.0 .INDENT 3.5 .sp .EX if (x < y); { x++; } .EE .UNINDENT .UNINDENT .sp Here the body of the \fBif\fP statement consists of only the semicolon at the end of the first line, and \fIx\fP will be incremented regardless of the condition. .INDENT 0.0 .INDENT 3.5 .sp .EX while ((line = readLine(file)) != NULL); processLine(line); .EE .UNINDENT .UNINDENT .sp As a result of this code, \fIprocessLine()\fP will only be called once, when the \fBwhile\fP loop with the empty body exits with \fBline == NULL\fP\&. The indentation of the code indicates the intention of the programmer. .INDENT 0.0 .INDENT 3.5 .sp .EX if (x >= y); x \-= y; .EE .UNINDENT .UNINDENT .sp While the indentation does not imply any nesting, there is simply no valid reason to have an \fIif\fP statement with an empty body (but it can make sense for a loop). So this check issues a warning for the code above. .sp To solve the issue remove the stray semicolon or in case the empty body is intentional, reflect this using code indentation or put the semicolon in a new line. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX while (readWhitespace()); Token t = readNextToken(); .EE .UNINDENT .UNINDENT .sp Here the second line is indented in a way that suggests that it is meant to be the body of the \fIwhile\fP loop \- whose body is in fact empty, because of the semicolon at the end of the first line. .sp Either remove the indentation from the second line: .INDENT 0.0 .INDENT 3.5 .sp .EX while (readWhitespace()); Token t = readNextToken(); .EE .UNINDENT .UNINDENT .sp \&... or move the semicolon from the end of the first line to a new line: .INDENT 0.0 .INDENT 3.5 .sp .EX while (readWhitespace()) ; Token t = readNextToken(); .EE .UNINDENT .UNINDENT .sp In this case the check will assume that you know what you are doing, and will not raise a warning. .SS bugprone\-suspicious\-string\-compare .sp Find suspicious usage of runtime string comparison functions. This check is valid in C and C++. .sp Checks for calls with implicit comparator and proposed to explicitly add it. .INDENT 0.0 .INDENT 3.5 .sp .EX if (strcmp(...)) // Implicitly compare to zero if (!strcmp(...)) // Won\(aqt warn if (strcmp(...) != 0) // Won\(aqt warn .EE .UNINDENT .UNINDENT .sp Checks that compare function results (i.e., \fBstrcmp\fP) are compared to valid constant. The resulting value is .INDENT 0.0 .INDENT 3.5 .sp .EX < 0 when lower than, > 0 when greater than, == 0 when equals. .EE .UNINDENT .UNINDENT .sp A common mistake is to compare the result to \fI1\fP or \fI\-1\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .EX if (strcmp(...) == \-1) // Incorrect usage of the returned value. .EE .UNINDENT .UNINDENT .sp Additionally, the check warns if the results value is implicitly cast to a \fIsuspicious\fP non\-integer type. It\(aqs happening when the returned value is used in a wrong context. .INDENT 0.0 .INDENT 3.5 .sp .EX if (strcmp(...) < 0.) // Incorrect usage of the returned value. .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B WarnOnImplicitComparison When \fItrue\fP, the check will warn on implicit comparison. \fItrue\fP by default. .UNINDENT .INDENT 0.0 .TP .B WarnOnLogicalNotComparison When \fItrue\fP, the check will warn on logical not comparison. \fIfalse\fP by default. .UNINDENT .INDENT 0.0 .TP .B StringCompareLikeFunctions A string specifying the comma\-separated names of the extra string comparison functions. Default is an empty string. The check will detect the following string comparison functions: \fI__builtin_memcmp\fP, \fI__builtin_strcasecmp\fP, \fI__builtin_strcmp\fP, \fI__builtin_strncasecmp\fP, \fI__builtin_strncmp\fP, \fI_mbscmp\fP, \fI_mbscmp_l\fP, \fI_mbsicmp\fP, \fI_mbsicmp_l\fP, \fI_mbsnbcmp\fP, \fI_mbsnbcmp_l\fP, \fI_mbsnbicmp\fP, \fI_mbsnbicmp_l\fP, \fI_mbsncmp\fP, \fI_mbsncmp_l\fP, \fI_mbsnicmp\fP, \fI_mbsnicmp_l\fP, \fI_memicmp\fP, \fI_memicmp_l\fP, \fI_stricmp\fP, \fI_stricmp_l\fP, \fI_strnicmp\fP, \fI_strnicmp_l\fP, \fI_wcsicmp\fP, \fI_wcsicmp_l\fP, \fI_wcsnicmp\fP, \fI_wcsnicmp_l\fP, \fIlstrcmp\fP, \fIlstrcmpi\fP, \fImemcmp\fP, \fImemicmp\fP, \fIstrcasecmp\fP, \fIstrcmp\fP, \fIstrcmpi\fP, \fIstricmp\fP, \fIstrncasecmp\fP, \fIstrncmp\fP, \fIstrnicmp\fP, \fIwcscasecmp\fP, \fIwcscmp\fP, \fIwcsicmp\fP, \fIwcsncmp\fP, \fIwcsnicmp\fP, \fIwmemcmp\fP\&. .UNINDENT .SS bugprone\-suspicious\-stringview\-data\-usage .sp Identifies suspicious usages of \fBstd::string_view::data()\fP that could lead to reading out\-of\-bounds data due to inadequate or incorrect string null termination. .sp It warns when the result of \fBdata()\fP is passed to a constructor or function without also passing the corresponding result of \fBsize()\fP or \fBlength()\fP member function. Such usage can lead to unintended behavior, particularly when assuming the data pointed to by \fBdata()\fP is null\-terminated. .sp The absence of a \fBc_str()\fP method in \fBstd::string_view\fP often leads developers to use \fBdata()\fP as a substitute, especially when interfacing with C APIs that expect null\-terminated strings. However, since \fBdata()\fP does not guarantee null termination, this can result in unintended behavior if the API relies on proper null termination for correct string interpretation. .sp In today\(aqs programming landscape, this scenario can occur when implicitly converting an \fBstd::string_view\fP to an \fBstd::string\fP\&. Since the constructor in \fBstd::string\fP designed for string\-view\-like objects is \fBexplicit\fP, attempting to pass an \fBstd::string_view\fP to a function expecting an \fBstd::string\fP will result in a compilation error. As a workaround, developers may be tempted to utilize the \fB\&.data()\fP method to achieve compilation, introducing potential risks. .sp For instance: .INDENT 0.0 .INDENT 3.5 .sp .EX void printString(const std::string& str) { std::cout << \(dqString: \(dq << str << std::endl; } void something(std::string_view sv) { printString(sv.data()); } .EE .UNINDENT .UNINDENT .sp In this example, directly passing \fBsv\fP to the \fBprintString\fP function would lead to a compilation error due to the explicit nature of the \fBstd::string\fP constructor. Consequently, developers might opt for \fBsv.data()\fP to resolve the compilation error, albeit introducing potential hazards as discussed. .SS Options .INDENT 0.0 .TP .B StringViewTypes Option allows users to specify custom string view\-like types for analysis. It accepts a semicolon\-separated list of type names or regular expressions matching these types. Default value is: \fI::std::basic_string_view;::llvm::StringRef\fP\&. .UNINDENT .INDENT 0.0 .TP .B AllowedCallees Specifies methods, functions, or classes where the result of \fB\&.data()\fP is passed to. Allows to exclude such calls from the analysis. Accepts a semicolon\-separated list of names or regular expressions matching these entities. Default value is: empty string. .UNINDENT .SS bugprone\-swapped\-arguments .sp Finds potentially swapped arguments by examining implicit conversions. It analyzes the types of the arguments being passed to a function and compares them to the expected types of the corresponding parameters. If there is a mismatch or an implicit conversion that indicates a potential swap, a warning is raised. .INDENT 0.0 .INDENT 3.5 .sp .EX void printNumbers(int a, float b); int main() { // Swapped arguments: float passed as int, int as float) printNumbers(10.0f, 5); return 0; } .EE .UNINDENT .UNINDENT .sp Covers a wide range of implicit conversions, including: \- User\-defined conversions \- Conversions from floating\-point types to boolean or integral types \- Conversions from integral types to boolean or floating\-point types \- Conversions from boolean to integer types or floating\-point types \- Conversions from (member) pointers to boolean .sp It is important to note that for most argument swaps, the types need to match exactly. However, there are exceptions to this rule. Specifically, when the swapped argument is of integral type, an exact match is not always necessary. Implicit casts from other integral types are also accepted. Similarly, when dealing with floating\-point arguments, implicit casts between different floating\-point types are considered acceptable. .sp To avoid confusion, swaps where both swapped arguments are of integral types or both are of floating\-point types do not trigger the warning. In such cases, it\(aqs assumed that the developer intentionally used different integral or floating\-point types and does not raise a warning. This approach prevents false positives and provides flexibility in handling situations where varying integral or floating\-point types are intentionally utilized. .SS bugprone\-switch\-missing\-default\-case .sp Ensures that switch statements without default cases are flagged, focuses only on covering cases with non\-enums where the compiler may not issue warnings. .sp Switch statements without a default case can lead to unexpected behavior and incomplete handling of all possible cases. When a switch statement lacks a default case, if a value is encountered that does not match any of the specified cases, the switch statement will do nothing and the program will continue execution without handling the value. .sp This check helps identify switch statements that are missing a default case, allowing developers to ensure that all possible cases are handled properly. Adding a default case allows for graceful handling of unexpected or unmatched values, reducing the risk of program errors and unexpected behavior. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX // Example 1: // warning: switching on non\-enum value without default case may not cover all cases switch (i) { case 0: break; } // Example 2: enum E { eE1 }; E e = eE1; switch (e) { // no\-warning case eE1: break; } // Example 3: int i = 0; switch (i) { // no\-warning case 0: break; default: break; } .EE .UNINDENT .UNINDENT .sp \fBNote:\fP .INDENT 0.0 .INDENT 3.5 Enum types are already covered by compiler warnings (comes under \-Wswitch) when a switch statement does not handle all enum values. This check focuses on non\-enum types where the compiler warnings may not be present. .UNINDENT .UNINDENT .sp \fBSee also:\fP .INDENT 0.0 .INDENT 3.5 The CppCoreGuideline ES.79 \% provide guidelines on switch statements, including the recommendation to always provide a default case. .UNINDENT .UNINDENT .SS bugprone\-tagged\-union\-member\-count .sp Gives warnings for tagged unions, where the number of tags is different from the number of data members inside the union. .sp A struct or a class is considered to be a tagged union if it has exactly one union data member and exactly one enum data member and any number of other data members that are neither unions or enums. Furthermore, the types of the union and the enum members must not come from system header files nor the \fBstd\fP namespace. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX enum Tags { Tag1, Tag2, }; struct TaggedUnion { // warning: tagged union has more data members (3) than tags (2) enum Tags Kind; union { int I; float F; char *Str; } Data; }; .EE .UNINDENT .UNINDENT .sp The following example illustrates the exception for unions and enums from system header files and the \fBstd\fP namespace. .INDENT 0.0 .INDENT 3.5 .sp .EX #include struct NotTaggedUnion { enum MyEnum { MyEnumConstant1, MyEnumConstant2 } En; pthread_mutex_t Mutex; }; .EE .UNINDENT .UNINDENT .sp The \fBpthread_mutex_t\fP type may be defined as a union behind a \fBtypedef\fP, in which case the check could mistake this type as a user\-defined tagged union. After all, it has exactly one enum data member and exactly one union data member. To avoid false\-positive cases originating from this, unions and enums from system headers and the \fBstd\fP namespace are ignored when pinpointing the union part and the enum part of a potential user\-defined tagged union. .SS How enum constants are counted .sp The main complicating factor when counting the number of enum constants is that some of them might be auxiliary values that purposefully don\(aqt have a corresponding union data member and are used for something else. For example the last enum constant sometimes explicitly \(dqpoints to\(dq the last declared valid enum constant or tracks how many enum constants have been declared. .sp For an illustration: .INDENT 0.0 .INDENT 3.5 .sp .EX enum TagWithLast { Tag1 = 0, Tag2 = 1, Tag3 = 2, LastTag = 2 }; enum TagWithCounter { Tag1, // is 0 Tag2, // is 1 Tag3, // is 2 TagCount, // is 3 }; .EE .UNINDENT .UNINDENT .sp The check counts the number of distinct values among the enum constants and not the enum constants themselves. This way the enum constants that are essentially just aliases of other enum constants are not included in the final count. .sp Handling of counting enum constants (ones like \fBTagCount\fP in the previous code example) is done by decreasing the number of enum values by one if the name of the last enum constant starts with a prefix or ends with a suffix specified in \fBCountingEnumPrefixes\fP, \fBCountingEnumSuffixes\fP and it\(aqs value is one less than the total number of distinct values in the enum. .sp When the final count is adjusted based on this heuristic then a diagnostic note is emitted that shows which enum constant matched the criteria. .sp The heuristic can be disabled entirely (\fBEnableCountingEnumHeuristic\fP) or configured to follow your naming convention (\fBCountingEnumPrefixes\fP, \fBCountingEnumSuffixes\fP). The strings specified in \fBCountingEnumPrefixes\fP, \fBCountingEnumSuffixes\fP are matched case insensitively. .sp Example counts: .INDENT 0.0 .INDENT 3.5 .sp .EX // Enum count is 3, because the value 2 is counted only once enum TagWithLast { Tag1 = 0, Tag2 = 1, Tag3 = 2, LastTag = 2 }; // Enum count is 3, because TagCount is heuristically excluded enum TagWithCounter { Tag1, // is 0 Tag2, // is 1 Tag3, // is 2 TagCount, // is 3 }; .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B EnableCountingEnumHeuristic .UNINDENT .sp This option enables or disables the counting enum heuristic. It uses the prefixes and suffixes specified in the options \fBCountingEnumPrefixes\fP, \fBCountingEnumSuffixes\fP to find counting enum constants by using them for prefix and suffix matching. .sp This option is enabled by default. .sp When \fBEnableCountingEnumHeuristic\fP is \fIfalse\fP: .INDENT 0.0 .INDENT 3.5 .sp .EX enum TagWithCounter { Tag1, Tag2, Tag3, TagCount, }; struct TaggedUnion { TagWithCounter Kind; union { int A; long B; char *Str; float F; } Data; }; .EE .UNINDENT .UNINDENT .sp When \fBEnableCountingEnumHeuristic\fP is \fItrue\fP: .INDENT 0.0 .INDENT 3.5 .sp .EX enum TagWithCounter { Tag1, Tag2, Tag3, TagCount, }; struct TaggedUnion { // warning: tagged union has more data members (4) than tags (3) TagWithCounter Kind; union { int A; long B; char *Str; float F; } Data; }; .EE .UNINDENT .UNINDENT .INDENT 0.0 .TP .B CountingEnumPrefixes .UNINDENT .sp See \fBCountingEnumSuffixes\fP below. .INDENT 0.0 .TP .B CountingEnumSuffixes .UNINDENT .sp CountingEnumPrefixes and CountingEnumSuffixes are lists of semicolon separated strings that are used to search for possible counting enum constants. These strings are matched case insensitively as prefixes and suffixes respectively on the names of the enum constants. If \fBEnableCountingEnumHeuristic\fP is \fIfalse\fP then these options do nothing. .sp The default value of \fBCountingEnumSuffixes\fP is \fIcount\fP and of \fBCountingEnumPrefixes\fP is the empty string. .sp When \fBEnableCountingEnumHeuristic\fP is \fItrue\fP and \fBCountingEnumSuffixes\fP is \fIcount;size\fP: .INDENT 0.0 .INDENT 3.5 .sp .EX enum TagWithCounterCount { Tag1, Tag2, Tag3, TagCount, }; struct TaggedUnionCount { // warning: tagged union has more data members (4) than tags (3) TagWithCounterCount Kind; union { int A; long B; char *Str; float F; } Data; }; enum TagWithCounterSize { Tag11, Tag22, Tag33, TagSize, }; struct TaggedUnionSize { // warning: tagged union has more data members (4) than tags (3) TagWithCounterSize Kind; union { int A; long B; char *Str; float F; } Data; }; .EE .UNINDENT .UNINDENT .sp When \fBEnableCountingEnumHeuristic\fP is \fItrue\fP and \fBCountingEnumPrefixes\fP is \fImaxsize;last_\fP .INDENT 0.0 .INDENT 3.5 .sp .EX enum TagWithCounterLast { Tag1, Tag2, Tag3, last_tag, }; struct TaggedUnionLast { // warning: tagged union has more data members (4) than tags (3) TagWithCounterLast tag; union { int I; short S; char *C; float F; } Data; }; enum TagWithCounterMaxSize { Tag1, Tag2, Tag3, MaxSizeTag, }; struct TaggedUnionMaxSize { // warning: tagged union has more data members (4) than tags (3) TagWithCounterMaxSize tag; union { int I; short S; char *C; float F; } Data; }; .EE .UNINDENT .UNINDENT .INDENT 0.0 .TP .B StrictMode .UNINDENT .sp When enabled, the check will also give a warning, when the number of tags is greater than the number of union data members. .sp This option is disabled by default. .sp When \fBStrictMode\fP \%<#\:cmdoption-arg-StrictMode> is \fIfalse\fP: .INDENT 0.0 .INDENT 3.5 .sp .EX struct TaggedUnion { enum { Tag1, Tag2, Tag3, } Tags; union { int I; float F; } Data; }; .EE .UNINDENT .UNINDENT .sp When \fBStrictMode\fP \%<#\:cmdoption-arg-StrictMode> is \fItrue\fP: .INDENT 0.0 .INDENT 3.5 .sp .EX struct TaggedUnion { // warning: tagged union has fewer data members (2) than tags (3) enum { Tag1, Tag2, Tag3, } Tags; union { int I; float F; } Data; }; .EE .UNINDENT .UNINDENT .SS bugprone\-terminating\-continue .sp Detects \fBdo while\fP loops with a condition always evaluating to false that have a \fBcontinue\fP statement, as this \fBcontinue\fP terminates the loop effectively. .INDENT 0.0 .INDENT 3.5 .sp .EX void f() { do { // some code continue; // terminating continue // some other code } while(false); .EE .UNINDENT .UNINDENT .SS bugprone\-throw\-keyword\-missing .sp Warns about a potentially missing \fBthrow\fP keyword. If a temporary object is created, but the object\(aqs type derives from (or is the same as) a class that has \(aqEXCEPTION\(aq, \(aqException\(aq or \(aqexception\(aq in its name, we can assume that the programmer\(aqs intention was to throw that object. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX void f(int i) { if (i < 0) { // Exception is created but is not thrown. std::runtime_error(\(dqUnexpected argument\(dq); } } .EE .UNINDENT .UNINDENT .SS bugprone\-throwing\-static\-initialization .sp Finds all \fBstatic\fP or \fBthread_local\fP variable declarations where the initializer for the object may throw an exception. .SS References .sp This check corresponds to the CERT C++ Coding Standard rule ERR58\-CPP. Handle all exceptions thrown before main() begins executing \%\&. .SS bugprone\-too\-small\-loop\-variable .sp Detects those \fBfor\fP loops that have a loop variable with a \(dqtoo small\(dq type which means this type can\(aqt represent all values which are part of the iteration range. .INDENT 0.0 .INDENT 3.5 .sp .EX int main() { long size = 294967296l; for (short i = 0; i < size; ++i) {} } .EE .UNINDENT .UNINDENT .sp This \fBfor\fP loop is an infinite loop because the \fBshort\fP type can\(aqt represent all values in the \fB[0..size]\fP interval. .sp In a real use case size means a container\(aqs size which depends on the user input. .INDENT 0.0 .INDENT 3.5 .sp .EX int doSomething(const std::vector& items) { for (short i = 0; i < items.size(); ++i) {} } .EE .UNINDENT .UNINDENT .sp This algorithm works for a small amount of objects, but will lead to freeze for a larger user input. .sp It\(aqs recommended to enable the compiler warning \fI\-Wtautological\-constant\-out\-of\-range\-compare\fP as well, since check does not inspect compile\-time constant loop boundaries to avoid overlaps with the warning. .SS Options .INDENT 0.0 .TP .B MagnitudeBitsUpperLimit Upper limit for the magnitude bits of the loop variable. If it\(aqs set the check filters out those catches in which the loop variable\(aqs type has more magnitude bits as the specified upper limit. The default value is 16. For example, if the user sets this option to 31 (bits), then a 32\-bit \fBunsigned int\fP is ignored by the check, however a 32\-bit \fBint\fP is not (A 32\-bit \fBsigned int\fP has 31 magnitude bits). .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .EX int main() { long size = 294967296l; for (unsigned i = 0; i < size; ++i) {} // no warning with MagnitudeBitsUpperLimit = 31 on a system where unsigned is 32\-bit for (int i = 0; i < size; ++i) {} // warning with MagnitudeBitsUpperLimit = 31 on a system where int is 32\-bit } .EE .UNINDENT .UNINDENT .SS bugprone\-unchecked\-optional\-access .sp \fINote\fP: This check uses a flow\-sensitive static analysis to produce its results. Therefore, it may be more resource intensive (RAM, CPU) than the average clang\-tidy check. .sp This check identifies unsafe accesses to values contained in \fBstd::optional\fP, \fBabsl::optional\fP, \fBbase::Optional\fP, \fBfolly::Optional\fP, \fBbsl::optional\fP, or \fBBloombergLP::bdlb::NullableValue\fP objects. Below we will refer to all these types collectively as \fBoptional\fP\&. .sp An access to the value of an \fBoptional\fP occurs when one of its \fBvalue\fP, \fBoperator*\fP, or \fBoperator\->\fP member functions is invoked. To align with common misconceptions, the check considers these member functions as equivalent, even though there are subtle differences related to exceptions versus undefined behavior. See \fIAdditional notes\fP, below, for more information on this topic. .sp An access to the value of an \fBoptional\fP is considered safe if and only if code in the local scope (for example, a function body) ensures that the \fBoptional\fP has a value in all possible execution paths that can reach the access. That should happen either through an explicit check, using the \fBoptional::has_value\fP member function, or by constructing the \fBoptional\fP in a way that shows that it unambiguously holds a value (e.g using \fBstd::make_optional\fP which always returns a populated \fBstd::optional\fP). .sp Below we list some examples, starting with unsafe optional access patterns, followed by safe access patterns. .SS Unsafe access patterns .SS Access the value without checking if it exists .sp The check flags accesses to the value that are not locally guarded by existence check: .INDENT 0.0 .INDENT 3.5 .sp .EX void f(std::optional opt) { use(*opt); // unsafe: it is unclear whether \(gaopt\(ga has a value. } .EE .UNINDENT .UNINDENT .SS Access the value in the wrong branch .sp The check is aware of the state of an optional object in different branches of the code. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX void f(std::optional opt) { if (opt.has_value()) { } else { use(opt.value()); // unsafe: it is clear that \(gaopt\(ga does *not* have a value. } } .EE .UNINDENT .UNINDENT .SS Assume a function result to be stable .sp The check is aware that function results might not be stable. That is, consecutive calls to the same function might return different values. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX void f(Foo foo) { if (foo.take().has_value()) { use(*foo.take()); // unsafe: it is unclear whether \(gafoo.take()\(ga has a value. } } .EE .UNINDENT .UNINDENT .SS Exception: accessor methods .sp The check assumes \fIaccessor\fP methods of a class are stable, with a heuristic to determine which methods are accessors. Specifically, parameter\-free \fBconst\fP methods and smart pointer\-like APIs (non \fBconst\fP overloads of \fB*\fP when there is a parallel \fBconst\fP overload) are treated as accessors. Note that this is not guaranteed to be safe \-\- but, it is widely used (safely) in practice. Calls to non \fBconst\fP methods are assumed to modify the state of the object and affect the stability of earlier accessor calls. .SS Rely on invariants of uncommon APIs .sp The check is unaware of invariants of uncommon APIs. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX void f(Foo foo) { if (foo.HasProperty(\(dqbar\(dq)) { use(*foo.GetProperty(\(dqbar\(dq)); // unsafe: it is unclear whether \(gafoo.GetProperty(\(dqbar\(dq)\(ga has a value. } } .EE .UNINDENT .UNINDENT .SS Check if a value exists, then pass the optional to another function .sp The check relies on local reasoning. The check and value access must both happen in the same function. An access is considered unsafe even if the caller of the function performing the access ensures that the optional has a value. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX void g(std::optional opt) { use(*opt); // unsafe: it is unclear whether \(gaopt\(ga has a value. } void f(std::optional opt) { if (opt.has_value()) { g(opt); } } .EE .UNINDENT .UNINDENT .SS Safe access patterns .SS Check if a value exists, then access the value .sp The check recognizes all straightforward ways for checking if a value exists and accessing the value contained in an optional object. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX void f(std::optional opt) { if (opt.has_value()) { use(*opt); } } .EE .UNINDENT .UNINDENT .SS Check if a value exists, then access the value from a copy .sp The criteria that the check uses is semantic, not syntactic. It recognizes when a copy of the optional object being accessed is known to have a value. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX void f(std::optional opt1) { if (opt1.has_value()) { std::optional opt2 = opt1; use(*opt2); } } .EE .UNINDENT .UNINDENT .SS Ensure that a value exists using common macros .sp The check is aware of common macros like \fBCHECK\fP and \fBDCHECK\fP\&. Those can be used to ensure that an optional object has a value. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX void f(std::optional opt) { DCHECK(opt.has_value()); use(*opt); } .EE .UNINDENT .UNINDENT .SS Ensure that a value exists, then access the value in a correlated branch .sp The check is aware of correlated branches in the code and can figure out when an optional object is ensured to have a value on all execution paths that lead to an access. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX void f(std::optional opt) { bool safe = false; if (opt.has_value() && SomeOtherCondition()) { safe = true; } // ... more code... if (safe) { use(*opt); } } .EE .UNINDENT .UNINDENT .SS Stabilize function results .sp Function results are not assumed to be stable across calls, except for const accessor methods. For more complex accessors (non\-const, or depend on multiple params) it is best to store the result of the function call in a local variable and use that variable to access the value. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX void f(Foo foo) { if (const auto& foo_opt = foo.take(); foo_opt.has_value()) { use(*foo_opt); } } .EE .UNINDENT .UNINDENT .SS Do not rely on uncommon\-API invariants .sp When uncommon APIs guarantee that an optional has contents, do not rely on it \-\- instead, check explicitly that the optional object has a value. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX void f(Foo foo) { if (const auto& property = foo.GetProperty(\(dqbar\(dq)) { use(*property); } } .EE .UNINDENT .UNINDENT .sp instead of the \fIHasProperty\fP, \fIGetProperty\fP pairing we saw above. .SS Do not rely on caller\-performed checks .sp If you know that all of a function\(aqs callers have checked that an optional argument has a value, either change the function to take the value directly or check the optional again in the local scope of the callee. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX void g(int val) { use(val); } void f(std::optional opt) { if (opt.has_value()) { g(*opt); } } .EE .UNINDENT .UNINDENT .sp and .INDENT 0.0 .INDENT 3.5 .sp .EX struct S { std::optional opt; int x; }; void g(const S &s) { if (s.opt.has_value() && s.x > 10) { use(*s.opt); } void f(S s) { if (s.opt.has_value()) { g(s); } } .EE .UNINDENT .UNINDENT .SS Additional notes .SS Aliases created via \fBusing\fP declarations .sp The check is aware of aliases of optional types that are created via \fBusing\fP declarations. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX using OptionalInt = std::optional; void f(OptionalInt opt) { use(opt.value()); // unsafe: it is unclear whether \(gaopt\(ga has a value. } .EE .UNINDENT .UNINDENT .SS Lambdas .sp The check does not currently report unsafe optional accesses in lambdas. A future version will expand the scope to lambdas, following the rules outlined above. It is best to follow the same principles when using optionals in lambdas. .SS Access with \fBoperator*()\fP vs. \fBvalue()\fP .sp Given that \fBvalue()\fP has well\-defined behavior (either throwing an exception or terminating the program), why treat it the same as \fBoperator*()\fP which causes undefined behavior (UB)? That is, why is it considered unsafe to access an optional with \fBvalue()\fP, if it\(aqs not provably populated with a value? For that matter, why is \fBCHECK()\fP followed by \fBoperator*()\fP any better than \fBvalue()\fP, given that they are semantically equivalent (on configurations that disable exceptions)? .sp The answer is that we assume most users do not realize the difference between \fBvalue()\fP and \fBoperator*()\fP\&. Shifting to \fBoperator*()\fP and some form of explicit value\-presence check or explicit program termination has two advantages: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 Readability. The check, and any potential side effects like program shutdown, are very clear in the code. Separating access from checks can actually make the checks more obvious. .IP \(bu 2 Performance. A single check can cover many or even all accesses within scope. This gives the user the best of both worlds \-\- the safety of a dynamic check, but without incurring redundant costs. .UNINDENT .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IgnoreSmartPointerDereference If set to \fItrue\fP, the check ignores optionals that are reached through overloaded smart\-pointer\-like dereference (\fBoperator*\fP, \fBoperator\->\fP) on classes other than the optional type itself. This helps avoid false positives where the analysis cannot equate results across such calls. This does not cover access through \fBoperator[]\fP\&. Default is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B IgnoreValueCalls If set to \fItrue\fP, the check does not diagnose calls to \fBoptional::value()\fP\&. Diagnostics for \fBoperator*()\fP and \fBoperator\->()\fP remain enabled. This is useful for codebases that intentionally rely on \fBvalue()\fP for defined, guarded access while still flagging UB\-prone operator dereferences. Default is \fIfalse\fP\&. .UNINDENT .SS bugprone\-unchecked\-string\-to\-number\-conversion .sp This check flags calls to string\-to\-number conversion functions that do not verify the validity of the conversion, such as \fBatoi()\fP or \fBscanf()\fP\&. It does not flag calls to \fBstrtol()\fP, or other, related conversion functions that do perform better error checking. .INDENT 0.0 .INDENT 3.5 .sp .EX #include void func(const char *buff) { int si; if (buff) { si = atoi(buff); /* \(aqatoi\(aq used to convert a string to an integer, but function will not report conversion errors; consider using \(aqstrtol\(aq instead. */ } else { /* Handle error */ } } .EE .UNINDENT .UNINDENT .SS References .sp This check corresponds to the CERT C Coding Standard rule ERR34\-C. Detect errors when converting a string to a number \%\&. .SS bugprone\-undefined\-memory\-manipulation .sp Finds calls of memory manipulation functions \fBmemset()\fP, \fBmemcpy()\fP and \fBmemmove()\fP on non\-TriviallyCopyable objects resulting in undefined behavior. .sp Using memory manipulation functions on non\-TriviallyCopyable objects can lead to a range of subtle and challenging issues in C++ code. The most immediate concern is the potential for undefined behavior, where the state of the object may become corrupted or invalid. This can manifest as crashes, data corruption, or unexpected behavior at runtime, making it challenging to identify and diagnose the root cause. Additionally, misuse of memory manipulation functions can bypass essential object\-specific operations, such as constructors and destructors, leading to resource leaks or improper initialization. .sp For example, when using \fBmemcpy\fP to copy \fBstd::string\fP, pointer data is being copied, and it can result in a double free issue. .INDENT 0.0 .INDENT 3.5 .sp .EX #include #include int main() { std::string source = \(dqHello\(dq; std::string destination; std::memcpy(&destination, &source, sizeof(std::string)); // Undefined behavior may occur here, during std::string destructor call. return 0; } .EE .UNINDENT .UNINDENT .SS bugprone\-undelegated\-constructor .sp Finds creation of temporary objects in constructors that look like a function call to another constructor of the same class. .sp The user most likely meant to use a delegating constructor or base class initializer. .SS bugprone\-unhandled\-exception\-at\-new .sp Finds calls to \fBnew\fP with missing exception handler for \fBstd::bad_alloc\fP\&. .sp Calls to \fBnew\fP may throw exceptions of type \fBstd::bad_alloc\fP that should be handled. Alternatively, the nonthrowing form of \fBnew\fP can be used. The check verifies that the exception is handled in the function that calls \fBnew\fP\&. .sp If a nonthrowing version is used or the exception is allowed to propagate out of the function no warning is generated. .sp The exception handler is checked if it catches a \fBstd::bad_alloc\fP or \fBstd::exception\fP exception type, or all exceptions (catch\-all). The check assumes that any user\-defined \fBoperator new\fP is either \fBnoexcept\fP or may throw an exception of type \fBstd::bad_alloc\fP (or one derived from it). Other exception class types are not taken into account. .INDENT 0.0 .INDENT 3.5 .sp .EX int *f() noexcept { int *p = new int[1000]; // warning: missing exception handler for allocation failure at \(aqnew\(aq // ... return p; } .EE .UNINDENT .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .EX int *f1() { // not \(aqnoexcept\(aq int *p = new int[1000]; // no warning: exception can be handled outside // of this function // ... return p; } int *f2() noexcept { try { int *p = new int[1000]; // no warning: exception is handled // ... return p; } catch (std::bad_alloc &) { // ... } // ... } int *f3() noexcept { int *p = new (std::nothrow) int[1000]; // no warning: \(dqnothrow\(dq is used // ... return p; } .EE .UNINDENT .UNINDENT .SS bugprone\-unhandled\-self\-assignment .sp \fIcert\-oop54\-cpp\fP redirects here as an alias for this check. For the CERT alias, the \fIWarnOnlyIfThisHasSuspiciousField\fP option is set to \fIfalse\fP\&. .sp Finds user\-defined copy assignment operators which do not protect the code against self\-assignment either by checking self\-assignment explicitly or using the copy\-and\-swap or the copy\-and\-move method. .sp By default, this check searches only those classes which have any pointer or C array field to avoid false positives. In case of a pointer or a C array, it\(aqs likely that self\-copy assignment breaks the object if the copy assignment operator was not written with care. .sp See also: OOP54\-CPP. Gracefully handle self\-copy assignment \% .sp A copy assignment operator must prevent that self\-copy assignment ruins the object state. A typical use case is when the class has a pointer field and the copy assignment operator first releases the pointed object and then tries to assign it: .INDENT 0.0 .INDENT 3.5 .sp .EX class T { int* p; public: T(const T &rhs) : p(rhs.p ? new int(*rhs.p) : nullptr) {} ~T() { delete p; } // ... T& operator=(const T &rhs) { delete p; p = new int(*rhs.p); return *this; } }; .EE .UNINDENT .UNINDENT .sp There are two common C++ patterns to avoid this problem. The first is the self\-assignment check: .INDENT 0.0 .INDENT 3.5 .sp .EX class T { int* p; public: T(const T &rhs) : p(rhs.p ? new int(*rhs.p) : nullptr) {} ~T() { delete p; } // ... T& operator=(const T &rhs) { if(this == &rhs) return *this; delete p; p = new int(*rhs.p); return *this; } }; .EE .UNINDENT .UNINDENT .sp The second one is the copy\-and\-swap method when we create a temporary copy (using the copy constructor) and then swap this temporary object with \fBthis\fP: .INDENT 0.0 .INDENT 3.5 .sp .EX class T { int* p; public: T(const T &rhs) : p(rhs.p ? new int(*rhs.p) : nullptr) {} ~T() { delete p; } // ... void swap(T &rhs) { using std::swap; swap(p, rhs.p); } T& operator=(const T &rhs) { T(rhs).swap(*this); return *this; } }; .EE .UNINDENT .UNINDENT .sp There is a third pattern which is less common. Let\(aqs call it the copy\-and\-move method when we create a temporary copy (using the copy constructor) and then move this temporary object into \fBthis\fP (needs a move assignment operator): .INDENT 0.0 .INDENT 3.5 .sp .EX class T { int* p; public: T(const T &rhs) : p(rhs.p ? new int(*rhs.p) : nullptr) {} ~T() { delete p; } // ... T& operator=(const T &rhs) { T t = rhs; *this = std::move(t); return *this; } T& operator=(T &&rhs) { p = rhs.p; rhs.p = nullptr; return *this; } }; .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B WarnOnlyIfThisHasSuspiciousField When \fItrue\fP, the check will warn only if the container class of the copy assignment operator has any suspicious fields (pointer, C array and C++ smart pointer). This option is set to \fItrue\fP by default. .UNINDENT .SS bugprone\-unintended\-char\-ostream\-output .sp Finds unintended character output from \fBunsigned char\fP and \fBsigned char\fP to an \fBostream\fP\&. .sp Normally, when \fBunsigned char (uint8_t)\fP or \fBsigned char (int8_t)\fP is used, it is more likely a number than a character. However, when it is passed directly to \fBstd::ostream\fP\(aqs \fBoperator<<\fP, the result is the character output instead of the numeric value. This often contradicts the developer\(aqs intent to print integer values. .INDENT 0.0 .INDENT 3.5 .sp .EX uint8_t v = 65; std::cout << v; // output \(aqA\(aq instead of \(aq65\(aq .EE .UNINDENT .UNINDENT .sp The check will suggest casting the value to an appropriate type to indicate the intent, by default, it will cast to \fBunsigned int\fP for \fBunsigned char\fP and \fBint\fP for \fBsigned char\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .EX std::cout << static_cast(v); // when v is unsigned char std::cout << static_cast(v); // when v is signed char .EE .UNINDENT .UNINDENT .sp To avoid lengthy cast statements, add prefix \fB+\fP to the variable can also suppress warnings because unary expression will promote the value to an \fBint\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .EX std::cout << +v; .EE .UNINDENT .UNINDENT .sp Or cast to char to explicitly indicate that output should be a character. .INDENT 0.0 .INDENT 3.5 .sp .EX std::cout << static_cast(v); .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B AllowedTypes A semicolon\-separated list of type names that will be treated like the \fBchar\fP type: the check will not report variables declared with with these types or explicit cast expressions to these types. Note that this distinguishes type aliases from the original type, so specifying e.g. \fBunsigned char\fP here will not suppress reports about \fBuint8_t\fP even if it is defined as a \fBtypedef\fP alias for \fBunsigned char\fP\&. Default is \fIunsigned char;signed char\fP\&. .UNINDENT .INDENT 0.0 .TP .B CastTypeName When \fICastTypeName\fP is specified, the fix\-it will use \fICastTypeName\fP as the cast target type. Otherwise, fix\-it will automatically infer the type. .UNINDENT .SS bugprone\-unique\-ptr\-array\-mismatch .sp Finds initializations of C++ unique pointers to non\-array type that are initialized with an array. .sp If a pointer \fBstd::unique_ptr\fP is initialized with a new\-expression \fBnew T[]\fP the memory is not deallocated correctly. A plain \fBdelete\fP is used in this case to deallocate the target memory. Instead a \fBdelete[]\fP call is needed. A \fBstd::unique_ptr\fP uses the correct delete operator. The check does not emit warning if an \fBunique_ptr\fP with user\-specified deleter type is used. .sp The check offers replacement of \fBunique_ptr\fP to \fBunique_ptr\fP if it is used at a single variable declaration (one variable in one statement). .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX std::unique_ptr x(new Foo[10]); // \-> std::unique_ptr x(new Foo[10]); // ^ warning: unique pointer to non\-array is initialized with array std::unique_ptr x1(new Foo), x2(new Foo[10]); // no replacement // ^ warning: unique pointer to non\-array is initialized with array D d; std::unique_ptr x3(new Foo[10], d); // no warning (custom deleter used) struct S { std::unique_ptr x(new Foo[10]); // no replacement in this case // ^ warning: unique pointer to non\-array is initialized with array }; .EE .UNINDENT .UNINDENT .sp This check partially covers the CERT C++ Coding Standard rule MEM51\-CPP. Properly deallocate dynamically allocated resources \% However, only the \fBstd::unique_ptr\fP case is detected by this check. .SS bugprone\-unsafe\-functions .sp Checks for functions that have safer, more secure replacements available, or are considered deprecated due to design flaws. The check heavily relies on the functions from the \fBAnnex K.\fP \(dqBounds\-checking interfaces\(dq of C11. .INDENT 0.0 .TP .B The check implements the following rules from the CERT C Coding Standard: .INDENT 7.0 .IP \(bu 2 Recommendation MSC24\-C. Do not use deprecated or obsolescent functions \%\&. .IP \(bu 2 Rule MSC33\-C. Do not pass invalid data to the asctime() function \%\&. .UNINDENT .UNINDENT .sp \fIcert\-msc24\-c\fP and \fIcert\-msc33\-c\fP redirect here as aliases of this check. .SS Unsafe functions .sp The following functions are reported if \fBReportDefaultFunctions\fP is enabled. .sp If \fIAnnex K.\fP is available, a replacement from \fIAnnex K.\fP is suggested for the following functions: .sp \fBasctime\fP, \fBasctime_r\fP, \fBbsearch\fP, \fBctime\fP, \fBfopen\fP, \fBfprintf\fP, \fBfreopen\fP, \fBfscanf\fP, \fBfwprintf\fP, \fBfwscanf\fP, \fBgetenv\fP, \fBgets\fP, \fBgmtime\fP, \fBlocaltime\fP, \fBmbsrtowcs\fP, \fBmbstowcs\fP, \fBmemcpy\fP, \fBmemmove\fP, \fBmemset\fP, \fBprintf\fP, \fBqsort\fP, \fBscanf\fP, \fBsnprintf\fP, \fBsprintf\fP, \fBsscanf\fP, \fBstrcat\fP, \fBstrcpy\fP, \fBstrerror\fP, \fBstrlen\fP, \fBstrncat\fP, \fBstrncpy\fP, \fBstrtok\fP, \fBswprintf\fP, \fBswscanf\fP, \fBvfprintf\fP, \fBvfscanf\fP, \fBvfwprintf\fP, \fBvfwscanf\fP, \fBvprintf\fP, \fBvscanf\fP, \fBvsnprintf\fP, \fBvsprintf\fP, \fBvsscanf\fP, \fBvswprintf\fP, \fBvswscanf\fP, \fBvwprintf\fP, \fBvwscanf\fP, \fBwcrtomb\fP, \fBwcscat\fP, \fBwcscpy\fP, \fBwcslen\fP, \fBwcsncat\fP, \fBwcsncpy\fP, \fBwcsrtombs\fP, \fBwcstok\fP, \fBwcstombs\fP, \fBwctomb\fP, \fBwmemcpy\fP, \fBwmemmove\fP, \fBwprintf\fP, \fBwscanf\fP\&. .sp If \fIAnnex K.\fP is not available, replacements are suggested only for the following functions from the previous list: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fBasctime\fP, \fBasctime_r\fP, suggested replacement: \fBstrftime\fP .IP \(bu 2 \fBgets\fP, suggested replacement: \fBfgets\fP .UNINDENT .UNINDENT .UNINDENT .sp The following functions are always checked, regardless of \fIAnnex K\fP availability: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fBrewind\fP, suggested replacement: \fBfseek\fP .IP \(bu 2 \fBsetbuf\fP, suggested replacement: \fBsetvbuf\fP .UNINDENT .UNINDENT .UNINDENT .sp If \fBReportMoreUnsafeFunctions\fP is enabled, the following functions are also checked: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fBbcmp\fP, suggested replacement: \fBmemcmp\fP .IP \(bu 2 \fBbcopy\fP, suggested replacement: \fBmemcpy_s\fP if \fIAnnex K\fP is available, or \fBmemcpy\fP .IP \(bu 2 \fBbzero\fP, suggested replacement: \fBmemset_s\fP if \fIAnnex K\fP is available, or \fBmemset\fP .IP \(bu 2 \fBgetpw\fP, suggested replacement: \fBgetpwuid\fP .IP \(bu 2 \fBvfork\fP, suggested replacement: \fBposix_spawn\fP .UNINDENT .UNINDENT .UNINDENT .sp Although mentioned in the associated CERT rules, the following functions are \fBignored\fP by the check: .sp \fBatof\fP, \fBatoi\fP, \fBatol\fP, \fBatoll\fP, \fBtmpfile\fP\&. .sp The availability of \fIAnnex K\fP is determined based on the following macros: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fB__STDC_LIB_EXT1__\fP: feature macro, which indicates the presence of \fIAnnex K. \(dqBounds\-checking interfaces\(dq\fP in the library implementation .IP \(bu 2 \fB__STDC_WANT_LIB_EXT1__\fP: user\-defined macro, which indicates that the user requests the functions from \fIAnnex K.\fP to be defined. .UNINDENT .UNINDENT .UNINDENT .sp Both macros have to be defined to suggest replacement functions from \fIAnnex K.\fP \fB__STDC_LIB_EXT1__\fP is defined by the library implementation, and \fB__STDC_WANT_LIB_EXT1__\fP must be defined to \fB1\fP by the user \fBbefore\fP including any system headers. .SS Custom functions .sp The option \fBCustomFunctions\fP allows the user to define custom functions to be checked. The format is the following, without newlines: .INDENT 0.0 .INDENT 3.5 .sp .EX bugprone\-unsafe\-functions.CustomFunctions=\(dq functionRegex1[, replacement1[, reason1]]; functionRegex2[, replacement2[, reason2]]; ... \(dq .EE .UNINDENT .UNINDENT .sp The functions are matched using POSIX extended regular expressions. \fI(Note: The regular expressions do not support negative\fP \fB(?!)\fP \fImatches.)\fP .sp The \fIreason\fP is optional and is used to provide additional information about the reasoning behind the replacement. The default reason is \fIis marked as unsafe\fP\&. .sp If \fIreplacement\fP is empty, the default text \fIit should not be used\fP will be shown instead of the suggestion for a replacement. .sp If the \fIreason\fP starts with the character \fI>\fP, the reason becomes fully custom. The default suffix is disabled even if a \fIreplacement\fP is present, and only the reason message is shown after the matched function, to allow better control over the suggestions. (The starting \fI>\fP and whitespace directly after it are trimmed from the message.) .sp As an example, the following configuration matches only the function \fBoriginal\fP in the default namespace. A similar diagnostic can also be printed using a fully custom reason. .INDENT 0.0 .INDENT 3.5 .sp .EX // bugprone\-unsafe\-functions.CustomFunctions: // ^original$, replacement, is deprecated; // Using the fully custom message syntax: // ^suspicious$,,> should be avoided if possible. original(); // warning: function \(aqoriginal\(aq is deprecated; \(aqreplacement\(aq should be used instead. suspicious(); // warning: function \(aqsuspicious\(aq should be avoided if possible. ::std::original(); // no\-warning original_function(); // no\-warning .EE .UNINDENT .UNINDENT .sp If the regular expression contains the character \fI:\fP, it is matched against the qualified name (i.e. \fBstd::original\fP), otherwise the regex is matched against the unqualified name (\fBoriginal\fP). If the regular expression starts with \fI::\fP (or \fI^::\fP), it is matched against the fully qualified name (\fB::std::original\fP). .sp One of the use cases for fully custom messages is suggesting compiler options and warning flags: .INDENT 0.0 .INDENT 3.5 .sp .EX // bugprone\-unsafe\-functions.CustomFunctions: // ^memcpy$,,>is recommended to have compiler hardening using \(aq_FORTIFY_SOURCE\(aq; // ^printf$,,>is recommended to have the \(aq\-Werror=format\-security\(aq compiler warning flag; memcpy(dest, src, 999\(aq999); // warning: function \(aqmemcpy\(aq is recommended to have compiler hardening using \(aq_FORTIFY_SOURCE\(aq printf(raw_str); // warning: function \(aqprintf\(aq is recommended to have the \(aq\-Werror=format\-security\(aq compiler warning flag .EE .UNINDENT .UNINDENT .sp \fBNote:\fP .INDENT 0.0 .INDENT 3.5 Fully qualified names can contain template parameters on certain C++ classes, but not on C++ functions. Type aliases are resolved before matching. .sp As an example, the member function \fBopen\fP in the class \fBstd::ifstream\fP has a fully qualified name of \fB::std::basic_ifstream::open\fP\&. .sp The example could also be matched with the regex \fB::std::basic_ifstream<[^>]*>::open\fP, which matches all potential template parameters, but does not match nested template classes. .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B ReportMoreUnsafeFunctions When \fItrue\fP, additional functions from widely used APIs (such as POSIX) are added to the list of reported functions. See the main documentation of the check for the complete list as to what this option enables. Default is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B ReportDefaultFunctions When \fItrue\fP, the check reports the default set of functions. Consider changing the setting to false if you only want to see custom functions matched via custom functions\&. Default is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B CustomFunctions A semicolon\-separated list of custom functions to be matched. A matched function contains a regular expression, an optional name of the replacement function, and an optional reason, separated by comma. For more information, see Custom functions\&. .UNINDENT .SS Examples .INDENT 0.0 .INDENT 3.5 .sp .EX #ifndef __STDC_LIB_EXT1__ #error \(dqAnnex K is not supported by the current standard library implementation.\(dq #endif #define __STDC_WANT_LIB_EXT1__ 1 #include // Defines functions from Annex K. #include enum { BUFSIZE = 32 }; void Unsafe(const char *Msg) { static const char Prefix[] = \(dqError: \(dq; static const char Suffix[] = \(dq\en\(dq; char Buf[BUFSIZE] = {0}; strcpy(Buf, Prefix); // warning: function \(aqstrcpy\(aq is not bounds\-checking; \(aqstrcpy_s\(aq should be used instead. strcat(Buf, Msg); // warning: function \(aqstrcat\(aq is not bounds\-checking; \(aqstrcat_s\(aq should be used instead. strcat(Buf, Suffix); // warning: function \(aqstrcat\(aq is not bounds\-checking; \(aqstrcat_s\(aq should be used instead. if (fputs(buf, stderr) < 0) { // error handling return; } } void UsingSafeFunctions(const char *Msg) { static const char Prefix[] = \(dqError: \(dq; static const char Suffix[] = \(dq\en\(dq; char Buf[BUFSIZE] = {0}; if (strcpy_s(Buf, BUFSIZE, Prefix) != 0) { // error handling return; } if (strcat_s(Buf, BUFSIZE, Msg) != 0) { // error handling return; } if (strcat_s(Buf, BUFSIZE, Suffix) != 0) { // error handling return; } if (fputs(Buf, stderr) < 0) { // error handling return; } } .EE .UNINDENT .UNINDENT .SS bugprone\-unused\-local\-non\-trivial\-variable .sp Warns when a local non trivial variable is unused within a function. The following types of variables are excluded from this check: .INDENT 0.0 .IP \(bu 2 trivial and trivially copyable .IP \(bu 2 references and pointers .IP \(bu 2 exception variables in catch clauses .IP \(bu 2 static or thread local .IP \(bu 2 structured bindings .IP \(bu 2 variables with \fB[[maybe_unused]]\fP attribute .IP \(bu 2 name\-independent variables .UNINDENT .sp This check can be configured to warn on all non\-trivial variables by setting \fIIncludeTypes\fP to \fI\&.*\fP, and excluding specific types using \fIExcludeTypes\fP\&. .sp In the this example, \fImy_lock\fP would generate a warning that it is unused. .INDENT 0.0 .INDENT 3.5 .sp .EX std::mutex my_lock; // my_lock local variable is never used .EE .UNINDENT .UNINDENT .sp In the next example, \fIfuture2\fP would generate a warning that it is unused. .INDENT 0.0 .INDENT 3.5 .sp .EX std::future future1; std::future future2; // ... MyObject foo = future1.get(); // future2 is not used. .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IncludeTypes Semicolon\-separated list of regular expressions matching types of variables to check. By default the following types are checked: .INDENT 7.0 .IP \(bu 2 \fI::std::.*mutex\fP .IP \(bu 2 \fI::std::future\fP .IP \(bu 2 \fI::std::basic_string\fP .IP \(bu 2 \fI::std::basic_regex\fP .IP \(bu 2 \fI::std::basic_istringstream\fP .IP \(bu 2 \fI::std::basic_stringstream\fP .IP \(bu 2 \fI::std::bitset\fP .IP \(bu 2 \fI::std::filesystem::path\fP .UNINDENT .UNINDENT .INDENT 0.0 .TP .B ExcludeTypes A semicolon\-separated list of regular expressions matching types that are excluded from the \fIIncludeTypes\fP matches. By default it is an empty list. .UNINDENT .SS bugprone\-unused\-raii .sp Finds temporaries that look like RAII objects. .sp The canonical example for this is a scoped lock. .INDENT 0.0 .INDENT 3.5 .sp .EX { scoped_lock(&global_mutex); critical_section(); } .EE .UNINDENT .UNINDENT .sp The destructor of the scoped_lock is called before the \fBcritical_section\fP is entered, leaving it unprotected. .sp We apply a number of heuristics to reduce the false positive count of this check: .INDENT 0.0 .IP \(bu 2 Ignore code expanded from macros. Testing frameworks make heavy use of this. .IP \(bu 2 Ignore types with trivial destructors. They are very unlikely to be RAII objects and there\(aqs no difference when they are deleted. .IP \(bu 2 Ignore objects at the end of a compound statement (doesn\(aqt change behavior). .IP \(bu 2 Ignore objects returned from a call. .UNINDENT .SS bugprone\-unused\-return\-value .sp Warns on unused function return values. The checked functions can be configured. .sp Operator overloading with assignment semantics are ignored. .SS Options .INDENT 0.0 .TP .B CheckedFunctions Semicolon\-separated list of functions to check. This parameter supports regexp. The function is checked if the name and scope matches, with any arguments. By default the following functions are checked: \fB^::std::async$, ^::std::launder$, ^::std::remove$, ^::std::remove_if$, ^::std::unique$, ^::std::unique_ptr::release$, ^::std::basic_string::empty$, ^::std::vector::empty$, ^::std::back_inserter$, ^::std::distance$, ^::std::find$, ^::std::find_if$, ^::std::inserter$, ^::std::lower_bound$, ^::std::make_pair$, ^::std::map::count$, ^::std::map::find$, ^::std::map::lower_bound$, ^::std::multimap::equal_range$, ^::std::multimap::upper_bound$, ^::std::set::count$, ^::std::set::find$, ^::std::setfill$, ^::std::setprecision$, ^::std::setw$, ^::std::upper_bound$, ^::std::vector::at$, ^::bsearch$, ^::ferror$, ^::feof$, ^::isalnum$, ^::isalpha$, ^::isblank$, ^::iscntrl$, ^::isdigit$, ^::isgraph$, ^::islower$, ^::isprint$, ^::ispunct$, ^::isspace$, ^::isupper$, ^::iswalnum$, ^::iswprint$, ^::iswspace$, ^::isxdigit$, ^::memchr$, ^::memcmp$, ^::strcmp$, ^::strcoll$, ^::strncmp$, ^::strpbrk$, ^::strrchr$, ^::strspn$, ^::strstr$, ^::wcscmp$, ^::access$, ^::bind$, ^::connect$, ^::difftime$, ^::dlsym$, ^::fnmatch$, ^::getaddrinfo$, ^::getopt$, ^::htonl$, ^::htons$, ^::iconv_open$, ^::inet_addr$, isascii$, isatty$, ^::mmap$, ^::newlocale$, ^::openat$, ^::pathconf$, ^::pthread_equal$, ^::pthread_getspecific$, ^::pthread_mutex_trylock$, ^::readdir$, ^::readlink$, ^::recvmsg$, ^::regexec$, ^::scandir$, ^::semget$, ^::setjmp$, ^::shm_open$, ^::shmget$, ^::sigismember$, ^::strcasecmp$, ^::strsignal$, ^::ttyname$\fP .INDENT 7.0 .IP \(bu 2 \fBstd::async()\fP\&. Not using the return value makes the call synchronous. .IP \(bu 2 \fBstd::launder()\fP\&. Not using the return value usually means that the function interface was misunderstood by the programmer. Only the returned pointer is \(dqlaundered\(dq, not the argument. .IP \(bu 2 \fBstd::remove()\fP, \fBstd::remove_if()\fP and \fBstd::unique()\fP\&. The returned iterator indicates the boundary between elements to keep and elements to be removed. Not using the return value means that the information about which elements to remove is lost. .IP \(bu 2 \fBstd::unique_ptr::release()\fP\&. Not using the return value can lead to resource leaks if the same pointer isn\(aqt stored anywhere else. Often, ignoring the \fBrelease()\fP return value indicates that the programmer confused the function with \fBreset()\fP\&. .IP \(bu 2 \fBstd::basic_string::empty()\fP and \fBstd::vector::empty()\fP\&. Not using the return value often indicates that the programmer confused the function with \fBclear()\fP\&. .UNINDENT .UNINDENT .INDENT 0.0 .TP .B CheckedReturnTypes Semicolon\-separated list of function return types to check. By default the following function return types are checked: \fI^::std::error_code$\fP, \fI^::std::error_condition$\fP, \fI^::std::errc$\fP, \fI^::std::expected$\fP, \fI^::boost::system::error_code$\fP .UNINDENT .INDENT 0.0 .TP .B AllowCastToVoid Controls whether casting return values to \fBvoid\fP is permitted. Default: \fIfalse\fP\&. .UNINDENT .sp cert\-err33\-c \%<> is an alias of this check that checks a fixed and large set of standard library functions. .SS bugprone\-use\-after\-move .sp Warns if an object is used after it has been moved, for example: .INDENT 0.0 .INDENT 3.5 .sp .EX std::string str = \(dqHello, world!\en\(dq; std::vector messages; messages.emplace_back(std::move(str)); std::cout << str; .EE .UNINDENT .UNINDENT .sp The last line will trigger a warning that \fBstr\fP is used after it has been moved. .sp The check does not trigger a warning if the object is reinitialized after the move and before the use. For example, no warning will be output for this code: .INDENT 0.0 .INDENT 3.5 .sp .EX messages.emplace_back(std::move(str)); str = \(dqGreetings, stranger!\en\(dq; std::cout << str; .EE .UNINDENT .UNINDENT .sp Subsections below explain more precisely what exactly the check considers to be a move, use, and reinitialization. .sp The check takes control flow into account. A warning is only emitted if the use can be reached from the move. This means that the following code does not produce a warning: .INDENT 0.0 .INDENT 3.5 .sp .EX if (condition) { messages.emplace_back(std::move(str)); } else { std::cout << str; } .EE .UNINDENT .UNINDENT .sp On the other hand, the following code does produce a warning: .INDENT 0.0 .INDENT 3.5 .sp .EX for (int i = 0; i < 10; ++i) { std::cout << str; messages.emplace_back(std::move(str)); } .EE .UNINDENT .UNINDENT .sp (The use\-after\-move happens on the second iteration of the loop.) .sp In some cases, the check may not be able to detect that two branches are mutually exclusive. For example (assuming that \fBi\fP is an int): .INDENT 0.0 .INDENT 3.5 .sp .EX if (i == 1) { messages.emplace_back(std::move(str)); } if (i == 2) { std::cout << str; } .EE .UNINDENT .UNINDENT .sp In this case, the check will erroneously produce a warning, even though it is not possible for both the move and the use to be executed. More formally, the analysis is flow\-sensitive but not path\-sensitive \%\&. .SS Silencing erroneous warnings .sp An erroneous warning can be silenced by reinitializing the object after the move: .INDENT 0.0 .INDENT 3.5 .sp .EX if (i == 1) { messages.emplace_back(std::move(str)); str = \(dq\(dq; } if (i == 2) { std::cout << str; } .EE .UNINDENT .UNINDENT .sp If you want to avoid the overhead of actually reinitializing the object, you can create a dummy function that causes the check to assume the object was reinitialized: .INDENT 0.0 .INDENT 3.5 .sp .EX template void IS_INITIALIZED(T&) {} .EE .UNINDENT .UNINDENT .sp You can use this as follows: .INDENT 0.0 .INDENT 3.5 .sp .EX if (i == 1) { messages.emplace_back(std::move(str)); } if (i == 2) { IS_INITIALIZED(str); std::cout << str; } .EE .UNINDENT .UNINDENT .sp The check will not output a warning in this case because passing the object to a function as a non\-const pointer or reference counts as a reinitialization (see section Reinitialization below). .SS Unsequenced moves, uses, and reinitializations .sp In many cases, C++ does not make any guarantees about the order in which sub\-expressions of a statement are evaluated. This means that in code like the following, it is not guaranteed whether the use will happen before or after the move: .INDENT 0.0 .INDENT 3.5 .sp .EX void f(int i, std::vector v); std::vector v = { 1, 2, 3 }; f(v[1], std::move(v)); .EE .UNINDENT .UNINDENT .sp In this kind of situation, the check will note that the use and move are unsequenced. .sp The check will also take sequencing rules into account when reinitializations occur in the same statement as moves or uses. A reinitialization is only considered to reinitialize a variable if it is guaranteed to be evaluated after the move and before the use. .SS Move .sp The check currently only considers calls of \fBstd::move\fP on local variables or function parameters. It does not check moves of member variables or global variables. .sp Any call of \fBstd::move\fP on a variable is considered to cause a move of that variable, even if the result of \fBstd::move\fP is not passed to an rvalue reference parameter. .sp This means that the check will flag a use\-after\-move even on a type that does not define a move constructor or move assignment operator. This is intentional. Developers may use \fBstd::move\fP on such a type in the expectation that the type will add move semantics in the future. If such a \fBstd::move\fP has the potential to cause a use\-after\-move, we want to warn about it even if the type does not implement move semantics yet. .sp Furthermore, if the result of \fBstd::move\fP \fIis\fP passed to an rvalue reference parameter, this will always be considered to cause a move, even if the function that consumes this parameter does not move from it, or if it does so only conditionally. For example, in the following situation, the check will assume that a move always takes place: .INDENT 0.0 .INDENT 3.5 .sp .EX std::vector messages; void f(std::string &&str) { // Only remember the message if it isn\(aqt empty. if (!str.empty()) { messages.emplace_back(std::move(str)); } } std::string str = \(dq\(dq; f(std::move(str)); .EE .UNINDENT .UNINDENT .sp The check will assume that the last line causes a move, even though, in this particular case, it does not. Again, this is intentional. .sp There is one special case: A call to \fBstd::move\fP inside a \fBtry_emplace\fP call is conservatively assumed not to move. This is to avoid spurious warnings, as the check has no way to reason about the \fBbool\fP returned by \fBtry_emplace\fP\&. .sp When analyzing the order in which moves, uses and reinitializations happen (see section Unsequenced moves, uses, and reinitializations), the move is assumed to occur in whichever function the result of the \fBstd::move\fP is passed to. .sp The check also handles perfect\-forwarding with \fBstd::forward\fP so the following code will also trigger a use\-after\-move warning. .INDENT 0.0 .INDENT 3.5 .sp .EX void consume(int); void f(int&& i) { consume(std::forward(i)); consume(std::forward(i)); // use\-after\-move } .EE .UNINDENT .UNINDENT .SS Use .sp Any occurrence of the moved variable that is not a reinitialization (see below) is considered to be a use. .sp An exception to this are objects of type \fBstd::unique_ptr\fP, \fBstd::shared_ptr\fP, \fBstd::weak_ptr\fP, \fBstd::optional\fP, and \fBstd::any\fP\&. An exception to this are objects of type \fBstd::unique_ptr\fP, \fBstd::shared_ptr\fP, \fBstd::weak_ptr\fP, \fBstd::optional\fP, and \fBstd::any\fP, which can be reinitialized via \fBreset\fP\&. For smart pointers specifically, the moved\-from objects have a well\-defined state of being \fBnullptr\(ga\(gas, and only \(ga\(gaoperator*\fP, \fBoperator\->\fP and \fBoperator[]\fP are considered bad accesses as they would be dereferencing a \fBnullptr\fP\&. .sp If multiple uses occur after a move, only the first of these is flagged. .SS Reinitialization .sp The check considers a variable to be reinitialized in the following cases: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 The variable occurs on the left\-hand side of an assignment. .IP \(bu 2 The variable is passed to a function as a non\-const pointer or non\-const lvalue reference. (It is assumed that the variable may be an out\-parameter for the function.) .IP \(bu 2 \fBclear()\fP or \fBassign()\fP is called on the variable and the variable is of one of the standard container types \fBbasic_string\fP, \fBvector\fP, \fBdeque\fP, \fBforward_list\fP, \fBlist\fP, \fBset\fP, \fBmap\fP, \fBmultiset\fP, \fBmultimap\fP, \fBunordered_set\fP, \fBunordered_map\fP, \fBunordered_multiset\fP, \fBunordered_multimap\fP\&. .IP \(bu 2 \fBreset()\fP is called on the variable and the variable is of type \fBstd::unique_ptr\fP, \fBstd::shared_ptr\fP, \fBstd::weak_ptr\fP, \fBstd::optional\fP, or \fBstd::any\fP\&. .IP \(bu 2 A member function marked with the \fB[[clang::reinitializes]]\fP attribute is called on the variable. .UNINDENT .UNINDENT .UNINDENT .sp If the variable in question is a struct and an individual member variable of that struct is written to, the check does not consider this to be a reinitialization \-\- even if, eventually, all member variables of the struct are written to. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX struct S { std::string str; int i; }; S s = { \(dqHello, world!\en\(dq, 42 }; S s_other = std::move(s); s.str = \(dqLorem ipsum\(dq; s.i = 99; .EE .UNINDENT .UNINDENT .sp The check will not consider \fBs\fP to be reinitialized after the last line; instead, the line that assigns to \fBs.str\fP will be flagged as a use\-after\-move. This is intentional as this pattern of reinitializing a struct is error\-prone. For example, if an additional member variable is added to \fBS\fP, it is easy to forget to add the reinitialization for this additional member. Instead, it is safer to assign to the entire struct in one go, and this will also avoid the use\-after\-move warning. .SS Options .INDENT 0.0 .TP .B InvalidationFunctions A semicolon\-separated list of regular expressions matching names of functions that cause their first arguments to be invalidated (e.g., closing a handle). For member functions, the first argument is considered to be the implicit object argument (\fBthis\fP). Default value is an empty string. .UNINDENT .INDENT 0.0 .TP .B ReinitializationFunctions A semicolon\-separated list of regular expressions matching names of functions that reinitialize the object. For member functions, the implicit object argument (\fB*this\fP) is considered to be reinitialized. For non\-member or static member functions, the first argument is considered to be reinitialized. Default value is an empty string. .UNINDENT .SS bugprone\-virtual\-near\-miss .sp Warn if a function is a near miss (i.e. the name is very similar and the function signature is the same) to a virtual function from a base class. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX struct Base { virtual void func(); }; struct Derived : Base { virtual void funk(); // warning: \(aqDerived::funk\(aq has a similar name and the same signature as virtual method \(aqBase::func\(aq; did you mean to override it? }; .EE .UNINDENT .UNINDENT .SS cert\-arr39\-c .sp The \fIcert\-arr39\-c\fP check is an alias, please see bugprone\-sizeof\-expression \%<> for more information. .SS cert\-con36\-c .sp The \fIcert\-con36\-c\fP check is an alias, please see bugprone\-spuriously\-wake\-up\-functions \%<> for more information. .SS cert\-con54\-cpp .sp The \fIcert\-con54\-cpp\fP check is an alias, please see bugprone\-spuriously\-wake\-up\-functions \%<> for more information. .SS cert\-ctr56\-cpp .sp The \fIcert\-ctr56\-cpp\fP check is an alias, please see bugprone\-pointer\-arithmetic\-on\-polymorphic\-object \%<> for more information. .SS cert\-dcl03\-c .sp The \fIcert\-dcl03\-c\fP check is an alias, please see misc\-static\-assert \%<> for more information. .SS cert\-dcl16\-c .sp The \fIcert\-dcl16\-c\fP check is an alias, please see readability\-uppercase\-literal\-suffix \%<> for more information. .SS cert\-dcl37\-c .sp The \fIcert\-dcl37\-c\fP check is an alias, please see bugprone\-reserved\-identifier \%<> for more information. .SS cert\-dcl50\-cpp .sp The \fIcert\-dcl50\-cpp\fP check is an alias, please see modernize\-avoid\-variadic\-functions \%<> for more information. .sp This check corresponds to the CERT C++ Coding Standard rule DCL50\-CPP. Do not define a C\-style variadic function \%\&. .SS cert\-dcl51\-cpp .sp The \fIcert\-dcl51\-cpp\fP check is an alias, please see bugprone\-reserved\-identifier \%<> for more information. .SS cert\-dcl54\-cpp .sp The \fIcert\-dcl54\-cpp\fP check is an alias, please see misc\-new\-delete\-overloads \%<> for more information. .SS cert\-dcl58\-cpp .sp The \fIcert\-dcl58\-cpp\fP is an alias, please see bugprone\-std\-namespace\-modification \%<> for more information. .sp This check corresponds to the CERT C++ Coding Standard rule DCL58\-CPP. Do not modify the standard namespaces \%\&. .SS cert\-dcl59\-cpp .sp The \fIcert\-dcl59\-cpp\fP check is an alias, please see misc\-anonymous\-namespace\-in\-header \%<> for more information. .SS cert\-env33\-c .sp The \fIcert\-env33\-c\fP check is an alias, please see bugprone\-command\-processor \%<> for more information. .sp This check corresponds to the CERT C Coding Standard rule ENV33\-C. Do not call system() \%\&. .SS cert\-err09\-cpp .sp The \fIcert\-err09\-cpp\fP check is an alias, please see misc\-throw\-by\-value\-catch\-by\-reference \%<> for more information. .sp This check corresponds to the CERT C++ Coding Standard recommendation ERR09\-CPP. Throw anonymous temporaries. However, all of the CERT recommendations have been removed from public view, and so their justification for the behavior of this check requires an account on their wiki to view. .SS cert\-err33\-c .sp Warns on unused function return values. Many of the standard library functions return a value that indicates if the call was successful. Ignoring the returned value can cause unexpected behavior if an error has occurred. The following functions are checked: .INDENT 0.0 .IP \(bu 2 aligned_alloc() .IP \(bu 2 asctime_s() .IP \(bu 2 at_quick_exit() .IP \(bu 2 atexit() .IP \(bu 2 bsearch() .IP \(bu 2 bsearch_s() .IP \(bu 2 btowc() .IP \(bu 2 c16rtomb() .IP \(bu 2 c32rtomb() .IP \(bu 2 calloc() .IP \(bu 2 clock() .IP \(bu 2 cnd_broadcast() .IP \(bu 2 cnd_init() .IP \(bu 2 cnd_signal() .IP \(bu 2 cnd_timedwait() .IP \(bu 2 cnd_wait() .IP \(bu 2 ctime_s() .IP \(bu 2 fclose() .IP \(bu 2 fflush() .IP \(bu 2 fgetc() .IP \(bu 2 fgetpos() .IP \(bu 2 fgets() .IP \(bu 2 fgetwc() .IP \(bu 2 fopen() .IP \(bu 2 fopen_s() .IP \(bu 2 fprintf() .IP \(bu 2 fprintf_s() .IP \(bu 2 fputc() .IP \(bu 2 fputs() .IP \(bu 2 fputwc() .IP \(bu 2 fputws() .IP \(bu 2 fread() .IP \(bu 2 freopen() .IP \(bu 2 freopen_s() .IP \(bu 2 fscanf() .IP \(bu 2 fscanf_s() .IP \(bu 2 fseek() .IP \(bu 2 fsetpos() .IP \(bu 2 ftell() .IP \(bu 2 fwprintf() .IP \(bu 2 fwprintf_s() .IP \(bu 2 fwrite() .IP \(bu 2 fwscanf() .IP \(bu 2 fwscanf_s() .IP \(bu 2 getc() .IP \(bu 2 getchar() .IP \(bu 2 getenv() .IP \(bu 2 getenv_s() .IP \(bu 2 gets_s() .IP \(bu 2 getwc() .IP \(bu 2 getwchar() .IP \(bu 2 gmtime() .IP \(bu 2 gmtime_s() .IP \(bu 2 localtime() .IP \(bu 2 localtime_s() .IP \(bu 2 malloc() .IP \(bu 2 mbrtoc16() .IP \(bu 2 mbrtoc32() .IP \(bu 2 mbsrtowcs() .IP \(bu 2 mbsrtowcs_s() .IP \(bu 2 mbstowcs() .IP \(bu 2 mbstowcs_s() .IP \(bu 2 memchr() .IP \(bu 2 mktime() .IP \(bu 2 mtx_init() .IP \(bu 2 mtx_lock() .IP \(bu 2 mtx_timedlock() .IP \(bu 2 mtx_trylock() .IP \(bu 2 mtx_unlock() .IP \(bu 2 printf_s() .IP \(bu 2 putc() .IP \(bu 2 putwc() .IP \(bu 2 raise() .IP \(bu 2 realloc() .IP \(bu 2 remove() .IP \(bu 2 rename() .IP \(bu 2 setlocale() .IP \(bu 2 setvbuf() .IP \(bu 2 scanf() .IP \(bu 2 scanf_s() .IP \(bu 2 signal() .IP \(bu 2 snprintf() .IP \(bu 2 snprintf_s() .IP \(bu 2 sprintf() .IP \(bu 2 sprintf_s() .IP \(bu 2 sscanf() .IP \(bu 2 sscanf_s() .IP \(bu 2 strchr() .IP \(bu 2 strerror_s() .IP \(bu 2 strftime() .IP \(bu 2 strpbrk() .IP \(bu 2 strrchr() .IP \(bu 2 strstr() .IP \(bu 2 strtod() .IP \(bu 2 strtof() .IP \(bu 2 strtoimax() .IP \(bu 2 strtok() .IP \(bu 2 strtok_s() .IP \(bu 2 strtol() .IP \(bu 2 strtold() .IP \(bu 2 strtoll() .IP \(bu 2 strtoumax() .IP \(bu 2 strtoul() .IP \(bu 2 strtoull() .IP \(bu 2 strxfrm() .IP \(bu 2 swprintf() .IP \(bu 2 swprintf_s() .IP \(bu 2 swscanf() .IP \(bu 2 swscanf_s() .IP \(bu 2 thrd_create() .IP \(bu 2 thrd_detach() .IP \(bu 2 thrd_join() .IP \(bu 2 thrd_sleep() .IP \(bu 2 time() .IP \(bu 2 timespec_get() .IP \(bu 2 tmpfile() .IP \(bu 2 tmpfile_s() .IP \(bu 2 tmpnam() .IP \(bu 2 tmpnam_s() .IP \(bu 2 tss_create() .IP \(bu 2 tss_get() .IP \(bu 2 tss_set() .IP \(bu 2 ungetc() .IP \(bu 2 ungetwc() .IP \(bu 2 vfprintf() .IP \(bu 2 vfprintf_s() .IP \(bu 2 vfscanf() .IP \(bu 2 vfscanf_s() .IP \(bu 2 vfwprintf() .IP \(bu 2 vfwprintf_s() .IP \(bu 2 vfwscanf() .IP \(bu 2 vfwscanf_s() .IP \(bu 2 vprintf_s() .IP \(bu 2 vscanf() .IP \(bu 2 vscanf_s() .IP \(bu 2 vsnprintf() .IP \(bu 2 vsnprintf_s() .IP \(bu 2 vsprintf() .IP \(bu 2 vsprintf_s() .IP \(bu 2 vsscanf() .IP \(bu 2 vsscanf_s() .IP \(bu 2 vswprintf() .IP \(bu 2 vswprintf_s() .IP \(bu 2 vswscanf() .IP \(bu 2 vswscanf_s() .IP \(bu 2 vwprintf_s() .IP \(bu 2 vwscanf() .IP \(bu 2 vwscanf_s() .IP \(bu 2 wcrtomb() .IP \(bu 2 wcschr() .IP \(bu 2 wcsftime() .IP \(bu 2 wcspbrk() .IP \(bu 2 wcsrchr() .IP \(bu 2 wcsrtombs() .IP \(bu 2 wcsrtombs_s() .IP \(bu 2 wcsstr() .IP \(bu 2 wcstod() .IP \(bu 2 wcstof() .IP \(bu 2 wcstoimax() .IP \(bu 2 wcstok() .IP \(bu 2 wcstok_s() .IP \(bu 2 wcstol() .IP \(bu 2 wcstold() .IP \(bu 2 wcstoll() .IP \(bu 2 wcstombs() .IP \(bu 2 wcstombs_s() .IP \(bu 2 wcstoumax() .IP \(bu 2 wcstoul() .IP \(bu 2 wcstoull() .IP \(bu 2 wcsxfrm() .IP \(bu 2 wctob() .IP \(bu 2 wctrans() .IP \(bu 2 wctype() .IP \(bu 2 wmemchr() .IP \(bu 2 wprintf_s() .IP \(bu 2 wscanf() .IP \(bu 2 wscanf_s() .UNINDENT .sp This check is an alias of check bugprone\-unused\-return\-value \%<> with a fixed set of functions. .sp Suppressing issues by casting to \fBvoid\fP is enabled by default and can be disabled by setting \fIAllowCastToVoid\fP option to \fIfalse\fP\&. .sp The check corresponds to a part of CERT C Coding Standard rule ERR33\-C. Detect and handle standard library errors \%\&. The list of checked functions is taken from the rule, with following exception: .INDENT 0.0 .IP \(bu 2 The check can not differentiate if a function is called with \fBNULL\fP argument. Therefore the following functions are not checked: \fBmblen\fP, \fBmbrlen\fP, \fBmbrtowc\fP, \fBmbtowc\fP, \fBwctomb\fP, \fBwctomb_s\fP .UNINDENT .SS cert\-err34\-c .sp The cert\-err34\-c check is an alias, please see bugprone\-unchecked\-string\-to\-number\-conversion \%<> for more information. .SS cert\-err52\-cpp .sp The \fIcert\-err52\-cpp\fP check is an alias, please see modernize\-avoid\-setjmp\-longjmp \%<> for more information. .sp This check corresponds to the CERT C++ Coding Standard rule ERR52\-CPP. Do not use setjmp() or longjmp() \%\&. .SS cert\-err58\-cpp .sp The \fIcert\-err58\-cpp\fP check is an alias, please see bugprone\-throwing\-static\-initialization \%<> for more information. .sp This check corresponds to the CERT C++ Coding Standard rule ERR58\-CPP. Handle all exceptions thrown before main() begins executing \%\&. .SS cert\-err60\-cpp .sp The \fIcert\-err60\-cpp\fP check is an alias, please see bugprone\-exception\-copy\-constructor\-throws \%<> for more information. .sp This check corresponds to the CERT C++ Coding Standard rule ERR60\-CPP. Exception objects must be nothrow copy constructible \%\&. .SS cert\-err61\-cpp .sp The \fIcert\-err61\-cpp\fP check is an alias, please see misc\-throw\-by\-value\-catch\-by\-reference \%<> for more information. .SS cert\-exp42\-c .sp The \fIcert\-exp42\-c\fP check is an alias, please see bugprone\-suspicious\-memory\-comparison \%<> for more information. .SS cert\-fio38\-c .sp The \fIcert\-fio38\-c\fP check is an alias, please see misc\-non\-copyable\-objects \%<> for more information. .sp This check corresponds to CERT C++ Coding Standard rule FIO38\-C. Do not copy a FILE object \%\&. .SS cert\-flp30\-c .sp The \fIcert\-flp30\-c\fP check is an alias, please see bugprone\-float\-loop\-counter \%<> for more information .sp This check corresponds to the CERT C Coding Standard rule FLP30\-C. Do not use floating\-point variables as loop counters \%\&. .SS cert\-flp37\-c .sp The \fIcert\-flp37\-c\fP check is an alias, please see bugprone\-suspicious\-memory\-comparison \%<> for more information. .SS cert\-int09\-c .sp The \fIcert\-int09\-c\fP check is an alias, please see readability\-enum\-initial\-value \%<> for more information. .SS cert\-mem57\-cpp .sp The \fIcert\-mem57\-cpp\fP is an alias, please see bugprone\-default\-operator\-new\-on\-overaligned\-type \%<> for more information. .sp This check corresponds to the CERT C++ Coding Standard rule MEM57\-CPP. Avoid using default operator new for over\-aligned types \%\&. .SS cert\-msc24\-c .sp The \fIcert\-msc24\-c\fP check is an alias, please see bugprone\-unsafe\-functions \%<> for more information. .SS cert\-msc30\-c .sp The \fIcert\-msc30\-c\fP check is an alias, please see misc\-predictable\-rand \%<> for more information. .sp This check corresponds to the CERT C Coding Standard rule MSC30\-C. Do not use the rand() function for generating pseudorandom numbers \%\&. .SS cert\-msc32\-c .sp The \fIcert\-msc32\-c\fP check is an alias, please see bugprone\-random\-generator\-seed \%<> for more information. .sp This check corresponds to the CERT C Coding Standard rule MSC32\-C. Properly seed pseudorandom number generators \%\&. .SS cert\-msc33\-c .sp The \fIcert\-msc33\-c\fP check is an alias, please see bugprone\-unsafe\-functions \%<> for more information. .SS cert\-msc50\-cpp .sp The \fIcert\-msc50\-cpp\fP check is an alias, please see misc\-predictable\-rand \%<> for more information. .sp This check corresponds to the CERT C Coding Standard rule MSC50\-CPP. Do not use std::rand() for generating pseudorandom numbers \%\&. .SS cert\-msc51\-cpp .sp The \fIcert\-msc51\-cpp\fP check is an alias, please see bugprone\-random\-generator\-seed \%<> for more information. .sp This check corresponds to the CERT C++ Coding Standard rule MSC51\-CPP. Ensure your random number generator is properly seeded \%\&. .SS cert\-msc54\-cpp .sp The \fIcert\-msc54\-cpp\fP check is an alias, please see bugprone\-signal\-handler \%<> for more information. .SS cert\-oop11\-cpp .sp The \fIcert\-oop11\-cpp check\fP is an alias, please see performance\-move\-constructor\-init \%<> for more information. .sp This check corresponds to the CERT C++ Coding Standard recommendation OOP11\-CPP. Do not copy\-initialize members or base classes from a move constructor. However, all of the CERT recommendations have been removed from public view, and so their justification for the behavior of this check requires an account on their wiki to view. .SS cert\-oop54\-cpp .sp The \fIcert\-oop54\-cpp\fP check is an alias, please see bugprone\-unhandled\-self\-assignment \%<> for more information. .SS cert\-oop57\-cpp .sp The \fIcert\-oop57\-cpp\fP check is an alias, please see bugprone\-raw\-memory\-call\-on\-non\-trivial\-type \%<> for more information. .sp This check corresponds to the CERT C++ Coding Standard rule OOP57\-CPP. Prefer special member functions and overloaded operators to C Standard Library functions \%\&. .SS cert\-oop58\-cpp .sp The \fIcert\-oop58\-cpp\fP check is an alias, please see bugprone\-copy\-constructor\-mutates\-argument \%<> for more information. .SS cert\-pos44\-c .sp The \fIcert\-pos44\-c\fP check is an alias, please see bugprone\-bad\-signal\-to\-kill\-thread \%<> for more information. .SS cert\-pos47\-c .sp The \fIcert\-pos47\-c\fP check is an alias, please see concurrency\-thread\-canceltype\-asynchronous \%<> for more information. .SS cert\-sig30\-c .sp The \fIcert\-sig30\-c\fP check is an alias, please see bugprone\-signal\-handler \%<> for more information. .SS cert\-str34\-c .sp The \fIcert\-str34\-c\fP check is an alias, please see bugprone\-signed\-char\-misuse \%<> for more information. .SS clang\-analyzer\-core.BitwiseShift .sp Finds cases where bitwise shift operation causes undefined behaviour. .sp The \fIclang\-analyzer\-core.BitwiseShift\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-core.CallAndMessage .sp Check for logical errors for function calls and Objective\-C message expressions (e.g., uninitialized arguments, null function pointers). .sp The \fIclang\-analyzer\-core.CallAndMessage\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-core.DivideZero .sp Check for division by zero. .sp The \fIclang\-analyzer\-core.DivideZero\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-core.NonNullParamChecker .sp Check for null pointers passed as arguments to a function whose arguments are references or marked with the \(aqnonnull\(aq attribute. .sp The \fIclang\-analyzer\-core.NonNullParamChecker\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-core.NullDereference .sp Check for dereferences of null pointers. .sp The \fIclang\-analyzer\-core.NullDereference\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-core.StackAddressEscape .sp Check that addresses to stack memory do not escape the function. .sp The \fIclang\-analyzer\-core.StackAddressEscape\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-core.UndefinedBinaryOperatorResult .sp Check for undefined results of binary operators. .sp The \fIclang\-analyzer\-core.UndefinedBinaryOperatorResult\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-core.VLASize .sp Check for declarations of VLA of undefined or zero size. .sp The \fIclang\-analyzer\-core.VLASize\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-core.uninitialized.ArraySubscript .sp Check for uninitialized values used as array subscripts. .sp The \fIclang\-analyzer\-core.uninitialized.ArraySubscript\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-core.uninitialized.Assign .sp Check for assigning uninitialized values. .sp The \fIclang\-analyzer\-core.uninitialized.Assign\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-core.uninitialized.Branch .sp Check for uninitialized values used as branch conditions. .sp The \fIclang\-analyzer\-core.uninitialized.Branch\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-core.uninitialized.CapturedBlockVariable .sp Check for blocks that capture uninitialized values. .sp The \fIclang\-analyzer\-core.uninitialized.CapturedBlockVariable\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-core.uninitialized.NewArraySize .sp Check if the size of the array in a new[] expression is undefined. .sp The \fIclang\-analyzer\-core.uninitialized.NewArraySize\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-core.uninitialized.UndefReturn .sp Check for uninitialized values being returned to the caller. .sp The \fIclang\-analyzer\-core.uninitialized.UndefReturn\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-cplusplus.ArrayDelete .sp Reports destructions of arrays of polymorphic objects that are destructed as their base class. .sp The \fIclang\-analyzer\-cplusplus.ArrayDelete\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-cplusplus.InnerPointer .sp Check for inner pointers of C++ containers used after re/deallocation. .sp The \fIclang\-analyzer\-cplusplus.InnerPointer\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-cplusplus.Move .sp Find use\-after\-move bugs in C++. .sp The \fIclang\-analyzer\-cplusplus.Move\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-cplusplus.NewDelete .sp Check for double\-free and use\-after\-free problems. Traces memory managed by new/delete. .sp The \fIclang\-analyzer\-cplusplus.NewDelete\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-cplusplus.NewDeleteLeaks .sp Check for memory leaks. Traces memory managed by new/delete. .sp The \fIclang\-analyzer\-cplusplus.NewDeleteLeaks\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-cplusplus.PlacementNew .sp Check if default placement new is provided with pointers to sufficient storage capacity. .sp The \fIclang\-analyzer\-cplusplus.PlacementNew\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-cplusplus.SelfAssignment .sp Checks C++ copy and move assignment operators for self assignment. .sp The \fIclang\-analyzer\-cplusplus.SelfAssignment\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-cplusplus.StringChecker .sp Checks C++ std::string bugs. .sp The \fIclang\-analyzer\-cplusplus.StringChecker\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-deadcode.DeadStores .sp Check for values stored to variables that are never read afterwards. .sp The \fIclang\-analyzer\-deadcode.DeadStores\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-fuchsia.HandleChecker .sp A Checker that detect leaks related to Fuchsia handles. .sp The \fIclang\-analyzer\-fuchsia.HandleChecker\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-nullability.NullPassedToNonnull .sp Warns when a null pointer is passed to a pointer which has a _Nonnull type. .sp The \fIclang\-analyzer\-nullability.NullPassedToNonnull\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-nullability.NullReturnedFromNonnull .sp Warns when a null pointer is returned from a function that has _Nonnull return type. .sp The \fIclang\-analyzer\-nullability.NullReturnedFromNonnull\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-nullability.NullableDereferenced .sp Warns when a nullable pointer is dereferenced. .sp The \fIclang\-analyzer\-nullability.NullableDereferenced\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-nullability.NullablePassedToNonnull .sp Warns when a nullable pointer is passed to a pointer which has a _Nonnull type. .sp The \fIclang\-analyzer\-nullability.NullablePassedToNonnull\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-nullability.NullableReturnedFromNonnull .sp Warns when a nullable pointer is returned from a function that has _Nonnull return type. .sp The \fIclang\-analyzer\-nullability.NullableReturnedFromNonnull\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-optin.core.EnumCastOutOfRange .sp Check integer to enumeration casts for out of range values. .sp The \fIclang\-analyzer\-optin.core.EnumCastOutOfRange\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-optin.cplusplus.UninitializedObject .sp Reports uninitialized fields after object construction. .sp The \fIclang\-analyzer\-optin.cplusplus.UninitializedObject\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-optin.cplusplus.VirtualCall .sp Check virtual function calls during construction/destruction. .sp The \fIclang\-analyzer\-optin.cplusplus.VirtualCall\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-optin.mpi.MPI\-Checker .sp Checks MPI code. .sp The \fIclang\-analyzer\-optin.mpi.MPI\-Checker\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-optin.osx.cocoa.localizability.EmptyLocalizationContextChecker .sp Check that NSLocalizedString macros include a comment for context. .sp The \fIclang\-analyzer\-optin.osx.cocoa.localizability.EmptyLocalizationContextChecker\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-optin.osx.cocoa.localizability.NonLocalizedStringChecker .sp Warns about uses of non\-localized NSStrings passed to UI methods expecting localized NSStrings. .sp The \fIclang\-analyzer\-optin.osx.cocoa.localizability.NonLocalizedStringChecker\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-optin.performance.GCDAntipattern .sp Check for performance anti\-patterns when using Grand Central Dispatch. .sp The \fIclang\-analyzer\-optin.performance.GCDAntipattern\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-optin.performance.Padding .sp Check for excessively padded structs. .sp The \fIclang\-analyzer\-optin.performance.Padding\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-optin.portability.UnixAPI .sp Finds implementation\-defined behavior in UNIX/Posix functions. .sp The \fIclang\-analyzer\-optin.portability.UnixAPI\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-optin.taint.TaintedAlloc .sp Check for memory allocations, where the size parameter might be a tainted (attacker controlled) value. .sp The \fIclang\-analyzer\-optin.taint.TaintedAlloc\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-osx.API .sp Check for proper uses of various Apple APIs. .sp The \fIclang\-analyzer\-osx.API\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-osx.NumberObjectConversion .sp Check for erroneous conversions of objects representing numbers into numbers. .sp The \fIclang\-analyzer\-osx.NumberObjectConversion\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-osx.ObjCProperty .sp Check for proper uses of Objective\-C properties. .sp The \fIclang\-analyzer\-osx.ObjCProperty\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-osx.SecKeychainAPI .sp Check for proper uses of Secure Keychain APIs. .sp The \fIclang\-analyzer\-osx.SecKeychainAPI\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-osx.cocoa.AtSync .sp Check for nil pointers used as mutexes for @synchronized. .sp The \fIclang\-analyzer\-osx.cocoa.AtSync\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-osx.cocoa.AutoreleaseWrite .sp Warn about potentially crashing writes to autoreleasing objects from different autoreleasing pools in Objective\-C. .sp The \fIclang\-analyzer\-osx.cocoa.AutoreleaseWrite\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-osx.cocoa.ClassRelease .sp Check for sending \(aqretain\(aq, \(aqrelease\(aq, or \(aqautorelease\(aq directly to a Class. .sp The \fIclang\-analyzer\-osx.cocoa.ClassRelease\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-osx.cocoa.Dealloc .sp Warn about Objective\-C classes that lack a correct implementation of \-dealloc. .sp The \fIclang\-analyzer\-osx.cocoa.Dealloc\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-osx.cocoa.IncompatibleMethodTypes .sp Warn about Objective\-C method signatures with type incompatibilities. .sp The \fIclang\-analyzer\-osx.cocoa.IncompatibleMethodTypes\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-osx.cocoa.Loops .sp Improved modeling of loops using Cocoa collection types. .sp The \fIclang\-analyzer\-osx.cocoa.Loops\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-osx.cocoa.MissingSuperCall .sp Warn about Objective\-C methods that lack a necessary call to super. .sp The \fIclang\-analyzer\-osx.cocoa.MissingSuperCall\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-osx.cocoa.NSAutoreleasePool .sp Warn for suboptimal uses of NSAutoreleasePool in Objective\-C GC mode. .sp The \fIclang\-analyzer\-osx.cocoa.NSAutoreleasePool\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-osx.cocoa.NSError .sp Check usage of NSError** parameters. .sp The \fIclang\-analyzer\-osx.cocoa.NSError\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-osx.cocoa.NilArg .sp Check for prohibited nil arguments to ObjC method calls. .sp The \fIclang\-analyzer\-osx.cocoa.NilArg\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-osx.cocoa.NonNilReturnValue .sp Model the APIs that are guaranteed to return a non\-nil value. .sp The \fIclang\-analyzer\-osx.cocoa.NonNilReturnValue\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-osx.cocoa.ObjCGenerics .sp Check for type errors when using Objective\-C generics. .sp The \fIclang\-analyzer\-osx.cocoa.ObjCGenerics\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-osx.cocoa.RetainCount .sp Check for leaks and improper reference count management. .sp The \fIclang\-analyzer\-osx.cocoa.RetainCount\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-osx.cocoa.RunLoopAutoreleaseLeak .sp Check for leaked memory in autorelease pools that will never be drained. .sp The \fIclang\-analyzer\-osx.cocoa.RunLoopAutoreleaseLeak\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-osx.cocoa.SelfInit .sp Check that \(aqself\(aq is properly initialized inside an initializer method. .sp The \fIclang\-analyzer\-osx.cocoa.SelfInit\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-osx.cocoa.SuperDealloc .sp Warn about improper use of \(aq[super dealloc]\(aq in Objective\-C. .sp The \fIclang\-analyzer\-osx.cocoa.SuperDealloc\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-osx.cocoa.UnusedIvars .sp Warn about private ivars that are never used. .sp The \fIclang\-analyzer\-osx.cocoa.UnusedIvars\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-osx.cocoa.VariadicMethodTypes .sp Check for passing non\-Objective\-C types to variadic collection initialization methods that expect only Objective\-C types. .sp The \fIclang\-analyzer\-osx.cocoa.VariadicMethodTypes\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-osx.coreFoundation.CFError .sp Check usage of CFErrorRef* parameters. .sp The \fIclang\-analyzer\-osx.coreFoundation.CFError\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-osx.coreFoundation.CFNumber .sp Check for proper uses of CFNumber APIs. .sp The \fIclang\-analyzer\-osx.coreFoundation.CFNumber\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-osx.coreFoundation.CFRetainRelease .sp Check for null arguments to CFRetain/CFRelease/CFMakeCollectable. .sp The \fIclang\-analyzer\-osx.coreFoundation.CFRetainRelease\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-osx.coreFoundation.containers.OutOfBounds .sp Checks for index out\-of\-bounds when using \(aqCFArray\(aq API. .sp The \fIclang\-analyzer\-osx.coreFoundation.containers.OutOfBounds\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-osx.coreFoundation.containers.PointerSizedValues .sp Warns if \(aqCFArray\(aq, \(aqCFDictionary\(aq, \(aqCFSet\(aq are created with non\-pointer\-size values. .sp The \fIclang\-analyzer\-osx.coreFoundation.containers.PointerSizedValues\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-security.FloatLoopCounter .sp Warn on using a floating point value as a loop counter (CERT: FLP30\-C, FLP30\-CPP). .sp The \fIclang\-analyzer\-security.FloatLoopCounter\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-security.PutenvStackArray .sp Finds calls to the putenv function which pass a pointer to a stack\-allocated (automatic) array as the argument. Function putenv does not copy the passed string, only a pointer to the data is stored and this data can be read even by other threads. Content of a stack\-allocated array is likely to be overwritten after exiting from the function. .sp The \fIclang\-analyzer\-security.PutenvStackArray\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-security.SetgidSetuidOrder .sp The checker checks for sequences of \fBsetuid(getuid())\fP and \fBsetgid(getgid())\fP calls (in this order). If such a sequence is found and there is no other privilege\-changing function call (\fBseteuid\fP, \fBsetreuid\fP, \fBsetresuid\fP and the GID versions of these) in between, a warning is generated. The checker finds only exactly \fBsetuid(getuid())\fP calls (and the GID versions), not for example if the result of \fBgetuid()\fP is stored in a variable. .sp The \fIclang\-analyzer\-security.SetgidSetuidOrder\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-security.cert.env.InvalidPtr .sp Finds usages of possibly invalidated pointers. .sp The \fIclang\-analyzer\-security.cert.env.InvalidPtr\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-security.insecureAPI.DeprecatedOrUnsafeBufferHandling .sp Warn on uses of unsecure or deprecated buffer manipulating functions. .sp The \fIclang\-analyzer\-security.insecureAPI.DeprecatedOrUnsafeBufferHandling\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-security.insecureAPI.UncheckedReturn .sp Warn on uses of functions whose return values must be always checked. .sp The \fIclang\-analyzer\-security.insecureAPI.UncheckedReturn\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-security.insecureAPI.bcmp .sp Warn on uses of the \(aqbcmp\(aq function. .sp The \fIclang\-analyzer\-security.insecureAPI.bcmp\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-security.insecureAPI.bcopy .sp Warn on uses of the \(aqbcopy\(aq function. .sp The \fIclang\-analyzer\-security.insecureAPI.bcopy\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-security.insecureAPI.bzero .sp Warn on uses of the \(aqbzero\(aq function. .sp The \fIclang\-analyzer\-security.insecureAPI.bzero\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-security.insecureAPI.decodeValueOfObjCType .sp Warn on uses of the \(aq\-decodeValueOfObjCType:at:\(aq method. .sp The \fIclang\-analyzer\-security.insecureAPI.decodeValueOfObjCType\fP check is an alias, please see Clang Static Analyzer security.insecureAPI.decodeValueOfObjCType \% for more information. .SS clang\-analyzer\-security.insecureAPI.getpw .sp Warn on uses of the \(aqgetpw\(aq function. .sp The \fIclang\-analyzer\-security.insecureAPI.getpw\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-security.insecureAPI.gets .sp Warn on uses of the \(aqgets\(aq function. .sp The \fIclang\-analyzer\-security.insecureAPI.gets\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-security.insecureAPI.mkstemp .sp Warn when \(aqmkstemp\(aq is passed fewer than 6 X\(aqs in the format string. .sp The \fIclang\-analyzer\-security.insecureAPI.mkstemp\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-security.insecureAPI.mktemp .sp Warn on uses of the \(aqmktemp\(aq function. .sp The \fIclang\-analyzer\-security.insecureAPI.mktemp\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-security.insecureAPI.rand .sp Warn on uses of the \(aqrand\(aq, \(aqrandom\(aq, and related functions. .sp The \fIclang\-analyzer\-security.insecureAPI.rand\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-security.insecureAPI.strcpy .sp Warn on uses of the \(aqstrcpy\(aq and \(aqstrcat\(aq functions. .sp The \fIclang\-analyzer\-security.insecureAPI.strcpy\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-security.insecureAPI.vfork .sp Warn on uses of the \(aqvfork\(aq function. .sp The \fIclang\-analyzer\-security.insecureAPI.vfork\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-unix.API .sp Check calls to various UNIX/Posix functions. .sp The \fIclang\-analyzer\-unix.API\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-unix.BlockInCriticalSection .sp Check for calls to blocking functions inside a critical section. .sp The \fIclang\-analyzer\-unix.BlockInCriticalSection\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-unix.Errno .sp Check for improper use of \(aqerrno\(aq. .sp The \fIclang\-analyzer\-unix.Errno\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-unix.Malloc .sp Check for memory leaks, double free, and use\-after\-free problems. Traces memory managed by malloc()/free(). .sp The \fIclang\-analyzer\-unix.Malloc\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-unix.MallocSizeof .sp Check for dubious malloc arguments involving sizeof. .sp The \fIclang\-analyzer\-unix.MallocSizeof\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-unix.MismatchedDeallocator .sp Check for mismatched deallocators. .sp The \fIclang\-analyzer\-unix.MismatchedDeallocator\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-unix.StdCLibraryFunctions .sp Check for invalid arguments of C standard library functions, and apply relations between arguments and return value. .sp The \fIclang\-analyzer\-unix.StdCLibraryFunctions\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-unix.Stream .sp Check stream handling functions. .sp The \fIclang\-analyzer\-unix.Stream\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-unix.Vfork .sp Check for proper usage of vfork. .sp The \fIclang\-analyzer\-unix.Vfork\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-unix.cstring.BadSizeArg .sp Check the size argument passed into C string functions for common erroneous patterns. .sp The \fIclang\-analyzer\-unix.cstring.BadSizeArg\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-unix.cstring.NullArg .sp Check for null pointers being passed as arguments to C string functions. .sp The \fIclang\-analyzer\-unix.cstring.NullArg\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-webkit.NoUncountedMemberChecker .sp Check for no uncounted member variables. .sp The \fIclang\-analyzer\-webkit.NoUncountedMemberChecker\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-webkit.RefCntblBaseVirtualDtor .sp Check for any ref\-countable base class having virtual destructor. .sp The \fIclang\-analyzer\-webkit.RefCntblBaseVirtualDtor\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS clang\-analyzer\-webkit.UncountedLambdaCapturesChecker .sp Check uncounted lambda captures. .sp The \fIclang\-analyzer\-webkit.UncountedLambdaCapturesChecker\fP check is an alias, please see Clang Static Analyzer Available Checkers \% for more information. .SS concurrency\-mt\-unsafe .sp Checks for some thread\-unsafe functions against a black list of known\-to\-be\-unsafe functions. Usually they access static variables without synchronization (e.g. gmtime(3)) or utilize signals in a racy way. The set of functions to check is specified with the \fIFunctionSet\fP option. .sp Note that using some thread\-unsafe functions may be still valid in concurrent programming if only a single thread is used (e.g. setenv(3)), however, some functions may track a state in global variables which would be clobbered by subsequent (non\-parallel, but concurrent) calls to a related function. E.g. the following code suffers from unprotected accesses to a global state: .INDENT 0.0 .INDENT 3.5 .sp .EX // getnetent(3) maintains global state with DB connection, etc. // If a concurrent green thread calls getnetent(3), the global state is corrupted. netent = getnetent(); yield(); netent = getnetent(); .EE .UNINDENT .UNINDENT .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX tm = gmtime(timep); // uses a global buffer sleep(1); // implementation may use SIGALRM .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B FunctionSet Specifies which functions in libc should be considered thread\-safe, possible values are \fIposix\fP, \fIglibc\fP, or \fIany\fP\&. .sp \fIposix\fP means POSIX defined thread\-unsafe functions. POSIX.1\-2001 in \(dq2.9.1 Thread\-Safety\(dq defines that all functions specified in the standard are thread\-safe except a predefined list of thread\-unsafe functions. .sp Glibc defines some of them as thread\-safe (e.g. dirname(3)), but adds non\-POSIX thread\-unsafe ones (e.g. getopt_long(3)). Glibc\(aqs list is compiled from GNU web documentation with a search for MT\-Safe tag: \% .sp If you want to identify thread\-unsafe API for at least one libc or unsure which libc will be used, use \fIany\fP (default). .UNINDENT .SS concurrency\-thread\-canceltype\-asynchronous .sp Finds \fBpthread_setcanceltype\fP function calls where a thread\(aqs cancellation type is set to asynchronous. Asynchronous cancellation type (\fBPTHREAD_CANCEL_ASYNCHRONOUS\fP) is generally unsafe, use type \fBPTHREAD_CANCEL_DEFERRED\fP instead which is the default. Even with deferred cancellation, a cancellation point in an asynchronous signal handler may still be acted upon and the effect is as if it was an asynchronous cancellation. .INDENT 0.0 .INDENT 3.5 .sp .EX pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); .EE .UNINDENT .UNINDENT .sp This check corresponds to the CERT C Coding Standard rule POS47\-C. Do not use threads that can be canceled asynchronously \%\&. .sp \fIcert\-pos47\-c\fP redirects here as an alias of this check. .SS cppcoreguidelines\-avoid\-c\-arrays .sp The \fIcppcoreguidelines\-avoid\-c\-arrays\fP check is an alias, please see modernize\-avoid\-c\-arrays \%<> for more information. .SS cppcoreguidelines\-avoid\-capturing\-lambda\-coroutines .sp Flags C++20 coroutine lambdas with non\-empty capture lists that may cause use\-after\-free errors and suggests avoiding captures or ensuring the lambda closure object has a guaranteed lifetime. .sp This check implements CP.51 \% from the C++ Core Guidelines. .sp Using coroutine lambdas with non\-empty capture lists can be risky, as capturing variables can lead to accessing freed memory after the first suspension point. This issue can occur even with refcounted smart pointers and copyable types. When a lambda expression creates a coroutine, it results in a closure object with storage, which is often on the stack and will eventually go out of scope. When the closure object goes out of scope, its captures also go out of scope. While normal lambdas finish executing before this happens, coroutine lambdas may resume from suspension after the closure object has been destructed, resulting in use\-after\-free memory access for all captures. .sp Consider the following example: .INDENT 0.0 .INDENT 3.5 .sp .EX int value = get_value(); std::shared_ptr sharedFoo = get_foo(); { const auto lambda = [value, sharedFoo]() \-> std::future { co_await something(); // \(dqsharedFoo\(dq and \(dqvalue\(dq have already been destroyed // the \(dqshared\(dq pointer didn\(aqt accomplish anything }; lambda(); } // the lambda closure object has now gone out of scope .EE .UNINDENT .UNINDENT .sp In this example, the lambda object is defined with two captures: value and \fBsharedFoo\fP\&. When \fBlambda()\fP is called, the lambda object is created on the stack, and the captures are copied into the closure object. When the coroutine is suspended, the lambda object goes out of scope, and the closure object is destroyed. When the coroutine is resumed, the captured variables may have been destroyed, resulting in use\-after\-free bugs. .sp In conclusion, the use of coroutine lambdas with non\-empty capture lists can lead to use\-after\-free errors when resuming the coroutine after the closure object has been destroyed. This check helps prevent such errors by flagging C++20 coroutine lambdas with non\-empty capture lists and suggesting avoiding captures or ensuring the lambda closure object has a guaranteed lifetime. .sp Following these guidelines can help ensure the safe and reliable use of coroutine lambdas in C++ code. .SS cppcoreguidelines\-avoid\-const\-or\-ref\-data\-members .sp This check warns when structs or classes that are copyable or movable, and have const\-qualified or reference (lvalue or rvalue) data members. Having such members is rarely useful, and makes the class only copy\-constructible but not copy\-assignable. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX // Bad, const\-qualified member struct Const { const int x; } // Good: class Foo { public: int get() const { return x; } private: int x; }; // Bad, lvalue reference member struct Ref { int& x; }; // Good: struct Foo { int* x; std::unique_ptr x; std::shared_ptr x; gsl::not_null x; }; // Bad, rvalue reference member struct RefRef { int&& x; }; .EE .UNINDENT .UNINDENT .sp This check implements C.12 \% from the C++ Core Guidelines. .sp Further reading: Data members: Never const \%\&. .SS cppcoreguidelines\-avoid\-do\-while .sp Warns when using \fBdo\-while\fP loops. They are less readable than plain \fBwhile\fP loops, since the termination condition is at the end and the condition is not checked prior to the first iteration. This can lead to subtle bugs. .sp This check implements ES.75 \% from the C++ Core Guidelines. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX int x; do { std::cin >> x; // ... } while (x < 0); .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IgnoreMacros Ignore the check when analyzing macros. This is useful for safely defining function\-like macros: .INDENT 7.0 .INDENT 3.5 .sp .EX #define FOO_BAR(x) \e do { \e foo(x); \e bar(x); \e } while(0) .EE .UNINDENT .UNINDENT .sp Defaults to \fIfalse\fP\&. .UNINDENT .SS cppcoreguidelines\-avoid\-goto .sp The usage of \fBgoto\fP for control flow is error prone and should be replaced with looping constructs. Only forward jumps in nested loops are accepted. .sp This check implements ES.76 \% from the C++ Core Guidelines and 6.3.1 \% from High Integrity C++ Coding Standard. .sp For more information on why to avoid programming with \fBgoto\fP you can read the famous paper A Case against the GO TO Statement. \%\&. .sp The check diagnoses \fBgoto\fP for backward jumps in every language mode. These should be replaced with \fIC/C++\fP looping constructs. .INDENT 0.0 .INDENT 3.5 .sp .EX // Bad, handwritten for loop. int i = 0; // Jump label for the loop loop_start: do_some_operation(); if (i < 100) { ++i; goto loop_start; } // Better for(int i = 0; i < 100; ++i) do_some_operation(); .EE .UNINDENT .UNINDENT .sp Modern C++ needs \fBgoto\fP only to jump out of nested loops. .INDENT 0.0 .INDENT 3.5 .sp .EX for(int i = 0; i < 100; ++i) { for(int j = 0; j < 100; ++j) { if (i * j > 500) goto early_exit; } } early_exit: some_operation(); .EE .UNINDENT .UNINDENT .sp All other uses of \fBgoto\fP are diagnosed in \fIC++\fP\&. .SS Options .INDENT 0.0 .TP .B IgnoreMacros If set to \fItrue\fP, the check will not warn if a \fBgoto\fP statement is expanded from a macro. Default is \fIfalse\fP\&. .UNINDENT .SS cppcoreguidelines\-avoid\-magic\-numbers .sp The \fIcppcoreguidelines\-avoid\-magic\-numbers\fP check is an alias, please see readability\-magic\-numbers \%<> for more information. .SS cppcoreguidelines\-avoid\-non\-const\-global\-variables .sp Finds non\-const global variables as described in I.2 \% of C++ Core Guidelines. As R.6 \% of C++ Core Guidelines is a duplicate of rule I.2 \% it also covers that rule. .INDENT 0.0 .INDENT 3.5 .sp .EX char a; // Warns! const char b = 0; namespace some_namespace { char c; // Warns! const char d = 0; } char * c_ptr1 = &some_namespace::c; // Warns! char *const c_const_ptr = &some_namespace::c; // Warns! char & c_reference = some_namespace::c; // Warns! class Foo // No Warnings inside Foo, only namespace scope is covered { public: char e = 0; const char f = 0; protected: char g = 0; private: char h = 0; }; .EE .UNINDENT .UNINDENT .sp The variables \fBa\fP, \fBc\fP, \fBc_ptr1\fP, \fBc_const_ptr\fP and \fBc_reference\fP will all generate warnings since they are either a non\-const globally accessible variable, a pointer or a reference providing global access to non\-const data or both. .SS Options .INDENT 0.0 .TP .B AllowInternalLinkage When set to \fItrue\fP, static non\-const variables and variables in anonymous namespaces will not generate a warning. The default value is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B AllowThreadLocal When set to \fItrue\fP, non\-const global variables with thread\-local storage duration will not generate a warning. The default value is \fIfalse\fP\&. .UNINDENT .SS cppcoreguidelines\-avoid\-reference\-coroutine\-parameters .sp Warns when a coroutine accepts reference parameters. After a coroutine suspend point, references could be dangling and no longer valid. Instead, pass parameters as values. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX std::future someCoroutine(int& val) { co_await ...; // When the coroutine is resumed, \(aqval\(aq might no longer be valid. if (val) ... } .EE .UNINDENT .UNINDENT .sp This check implements CP.53 \% from the C++ Core Guidelines. .SS cppcoreguidelines\-c\-copy\-assignment\-signature .sp The \fIcppcoreguidelines\-c\-copy\-assignment\-signature\fP check is an alias, please see misc\-unconventional\-assign\-operator \%<> for more information. .SS cppcoreguidelines\-explicit\-virtual\-functions .sp The \fIcppcoreguidelines\-explicit\-virtual\-functions\fP check is an alias, please see modernize\-use\-override \%<> for more information. .SS cppcoreguidelines\-init\-variables .sp Checks whether there are local variables that are declared without an initial value. These may lead to unexpected behavior if there is a code path that reads the variable before assigning to it. .sp This rule is part of the Type safety (Type.5) \% profile and ES.20 \% from the C++ Core Guidelines. .sp Only integers, booleans, floats, doubles and pointers are checked. The fix option initializes all detected values with the value of zero. An exception is float and double types, which are initialized to NaN. .sp As an example a function that looks like this: .INDENT 0.0 .INDENT 3.5 .sp .EX void function() { int x; char *txt; double d; // Rest of the function. } .EE .UNINDENT .UNINDENT .sp Would be rewritten to look like this: .INDENT 0.0 .INDENT 3.5 .sp .EX #include void function() { int x = 0; char *txt = nullptr; double d = NAN; // Rest of the function. } .EE .UNINDENT .UNINDENT .sp It warns for the uninitialized enum case, but without a FixIt: .INDENT 0.0 .INDENT 3.5 .sp .EX enum A {A1, A2, A3}; enum A_c : char { A_c1, A_c2, A_c3 }; enum class B { B1, B2, B3 }; enum class B_i : int { B_i1, B_i2, B_i3 }; void function() { A a; // Warning: variable \(aqa\(aq is not initialized A_c a_c; // Warning: variable \(aqa_c\(aq is not initialized B b; // Warning: variable \(aqb\(aq is not initialized B_i b_i; // Warning: variable \(aqb_i\(aq is not initialized } .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IncludeStyle A string specifying which include\-style is used, \fIllvm\fP or \fIgoogle\fP\&. Default is \fIllvm\fP\&. .UNINDENT .INDENT 0.0 .TP .B MathHeader A string specifying the header to include to get the definition of \fINAN\fP\&. Default is \fI\fP\&. .UNINDENT .SS cppcoreguidelines\-interfaces\-global\-init .sp This check flags initializers of globals that access extern objects, and therefore can lead to order\-of\-initialization problems. .sp This check implements I.22 \% from the C++ Core Guidelines. .sp Note that currently this does not flag calls to non\-constexpr functions, and therefore globals could still be accessed from functions themselves. .SS cppcoreguidelines\-macro\-to\-enum .sp The \fIcppcoreguidelines\-macro\-to\-enum\fP check is an alias, please see modernize\-macro\-to\-enum \%<> for more information. .SS cppcoreguidelines\-macro\-usage .sp Finds macro usage that is considered problematic because better language constructs exist for the task. .sp The relevant sections in the C++ Core Guidelines are ES.31 \%, and ES.32 \%\&. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX #define C 0 #define F1(x, y) ((a) > (b) ? (a) : (b)) #define F2(...) (__VA_ARGS__) #define F3(x, y) x##y #define COMMA , #define NORETURN [[noreturn]] #define DEPRECATED attribute((deprecated)) #if LIB_EXPORTS #define DLLEXPORTS __declspec(dllexport) #else #define DLLEXPORTS __declspec(dllimport) #endif .EE .UNINDENT .UNINDENT .sp results in the following warnings: .INDENT 0.0 .INDENT 3.5 .sp .EX 4 warnings generated. test.cpp:1:9: warning: macro \(aqC\(aq used to declare a constant; consider using a \(aqconstexpr\(aq constant [cppcoreguidelines\-macro\-usage] #define C 0 ^ test.cpp:2:9: warning: function\-like macro \(aqF1\(aq used; consider a \(aqconstexpr\(aq template function [cppcoreguidelines\-macro\-usage] #define F1(x, y) ((a) > (b) ? (a) : (b)) ^ test.cpp:3:9: warning: variadic macro \(aqF2\(aq used; consider using a \(aqconstexpr\(aq variadic template function [cppcoreguidelines\-macro\-usage] #define F2(...) (__VA_ARGS__) ^ .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B AllowedRegexp A regular expression to filter allowed macros. For example \fIDEBUG*|LIBTORRENT*|TORRENT*|UNI*\fP could be applied to filter \fIlibtorrent\fP\&. Default value is \fI^DEBUG_*\fP\&. .UNINDENT .INDENT 0.0 .TP .B CheckCapsOnly Boolean flag to warn on all macros except those with CAPS_ONLY names. This option is intended to ease introduction of this check into older code bases. Default value is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B IgnoreCommandLineMacros Boolean flag to toggle ignoring command\-line\-defined macros. Default value is \fItrue\fP\&. .UNINDENT .SS cppcoreguidelines\-misleading\-capture\-default\-by\-value .sp Warns when lambda specify a by\-value capture default and capture \fBthis\fP\&. .sp By\-value capture defaults in member functions can be misleading about whether data members are captured by value or reference. This occurs because specifying the capture default \fB[=]\fP actually captures the \fBthis\fP pointer by value, not the data members themselves. As a result, data members are still indirectly accessed via the captured \fBthis\fP pointer, which essentially means they are being accessed by reference. Therefore, even when using \fB[=]\fP, data members are effectively captured by reference, which might not align with the user\(aqs expectations. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX struct AClass { int member; void misleadingLogic() { int local = 0; member = 0; auto f = [=]() mutable { local += 1; member += 1; }; f(); // Here, local is 0 but member is 1 } void clearLogic() { int local = 0; member = 0; auto f = [this, local]() mutable { local += 1; member += 1; }; f(); // Here, local is 0 but member is 1 } }; .EE .UNINDENT .UNINDENT .sp This check implements F.54 \% from the C++ Core Guidelines. .SS cppcoreguidelines\-missing\-std\-forward .sp Warns when a forwarding reference parameter is not forwarded inside the function body. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX template void wrapper(T&& t) { impl(std::forward(t), 1, 2); // Correct } template void wrapper2(T&& t) { impl(t, 1, 2); // Oops \- should use std::forward(t) } template void wrapper3(T&& t) { impl(std::move(t), 1, 2); // Also buggy \- should use std::forward(t) } template void wrapper_function(F&& f) { std::forward(f)(1, 2); // Correct } template void wrapper_function2(F&& f) { f(1, 2); // Incorrect \- may not invoke the desired qualified function operator } .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B ForwardFunction Specify the function used for forwarding. Default is \fI::std::forward\fP\&. .UNINDENT .sp This check implements F.19 \% from the C++ Core Guidelines. .SS cppcoreguidelines\-narrowing\-conversions .sp This check implements part of ES.46 \% from the C++ Core Guidelines. .sp The \fIcppcoreguidelines\-narrowing\-conversions\fP check is an alias, please see bugprone\-narrowing\-conversions \%<> for more information. .SS cppcoreguidelines\-no\-malloc .sp This check handles C\-Style memory management using \fBmalloc()\fP, \fBrealloc()\fP, \fBcalloc()\fP and \fBfree()\fP\&. It warns about its use and tries to suggest the use of an appropriate RAII object. Furthermore, it can be configured to check against a user\-specified list of functions that are used for memory management (e.g. \fBposix_memalign()\fP). .sp This check implements R.10 \% from the C++ Core Guidelines. .sp There is no attempt made to provide fix\-it hints, since manual resource management isn\(aqt easily transformed automatically into RAII. .INDENT 0.0 .INDENT 3.5 .sp .EX // Warns each of the following lines. // Containers like std::vector or std::string should be used. char* some_string = (char*) malloc(sizeof(char) * 20); char* some_string = (char*) realloc(sizeof(char) * 30); free(some_string); int* int_array = (int*) calloc(30, sizeof(int)); // Rather use a smartpointer or stack variable. struct some_struct* s = (struct some_struct*) malloc(sizeof(struct some_struct)); .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B Allocations Semicolon\-separated list of fully qualified names of memory allocation functions. Defaults to \fI::malloc;::calloc\fP\&. .UNINDENT .INDENT 0.0 .TP .B Deallocations Semicolon\-separated list of fully qualified names of memory allocation functions. Defaults to \fI::free\fP\&. .UNINDENT .INDENT 0.0 .TP .B Reallocations Semicolon\-separated list of fully qualified names of memory allocation functions. Defaults to \fI::realloc\fP\&. .UNINDENT .SS cppcoreguidelines\-no\-suspend\-with\-lock .sp Flags coroutines that suspend while a lock guard is in scope at the suspension point. .sp When a coroutine suspends, any mutexes held by the coroutine will remain locked until the coroutine resumes and eventually destructs the lock guard. This can lead to long periods with a mutex held and runs the risk of deadlock. .sp Instead, locks should be released before suspending a coroutine. .sp This check only checks suspending coroutines while a lock_guard is in scope; it does not consider manual locking or unlocking of mutexes, e.g., through calls to \fBstd::mutex::lock()\fP\&. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX future bad_coro() { std::lock_guard lock{mtx}; ++some_counter; co_await something(); // Suspending while holding a mutex } future good_coro() { { std::lock_guard lock{mtx}; ++some_counter; } // Destroy the lock_guard to release the mutex before suspending the coroutine co_await something(); // Suspending while holding a mutex } .EE .UNINDENT .UNINDENT .sp This check implements CP.52 \% from the C++ Core Guidelines. .SS cppcoreguidelines\-noexcept\-destructor .sp This check implements C.37 \% from the C++ Core Guidelines. .sp The \fIcppcoreguidelines\-noexcept\-destructor\fP check is an alias, please see performance\-noexcept\-destructor \%<> for more information. .SS cppcoreguidelines\-noexcept\-move\-operations .sp This check implements C.66 \% from the C++ Core Guidelines. .sp The \fIcppcoreguidelines\-noexcept\-move\-operations\fP check is an alias, please see performance\-noexcept\-move\-constructor \%<> for more information. .SS cppcoreguidelines\-noexcept\-swap .sp This check implements C.83 \% , C.84 \% and C.85 \% from the C++ Core Guidelines. .sp The \fIcppcoreguidelines\-noexcept\-swap check\fP is an alias, please see performance\-noexcept\-swap \%<> for more information. .SS cppcoreguidelines\-non\-private\-member\-variables\-in\-classes .sp The \fIcppcoreguidelines\-non\-private\-member\-variables\-in\-classes\fP check is an alias, please see misc\-non\-private\-member\-variables\-in\-classes \%<> for more information. .SS cppcoreguidelines\-owning\-memory .sp This check implements the type\-based semantics of \fBgsl::owner\fP, which allows static analysis on code, that uses raw pointers to handle resources like dynamic memory, but won\(aqt introduce RAII concepts. .sp This check implements I.11 \%, C.33 \%, R.3 \% and GSL.Views \% from the C++ Core Guidelines. The definition of a \fBgsl::owner\fP is straight forward .INDENT 0.0 .INDENT 3.5 .sp .EX namespace gsl { template owner = T; } .EE .UNINDENT .UNINDENT .sp It is therefore simple to introduce the owner even without using an implementation of the Guideline Support Library \%\&. .sp All checks are purely type based and not (yet) flow sensitive. .sp The following examples will demonstrate the correct and incorrect initializations of owners, assignment is handled the same way. Note that both \fBnew\fP and \fBmalloc()\fP\-like resource functions are considered to produce resources. .INDENT 0.0 .INDENT 3.5 .sp .EX // Creating an owner with factory functions is checked. gsl::owner function_that_returns_owner() { return gsl::owner(new int(42)); } // Dynamic memory must be assigned to an owner int* Something = new int(42); // BAD, will be caught gsl::owner Owner = new int(42); // Good gsl::owner Owner = new int[42]; // Good as well // Returned owner must be assigned to an owner int* Something = function_that_returns_owner(); // Bad, factory function gsl::owner Owner = function_that_returns_owner(); // Good, result lands in owner // Something not a resource or owner should not be assigned to owners int Stack = 42; gsl::owner Owned = &Stack; // Bad, not a resource assigned .EE .UNINDENT .UNINDENT .sp In the case of dynamic memory as resource, only \fBgsl::owner\fP variables are allowed to be deleted. .INDENT 0.0 .INDENT 3.5 .sp .EX // Example Bad, non\-owner as resource handle, will be caught. int* NonOwner = new int(42); // First warning here, since new must land in an owner delete NonOwner; // Second warning here, since only owners are allowed to be deleted // Example Good, Ownership correctly stated gsl::owner Owner = new int(42); // Good delete Owner; // Good as well, statically enforced, that only owners get deleted .EE .UNINDENT .UNINDENT .sp The check will furthermore ensure, that functions, that expect a \fBgsl::owner\fP as argument get called with either a \fBgsl::owner\fP or a newly created resource. .INDENT 0.0 .INDENT 3.5 .sp .EX void expects_owner(gsl::owner o) { delete o; } // Bad Code int NonOwner = 42; expects_owner(&NonOwner); // Bad, will get caught // Good Code gsl::owner Owner = new int(42); expects_owner(Owner); // Good expects_owner(new int(42)); // Good as well, recognized created resource // Port legacy code for better resource\-safety gsl::owner File = fopen(\(dqmy_file.txt\(dq, \(dqrw+\(dq); FILE* BadFile = fopen(\(dqanother_file.txt\(dq, \(dqw\(dq); // Bad, warned // ... use the file fclose(File); // Ok, File is annotated as \(aqowner<>\(aq fclose(BadFile); // BadFile is not an \(aqowner<>\(aq, will be warned .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B LegacyResourceProducers Semicolon\-separated list of fully qualified names of legacy functions that create resources but cannot introduce \fBgsl::owner<>\fP\&. Defaults to \fI::malloc;::aligned_alloc;::realloc;::calloc;::fopen;::freopen;::tmpfile\fP\&. .UNINDENT .INDENT 0.0 .TP .B LegacyResourceConsumers Semicolon\-separated list of fully qualified names of legacy functions expecting resource owners as pointer arguments but cannot introduce \fBgsl::owner<>\fP\&. Defaults to \fI::free;::realloc;::freopen;::fclose\fP\&. .UNINDENT .SS Limitations .sp Using \fBgsl::owner\fP in a typedef or alias is not handled correctly. .INDENT 0.0 .INDENT 3.5 .sp .EX using heap_int = gsl::owner; heap_int allocated = new int(42); // False positive! .EE .UNINDENT .UNINDENT .sp The \fBgsl::owner\fP is declared as a templated type alias. In template functions and classes, like in the example below, the information of the type aliases gets lost. Therefore using \fBgsl::owner\fP in a heavy templated code base might lead to false positives. .sp Known code constructs that do not get diagnosed correctly are: .INDENT 0.0 .IP \(bu 2 \fBstd::exchange\fP .IP \(bu 2 \fBstd::vector>\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .EX // This template function works as expected. Type information doesn\(aqt get lost. template void delete_owner(gsl::owner owned_object) { delete owned_object; // Everything alright } gsl::owner function_that_returns_owner() { return gsl::owner(new int(42)); } // Type deduction does not work for auto variables. // This is caught by the check and will be noted accordingly. auto OwnedObject = function_that_returns_owner(); // Type of OwnedObject will be int* // Problematic function template that looses the typeinformation on owner template void bad_template_function(T some_object) { // This line will trigger the warning, that a non\-owner is assigned to an owner gsl::owner new_owner = some_object; } // Calling the function with an owner still yields a false positive. bad_template_function(gsl::owner(new int(42))); // The same issue occurs with templated classes like the following. template class OwnedValue { public: const T getValue() const { return _val; } private: T _val; }; // Code, that yields a false positive. OwnedValue> Owner(new int(42)); // Type deduction yield T \-> int * // False positive, getValue returns int* and not gsl::owner gsl::owner OwnedInt = Owner.getValue(); .EE .UNINDENT .UNINDENT .sp Another limitation of the current implementation is only the type based checking. Suppose you have code like the following: .INDENT 0.0 .INDENT 3.5 .sp .EX // Two owners with assigned resources gsl::owner Owner1 = new int(42); gsl::owner Owner2 = new int(42); Owner2 = Owner1; // Conceptual Leak of initial resource of Owner2! Owner1 = nullptr; .EE .UNINDENT .UNINDENT .sp The semantic of a \fBgsl::owner\fP is mostly like a \fBstd::unique_ptr\fP, therefore assignment of two \fBgsl::owner\fP is considered a move, which requires that the resource \fBOwner2\fP must have been released before the assignment. This kind of condition could be caught in later improvements of this check with flowsensitive analysis. Currently, the \fIClang Static Analyzer\fP catches this bug for dynamic memory, but not for general types of resources. .SS cppcoreguidelines\-prefer\-member\-initializer .sp Finds member initializations in the constructor body which can be converted into member initializers of the constructor instead. This not only improves the readability of the code but also positively affects its performance. Class\-member assignments inside a control statement or following the first control statement are ignored. .sp This check implements C.49 \% from the C++ Core Guidelines. .sp Please note, that this check does not enforce rule C.48 \% from the C++ Core Guidelines. For that purpose see check modernize\-use\-default\-member\-init \%<>\&. .SS Example 1 .INDENT 0.0 .INDENT 3.5 .sp .EX class C { int n; int m; public: C() { n = 1; // Literal in default constructor if (dice()) return; m = 1; } }; .EE .UNINDENT .UNINDENT .sp Here \fBn\fP can be initialized in the constructor initializer list, unlike \fBm\fP, as \fBm\fP\(aqs initialization follows a control statement (\fBif\fP): .INDENT 0.0 .INDENT 3.5 .sp .EX class C { int n; int m; public: C(): n(1) { if (dice()) return; m = 1; } }; .EE .UNINDENT .UNINDENT .SS Example 2 .INDENT 0.0 .INDENT 3.5 .sp .EX class C { int n; int m; public: C(int nn, int mm) { n = nn; // Neither default constructor nor literal if (dice()) return; m = mm; } }; .EE .UNINDENT .UNINDENT .sp Here \fBn\fP can be initialized in the constructor initializer list, unlike \fBm\fP, as \fBm\fP\(aqs initialization follows a control statement (\fBif\fP): .INDENT 0.0 .INDENT 3.5 .sp .EX C(int nn, int mm) : n(nn) { if (dice()) return; m = mm; } .EE .UNINDENT .UNINDENT .SS cppcoreguidelines\-pro\-bounds\-array\-to\-pointer\-decay .sp This check flags all array to pointer decays. .sp Pointers should not be used as arrays. \fBspan\fP is a bounds\-checked, safe alternative to using pointers to access arrays. .sp This rule is part of the Bounds safety (Bounds 3) \% profile from the C++ Core Guidelines. .SS cppcoreguidelines\-pro\-bounds\-avoid\-unchecked\-container\-access .sp Finds calls to \fBoperator[]\fP in STL containers and suggests replacing them with safe alternatives. Safe alternatives include STL \fBat\fP or GSL \fBat\fP functions, \fBbegin()\fP or \fBend()\fP functions, \fBrange\-for\fP loops, \fBstd::span\fP, or an appropriate function from \fB\fP\&. .sp For example, both .INDENT 0.0 .INDENT 3.5 .sp .EX std::vector a; int b = a[4]; .EE .UNINDENT .UNINDENT .sp and .INDENT 0.0 .INDENT 3.5 .sp .EX std::unique_ptr a; int b = a[0]; .EE .UNINDENT .UNINDENT .sp will generate a warning. .sp STL containers for which \fBoperator[]\fP is well\-defined for all inputs are excluded from this check (e.g.: \fBstd::map::operator[]\fP). .sp This check enforces part of the SL.con.3 \% guideline and is part of the Bounds Safety (Bounds 4) \% profile from the C++ Core Guidelines. .SS Options .INDENT 0.0 .TP .B ExcludeClasses Semicolon\-separated list of regular expressions matching class names that overwrites the default exclusion list. The default is: \fI::std::map;::std::unordered_map;::std::flat_map\fP\&. .UNINDENT .INDENT 0.0 .TP .B FixMode Determines what fixes are suggested. Either \fInone\fP, \fIat\fP (use \fBa.at(index)\fP if a fitting function exists) or \fIfunction\fP (use a function \fBf(a, index)\fP). The default is \fInone\fP\&. .UNINDENT .INDENT 0.0 .TP .B FixFunction The function to use in the \fIfunction\fP mode. For C++23 and beyond, the passed function must support the empty subscript operator, i.e., the case where \fBa[]\fP becomes \fBf(a)\fP\&. \fBFixFunctionEmptyArgs\fP can be used to override the suggested function in that case. The default is \fIgsl::at\fP\&. .UNINDENT .INDENT 0.0 .TP .B FixFunctionEmptyArgs The function to use in the \fIfunction\fP mode for the empty subscript operator case in C++23 and beyond only. If no fixes should be made for empty subscript operators, pass an empty string. In that case, only the warnings will be printed. The default is the value of \fBFixFunction\fP\&. .UNINDENT .SS cppcoreguidelines\-pro\-bounds\-constant\-array\-index .sp This check flags all array subscript expressions on static arrays and \fBstd::arrays\fP that either do not have a constant integer expression index or are out of bounds (for \fBstd::array\fP). For out\-of\-bounds checking of static arrays, see the \fI\-Warray\-bounds\fP Clang diagnostic. .sp This rule is part of the Bounds safety (Bounds 2) \% profile from the C++ Core Guidelines. .sp Optionally, this check can generate fixes using \fBgsl::at\fP for indexing. .SS Options .INDENT 0.0 .TP .B GslHeader The check can generate fixes after this option has been set to the name of the include file that contains \fBgsl::at()\fP, e.g. \fI\(dqgsl/gsl.h\(dq\fP\&. Default is an empty string. .UNINDENT .INDENT 0.0 .TP .B IncludeStyle A string specifying which include\-style is used, \fIllvm\fP or \fIgoogle\fP\&. Default is \fIllvm\fP\&. .UNINDENT .SS cppcoreguidelines\-pro\-bounds\-pointer\-arithmetic .sp This check flags all usage of pointer arithmetic, because it could lead to an invalid pointer. Subtraction of two pointers is not flagged by this check. .sp Pointers should only refer to single objects, and pointer arithmetic is fragile and easy to get wrong. \fBspan\fP is a bounds\-checked, safe type for accessing arrays of data. .sp This rule is part of the Bounds safety (Bounds 1) \% profile from the C++ Core Guidelines. .SS Options .INDENT 0.0 .TP .B AllowIncrementDecrementOperators When enabled, the check will allow using the prefix/postfix increment or decrement operators on pointers. Default is \fBfalse\fP\&. .UNINDENT .SS cppcoreguidelines\-pro\-type\-const\-cast .sp Imposes limitations on the use of \fBconst_cast\fP within C++ code. It depends on the \fBStrictMode\fP \%<#\:cmdoption-arg-StrictMode> option setting to determine whether it should flag all instances of \fBconst_cast\fP or only those that remove either \fBconst\fP or \fBvolatile\fP qualifier. .sp Modifying a variable that has been declared as \fBconst\fP in C++ is generally considered undefined behavior, and this remains true even when using \fBconst_cast\fP\&. In C++, the \fBconst\fP qualifier indicates that a variable is intended to be read\-only, and the compiler enforces this by disallowing any attempts to change the value of that variable. .sp Removing the \fBvolatile\fP qualifier in C++ can have serious consequences. This qualifier indicates that a variable\(aqs value can change unpredictably, and removing it may lead to undefined behavior, optimization problems, and debugging challenges. It\(aqs essential to retain the \fBvolatile\fP qualifier in situations where the variable\(aqs volatility is a crucial aspect of program correctness and reliability. .sp This rule is part of the Type safety (Type 3) \% profile and ES.50: Don’t cast away const \% rule from the C++ Core Guidelines. .SS Options .INDENT 0.0 .TP .B StrictMode When this setting is set to \fItrue\fP, it means that any usage of \fBconst_cast\fP is not allowed. On the other hand, when it\(aqs set to \fIfalse\fP, it permits casting to \fBconst\fP or \fBvolatile\fP types. Default value is \fIfalse\fP\&. .UNINDENT .SS cppcoreguidelines\-pro\-type\-cstyle\-cast .sp This check flags all use of C\-style casts that perform a \fBstatic_cast\fP downcast, \fBconst_cast\fP, or \fBreinterpret_cast\fP\&. .sp Use of these casts can violate type safety and cause the program to access a variable that is actually of type X to be accessed as if it were of an unrelated type Z. Note that a C\-style \fB(T)expression\fP cast means to perform the first of the following that is possible: a \fBconst_cast\fP, a \fBstatic_cast\fP, a \fBstatic_cast\fP followed by a \fBconst_cast\fP, a \fBreinterpret_cast\fP, or a \fBreinterpret_cast\fP followed by a \fBconst_cast\fP\&. This rule bans \fB(T)expression\fP only when used to perform an unsafe cast. .sp This rule is part of the Type safety (Type.4) \% profile from the C++ Core Guidelines. .SS cppcoreguidelines\-pro\-type\-member\-init .sp The check flags user\-provided constructor definitions that do not initialize all fields that would be left in an undefined state by default construction, e.g. builtins, pointers and record types without user\-provided default constructors containing at least one such type. If these fields aren\(aqt initialized, the constructor will leave some of the memory in an undefined state. .sp For C++11 it suggests fixes to add in\-class field initializers. For older versions it inserts the field initializers into the constructor initializer list. It will also initialize any direct base classes that need to be zeroed in the constructor initializer list. .sp The check takes assignment of fields in the constructor body into account but generates false positives for fields initialized in methods invoked in the constructor body. .sp The check also flags variables with automatic storage duration that have record types without a user\-provided constructor and are not initialized. The suggested fix is to zero initialize the variable via \fB{}\fP for C++11 and beyond or \fB= {}\fP for older language versions. .SS Options .INDENT 0.0 .TP .B IgnoreArrays If set to \fItrue\fP, the check will not warn about array members that are not zero\-initialized during construction. For performance critical code, it may be important to not initialize fixed\-size array members. Default is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B UseAssignment If set to \fItrue\fP, the check will provide fix\-its with literal initializers ( \fBint i = 0;\fP ) instead of curly braces ( \fBint i{};\fP ). Default is \fIfalse\fP\&. .UNINDENT .sp This rule is part of the Type safety (Type.6) \% profile from the C++ Core Guidelines. .SS cppcoreguidelines\-pro\-type\-reinterpret\-cast .sp This check flags all uses of \fBreinterpret_cast\fP in C++ code. .sp Use of these casts can violate type safety and cause the program to access a variable that is actually of type \fBX\fP to be accessed as if it were of an unrelated type \fBZ\fP\&. .sp This rule is part of the Type safety (Type.1.1) \% profile from the C++ Core Guidelines. .SS cppcoreguidelines\-pro\-type\-static\-cast\-downcast .sp This check flags all usages of \fBstatic_cast\fP, where a base class is casted to a derived class. In those cases, a fix\-it is provided to convert the cast to a \fBdynamic_cast\fP\&. .sp Use of these casts can violate type safety and cause the program to access a variable that is actually of type \fBX\fP to be accessed as if it were of an unrelated type \fBZ\fP\&. .sp This rule is part of the Type safety (Type.2) \% profile from the C++ Core Guidelines. .SS Options .INDENT 0.0 .TP .B StrictMode When set to \fIfalse\fP, no warnings are emitted for casts on non\-polymorphic types. Default is \fItrue\fP\&. .UNINDENT .SS cppcoreguidelines\-pro\-type\-union\-access .sp This check flags all access to members of unions. Passing unions as a whole is not flagged. .sp Reading from a union member assumes that member was the last one written, and writing to a union member assumes another member with a nontrivial destructor had its destructor called. This is fragile because it cannot generally be enforced to be safe in the language and so relies on programmer discipline to get it right. .sp This rule is part of the Type safety (Type.7) \% profile from the C++ Core Guidelines. .SS cppcoreguidelines\-pro\-type\-vararg .sp This check flags all calls to c\-style vararg functions and all use of \fBva_arg\fP\&. .sp To allow for SFINAE use of vararg functions, a call is not flagged if a literal 0 is passed as the only vararg argument or function is used in unevaluated context. .sp Passing to varargs assumes the correct type will be read. This is fragile because it cannot generally be enforced to be safe in the language and so relies on programmer discipline to get it right. .sp This rule is part of the Type safety (Type.8) \% profile from the C++ Core Guidelines. .SS cppcoreguidelines\-rvalue\-reference\-param\-not\-moved .sp Warns when an rvalue reference function parameter is never moved within the function body. .sp Rvalue reference parameters indicate a parameter that should be moved with \fBstd::move\fP from within the function body. Any such parameter that is never moved is confusing and potentially indicative of a buggy program. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX void logic(std::string&& Input) { std::string Copy(Input); // Oops \- forgot to std::move } .EE .UNINDENT .UNINDENT .sp Note that parameters that are unused and marked as such will not be diagnosed. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX void conditional_use([[maybe_unused]] std::string&& Input) { // No diagnostic here since Input is unused and marked as such } .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B AllowPartialMove .INDENT 7.0 .INDENT 3.5 If set to \fItrue\fP, the check accepts \fBstd::move\fP calls containing any subexpression containing the parameter. CppCoreGuideline F.18 officially mandates that the parameter itself must be moved. Default is \fIfalse\fP\&. .UNINDENT .UNINDENT .INDENT 7.0 .INDENT 3.5 .sp .EX // \(aqp\(aq is flagged by this check if and only if AllowPartialMove is false void move_members_of(pair&& p) { pair other; other.first = std::move(p.first); other.second = std::move(p.second); } // \(aqp\(aq is never flagged by this check void move_whole_pair(pair&& p) { pair other = std::move(p); } .EE .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B IgnoreUnnamedParams If set to \fItrue\fP, the check ignores unnamed rvalue reference parameters. Default is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B IgnoreNonDeducedTemplateTypes .INDENT 7.0 .INDENT 3.5 If set to \fItrue\fP, the check ignores non\-deduced template type rvalue reference parameters. Default is \fIfalse\fP\&. .UNINDENT .UNINDENT .INDENT 7.0 .INDENT 3.5 .sp .EX template struct SomeClass { // Below, \(aqT\(aq is not deduced and \(aqT&&\(aq is an rvalue reference type. // This will be flagged if and only if IgnoreNonDeducedTemplateTypes is // false. One suggested fix would be to specialize the class for \(aqT\(aq and // \(aqT&\(aq separately (e.g., see std::future), or allow only one of \(aqT\(aq or // \(aqT&\(aq instantiations of SomeClass (e.g., see std::optional). SomeClass(T&& t) { } }; // Never flagged, since \(aqT\(aq is a forwarding reference in a deduced context template void forwarding_ref(T&& t) { T other = std::forward(t); } .EE .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B MoveFunction Specify the function used for moving. Default is \fI::std::move\fP\&. .UNINDENT .sp This check implements F.18 \% from the C++ Core Guidelines. .SS cppcoreguidelines\-slicing .sp Flags slicing of member variables or vtable. Slicing happens when copying a derived object into a base object: the members of the derived object (both member variables and virtual member functions) will be discarded. This can be misleading especially for member function slicing, for example: .INDENT 0.0 .INDENT 3.5 .sp .EX struct B { int a; virtual int f(); }; struct D : B { int b; int f() override; }; void use(B b) { // Missing reference, intended? b.f(); // Calls B::f. } D d; use(d); // Slice. .EE .UNINDENT .UNINDENT .sp This check implements ES.63 \% and C.145 \% from the C++ Core Guidelines. .SS cppcoreguidelines\-special\-member\-functions .sp The check finds classes where some but not all of the special member functions are defined. .sp By default the compiler defines a copy constructor, copy assignment operator, move constructor, move assignment operator and destructor. The default can be suppressed by explicit user\-definitions. The relationship between which functions will be suppressed by definitions of other functions is complicated and it is advised that all five are defaulted or explicitly defined. .sp Note that defining a function with \fB= delete\fP is considered to be a definition. .sp This check implements C.21 \% from the C++ Core Guidelines. .SS Options .INDENT 0.0 .TP .B AllowSoleDefaultDtor When set to \fItrue\fP (default is \fIfalse\fP), this check will only trigger on destructors if they are defined and not defaulted. .INDENT 7.0 .INDENT 3.5 .sp .EX struct A { // This is fine. virtual ~A() = default; }; struct B { // This is not fine. ~B() {} }; struct C { // This is not checked, because the destructor might be defaulted in // another translation unit. ~C(); }; .EE .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B AllowMissingMoveFunctions When set to \fItrue\fP (default is \fIfalse\fP), this check doesn\(aqt flag classes which define no move operations at all. It still flags classes which define only one of either move constructor or move assignment operator. With this option enabled, the following class won\(aqt be flagged: .INDENT 7.0 .INDENT 3.5 .sp .EX struct A { A(const A&); A& operator=(const A&); ~A(); }; .EE .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B AllowMissingMoveFunctionsWhenCopyIsDeleted When set to \fItrue\fP (default is \fIfalse\fP), this check doesn\(aqt flag classes which define deleted copy operations but don\(aqt define move operations. This flag is related to Google C++ Style Guide Copyable and Movable Types \%\&. With this option enabled, the following class won\(aqt be flagged: .INDENT 7.0 .INDENT 3.5 .sp .EX struct A { A(const A&) = delete; A& operator=(const A&) = delete; ~A(); }; .EE .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B AllowImplicitlyDeletedCopyOrMove When set to \fItrue\fP (default is \fIfalse\fP), this check doesn\(aqt flag classes which implicitly delete copy or move operations. With this option enabled, the following class won\(aqt be flagged: .INDENT 7.0 .INDENT 3.5 .sp .EX struct A : boost::noncopyable { ~A() { std::cout << \(dqdtor\en\(dq; } }; .EE .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B IgnoreMacros If set to \fItrue\fP, the check will not give warnings for classes defined inside macros. Default is \fItrue\fP\&. .UNINDENT .SS cppcoreguidelines\-use\-default\-member\-init .sp This check implements C.48 \% from the C++ Core Guidelines. .sp The \fIcppcoreguidelines\-use\-default\-member\-init\fP check is an alias, please see modernize\-use\-default\-member\-init \%<> for more information. .SS cppcoreguidelines\-use\-enum\-class .sp Finds unscoped (non\-class) \fBenum\fP declarations and suggests using \fBenum class\fP instead. .sp This check implements Enum.3 \% from the C++ Core Guidelines.\(dq .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX enum E {}; // use \(dqenum class E {};\(dq instead enum class E {}; // OK struct S { enum E {}; // use \(dqenum class E {};\(dq instead // OK with option IgnoreUnscopedEnumsInClasses }; namespace N { enum E {}; // use \(dqenum class E {};\(dq instead } .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IgnoreUnscopedEnumsInClasses When \fItrue\fP, ignores unscoped \fBenum\fP declarations in classes. Default is \fIfalse\fP\&. .UNINDENT .SS cppcoreguidelines\-virtual\-class\-destructor .sp Finds virtual classes whose destructor is neither public and virtual nor protected and non\-virtual. A virtual class\(aqs destructor should be specified in one of these ways to prevent undefined behavior. .sp This check implements C.35 \% from the C++ Core Guidelines. .sp Note that this check will diagnose a class with a virtual method regardless of whether the class is used as a base class or not. .sp Fixes are available for user\-declared and implicit destructors that are either public and non\-virtual or protected and virtual. No fixes are offered for private destructors. There, the decision whether to make them private and virtual or protected and non\-virtual depends on the use case and is thus left to the user. .SS Example .sp For example, the following classes/structs get flagged by the check since they violate guideline \fBC.35\fP: .INDENT 0.0 .INDENT 3.5 .sp .EX struct Foo { // NOK, protected destructor should not be virtual virtual void f(); protected: virtual ~Foo(){} }; class Bar { // NOK, public destructor should be virtual virtual void f(); public: ~Bar(){} }; .EE .UNINDENT .UNINDENT .sp This would be rewritten to look like this: .INDENT 0.0 .INDENT 3.5 .sp .EX struct Foo { // OK, destructor is not virtual anymore virtual void f(); protected: ~Foo(){} }; class Bar { // OK, destructor is now virtual virtual void f(); public: virtual ~Bar(){} }; .EE .UNINDENT .UNINDENT .SS darwin\-avoid\-spinlock .sp Finds usages of \fBOSSpinlock\fP, which is deprecated due to potential livelock problems. .sp This check will detect following function invocations: .INDENT 0.0 .IP \(bu 2 \fBOSSpinlockLock\fP .IP \(bu 2 \fBOSSpinlockTry\fP .IP \(bu 2 \fBOSSpinlockUnlock\fP .UNINDENT .sp The corresponding information about the problem of \fBOSSpinlock\fP: \% .SS darwin\-dispatch\-once\-nonstatic .sp Finds declarations of \fBdispatch_once_t\fP variables without static or global storage. The behavior of using \fBdispatch_once_t\fP predicates with automatic or dynamic storage is undefined by libdispatch, and should be avoided. .sp It is a common pattern to have functions initialize internal static or global data once when the function runs, but programmers have been known to miss the static on the \fBdispatch_once_t\fP predicate, leading to an uninitialized flag value at the mercy of the stack. .sp Programmers have also been known to make \fBdispatch_once_t\fP variables be members of structs or classes, with the intent to lazily perform some expensive struct or class member initialization only once; however, this violates the libdispatch requirements. .sp See the discussion section of Apple\(aqs dispatch_once documentation \% for more information. .SS fuchsia\-default\-arguments\-calls .sp Warns if a function or method is called with default arguments. .sp For example, given the declaration: .INDENT 0.0 .INDENT 3.5 .sp .EX int foo(int value = 5) { return value; } .EE .UNINDENT .UNINDENT .sp A function call expression that uses a default argument will be diagnosed. Calling it without defaults will not cause a warning: .INDENT 0.0 .INDENT 3.5 .sp .EX foo(); // warning foo(0); // no warning .EE .UNINDENT .UNINDENT .sp See the features disallowed in Fuchsia at \% .SS fuchsia\-default\-arguments\-declarations .sp Warns if a function or method is declared with default parameters. .sp For example, the declaration: .INDENT 0.0 .INDENT 3.5 .sp .EX int foo(int value = 5) { return value; } .EE .UNINDENT .UNINDENT .sp will cause a warning. .sp See the features disallowed in Fuchsia at \% .SS fuchsia\-header\-anon\-namespaces .sp The \fIfuchsia\-header\-anon\-namespaces\fP check is an alias, please see misc\-anonymous\-namespace\-in\-header \%<> for more information. .SS fuchsia\-multiple\-inheritance .sp The \fIfuchsia\-multiple\-inheritance\fP check is an alias, please See misc\-multiple\-inheritance \%<> for details. .sp See the features disallowed in Fuchsia at \% .SS fuchsia\-overloaded\-operator .sp Warns if an operator is overloaded, except for the assignment (copy and move) operators. .sp For example: .INDENT 0.0 .INDENT 3.5 .sp .EX int operator+(int); // Warning B &operator=(const B &Other); // No warning B &operator=(B &&Other) // No warning .EE .UNINDENT .UNINDENT .sp See the features disallowed in Fuchsia at \% .SS fuchsia\-statically\-constructed\-objects .sp Warns if global, non\-trivial objects with static storage are constructed, unless the object is statically initialized with a \fBconstexpr\fP constructor or has no explicit constructor. .sp For example: .INDENT 0.0 .INDENT 3.5 .sp .EX class A {}; class B { public: B(int Val) : Val(Val) {} private: int Val; }; class C { public: constexpr C(int Val) : Val(Val) {} C(int Val1, int Val2) : Val(Val1+Val2) {} private: int Val; }; static A a; // No warning, as there is no explicit constructor static C c(0); // No warning, as constructor is constexpr static B b(0); // Warning, as constructor is not constexpr static C c2(0, 1); // Warning, as constructor is not constexpr static int i; // No warning, as it is trivial extern int get_i(); static C c3(get_i());// Warning, as the constructor is dynamically initialized .EE .UNINDENT .UNINDENT .sp See the features disallowed in Fuchsia at \% .SS fuchsia\-temporary\-objects .sp Warns on construction of specific temporary objects in the Zircon kernel. If the object should be flagged, the fully qualified type name must be explicitly passed to the check. .sp For example, given the list of classes \(dqFoo\(dq and \(dqNS::Bar\(dq, all of the following will trigger the warning: .INDENT 0.0 .INDENT 3.5 .sp .EX Foo(); Foo F = Foo(); func(Foo()); namespace NS { Bar(); } .EE .UNINDENT .UNINDENT .sp With the same list, the following will not trigger the warning: .INDENT 0.0 .INDENT 3.5 .sp .EX Foo F; // Non\-temporary construction okay Foo F(param); // Non\-temporary construction okay Foo *F = new Foo(); // New construction okay Bar(); // Not NS::Bar, so okay NS::Bar B; // Non\-temporary construction okay .EE .UNINDENT .UNINDENT .sp Note that objects must be explicitly specified in order to be flagged, and so objects that inherit a specified object will not be flagged. .sp This check matches temporary objects without regard for inheritance and so a prohibited base class type does not similarly prohibit derived class types. .INDENT 0.0 .INDENT 3.5 .sp .EX class Derived : Foo {} // Derived is not explicitly disallowed Derived(); // and so temporary construction is okay .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B Names A semi\-colon\-separated list of fully\-qualified names of C++ classes that should not be constructed as temporaries. Default is empty string. .UNINDENT .SS fuchsia\-trailing\-return .sp Functions that have trailing returns are disallowed, except for those using \fBdecltype\fP specifiers and lambda with otherwise unutterable return types. .sp For example: .INDENT 0.0 .INDENT 3.5 .sp .EX // No warning int add_one(const int arg) { return arg; } // Warning auto get_add_one() \-> int (*)(const int) { return add_one; } .EE .UNINDENT .UNINDENT .sp Exceptions are made for lambdas and \fBdecltype\fP specifiers: .INDENT 0.0 .INDENT 3.5 .sp .EX // No warning auto lambda = [](double x, double y) \-> double {return x + y;}; // No warning template auto fn(const T1 &lhs, const T2 &rhs) \-> decltype(lhs + rhs) { return lhs + rhs; } .EE .UNINDENT .UNINDENT .sp See the features disallowed in Fuchsia at \% .SS fuchsia\-virtual\-inheritance .sp Warns if classes are defined with virtual inheritance. .sp For example, classes should not be defined with virtual inheritance: .INDENT 0.0 .INDENT 3.5 .sp .EX class B : public virtual A {}; // warning .EE .UNINDENT .UNINDENT .sp See the features disallowed in Fuchsia at \% .SS google\-build\-explicit\-make\-pair .sp Check that \fBmake_pair\fP\(aqs template arguments are deduced. .sp G++ 4.6 in C++11 mode fails badly if \fBmake_pair\fP\(aqs template arguments are specified explicitly, and such use isn\(aqt intended in any case. .sp Corresponding cpplint.py check name: \fIbuild/explicit_make_pair\fP\&. .SS google\-build\-namespaces .sp The \fIgoogle\-build\-namespaces\fP check is an alias, please see misc\-anonymous\-namespace\-in\-header \%<> for more information. .sp Finds anonymous namespaces in headers. .sp \% .sp Corresponding cpplint.py check name: \fIbuild/namespaces\fP\&. .SS google\-build\-using\-namespace .sp Finds \fBusing namespace\fP directives. .sp The check implements the following rule of the Google C++ Style Guide \%: .INDENT 0.0 .INDENT 3.5 You may not use a using\-directive to make all names from a namespace available. .UNINDENT .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .EX // Forbidden \-\- This pollutes the namespace. using namespace foo; .EE .UNINDENT .UNINDENT .sp Corresponding cpplint.py check name: \fIbuild/namespaces\fP\&. .SS google\-default\-arguments .sp Checks that default arguments are not given for virtual methods. .sp See \% .SS google\-explicit\-constructor .sp Checks that constructors callable with a single argument and conversion operators are marked explicit to avoid the risk of unintentional implicit conversions. .sp Consider this example: .INDENT 0.0 .INDENT 3.5 .sp .EX struct S { int x; operator bool() const { return true; } }; bool f() { S a{1}; S b{2}; return a == b; } .EE .UNINDENT .UNINDENT .sp The function will return \fBtrue\fP, since the objects are implicitly converted to \fBbool\fP before comparison, which is unlikely to be the intent. .sp The check will suggest inserting \fBexplicit\fP before the constructor or conversion operator declaration. However, copy and move constructors should not be explicit, as well as constructors taking a single \fBinitializer_list\fP argument. .sp This code: .INDENT 0.0 .INDENT 3.5 .sp .EX struct S { S(int a); explicit S(const S&); operator bool() const; ... .EE .UNINDENT .UNINDENT .sp will become .INDENT 0.0 .INDENT 3.5 .sp .EX struct S { explicit S(int a); S(const S&); explicit operator bool() const; ... .EE .UNINDENT .UNINDENT .sp See \% .SS google\-global\-names\-in\-headers .sp Flag global namespace pollution in header files. Right now it only triggers on \fBusing\fP declarations and directives. .sp The relevant style guide section is \%\&. .SS google\-objc\-avoid\-nsobject\-new .sp Finds calls to \fB+new\fP or overrides of it, which are prohibited by the Google Objective\-C style guide. .sp The Google Objective\-C style guide forbids calling \fB+new\fP or overriding it in class implementations, preferring \fB+alloc\fP and \fB\-init\fP methods to instantiate objects. .sp An example: .INDENT 0.0 .INDENT 3.5 .sp .EX NSDate *now = [NSDate new]; Foo *bar = [Foo new]; .EE .UNINDENT .UNINDENT .sp Instead, code should use \fB+alloc\fP/\fB\-init\fP or class factory methods. .INDENT 0.0 .INDENT 3.5 .sp .EX NSDate *now = [NSDate date]; Foo *bar = [[Foo alloc] init]; .EE .UNINDENT .UNINDENT .sp This check corresponds to the Google Objective\-C Style Guide rule Do Not Use +new \%\&. .SS google\-objc\-avoid\-throwing\-exception .sp Finds uses of throwing exceptions usages in Objective\-C files. .sp For the same reason as the Google C++ style guide, we prefer not throwing exceptions from Objective\-C code. .sp The corresponding C++ style guide rule: \% .sp Instead, prefer passing in \fBNSError **\fP and return \fBBOOL\fP to indicate success or failure. .sp A counterexample: .INDENT 0.0 .INDENT 3.5 .sp .EX \- (void)readFile { if ([self isError]) { @throw [NSException exceptionWithName:...]; } } .EE .UNINDENT .UNINDENT .sp Instead, returning an error via \fBNSError **\fP is preferred: .INDENT 0.0 .INDENT 3.5 .sp .EX \- (BOOL)readFileWithError:(NSError **)error { if ([self isError]) { *error = [NSError errorWithDomain:...]; return NO; } return YES; } .EE .UNINDENT .UNINDENT .sp The corresponding style guide rule: \% .SS google\-objc\-function\-naming .sp Finds function declarations in Objective\-C files that do not follow the pattern described in the Google Objective\-C Style Guide. .sp The corresponding style guide rule can be found here: \% .sp All function names should be in Pascal case. Functions whose storage class is not static should have an appropriate prefix. .sp The following code sample does not follow this pattern: .INDENT 0.0 .INDENT 3.5 .sp .EX static bool is_positive(int i) { return i > 0; } bool IsNegative(int i) { return i < 0; } .EE .UNINDENT .UNINDENT .sp The sample above might be corrected to the following code: .INDENT 0.0 .INDENT 3.5 .sp .EX static bool IsPositive(int i) { return i > 0; } bool *ABCIsNegative(int i) { return i < 0; } .EE .UNINDENT .UNINDENT .SS google\-objc\-global\-variable\-declaration .sp Finds global variable declarations in Objective\-C files that do not follow the pattern of variable names in Google\(aqs Objective\-C Style Guide. .sp The corresponding style guide rule: \% .sp All the global variables should follow the pattern of \fBg[A\-Z].*\fP (variables) or \fBk[A\-Z].*\fP (constants). The check will suggest a variable name that follows the pattern if it can be inferred from the original name. .sp For code: .INDENT 0.0 .INDENT 3.5 .sp .EX static NSString* myString = @\(dqhello\(dq; .EE .UNINDENT .UNINDENT .sp The fix will be: .INDENT 0.0 .INDENT 3.5 .sp .EX static NSString* gMyString = @\(dqhello\(dq; .EE .UNINDENT .UNINDENT .sp Another example of constant: .INDENT 0.0 .INDENT 3.5 .sp .EX static NSString* const myConstString = @\(dqhello\(dq; .EE .UNINDENT .UNINDENT .sp The fix will be: .INDENT 0.0 .INDENT 3.5 .sp .EX static NSString* const kMyConstString = @\(dqhello\(dq; .EE .UNINDENT .UNINDENT .sp However for code that prefixed with non\-alphabetical characters like: .INDENT 0.0 .INDENT 3.5 .sp .EX static NSString* __anotherString = @\(dqworld\(dq; .EE .UNINDENT .UNINDENT .sp The check will give a warning message but will not be able to suggest a fix. The user needs to fix it on their own. .SS google\-readability\-avoid\-underscore\-in\-googletest\-name .sp Checks whether there are underscores in googletest test suite names and test names in test macros: .INDENT 0.0 .IP \(bu 2 \fBTEST\fP .IP \(bu 2 \fBTEST_F\fP .IP \(bu 2 \fBTEST_P\fP .IP \(bu 2 \fBTYPED_TEST\fP .IP \(bu 2 \fBTYPED_TEST_P\fP .UNINDENT .sp The \fBFRIEND_TEST\fP macro is not included. .sp For example: .INDENT 0.0 .INDENT 3.5 .sp .EX TEST(TestSuiteName, Illegal_TestName) {} TEST(Illegal_TestSuiteName, TestName) {} .EE .UNINDENT .UNINDENT .sp would trigger the check. Underscores are not allowed \% in test suite name nor test names. .sp The \fBDISABLED_\fP prefix, which may be used to disable test suites and individual tests \%, is removed from the test suite name and test name before checking for underscores. .sp This check does not propose any fixes. .SS google\-readability\-braces\-around\-statements .sp The \fIgoogle\-readability\-braces\-around\-statements\fP check is an alias, please see readability\-braces\-around\-statements \%<> for more information. .SS google\-readability\-casting .sp The \fIgoogle\-readability\-casting\fP check is an alias, please see modernize\-avoid\-c\-style\-cast \%<> for more information. .sp Finds usages of C\-style casts. .sp \% .sp Corresponding cpplint.py check name: \fIreadability/casting\fP\&. .SS google\-readability\-function\-size .sp The \fIgoogle\-readability\-function\-size\fP check is an alias, please see readability\-function\-size \%<> for more information. .SS google\-readability\-namespace\-comments .sp The \fIgoogle\-readability\-namespace\-comments check\fP is an alias, please see llvm\-namespace\-comment \%<> for more information. .SS google\-readability\-todo .sp Finds TODO comments without a username or bug number. .sp The relevant style guide section is \%\&. .sp Corresponding cpplint.py check: \fIreadability/todo\fP .SS Options .INDENT 0.0 .TP .B Style A string specifying the TODO style for fix\-it hints. Accepted values are \fIHyphen\fP and \fIParentheses\fP\&. Default is \fIHyphen\fP\&. .INDENT 7.0 .IP \(bu 2 \fIHyphen\fP will format the fix\-it as: \fB// TODO: username \- details\fP\&. .IP \(bu 2 \fIParentheses\fP will format the fix\-it as: \fB// TODO(username): details\fP\&. .UNINDENT .UNINDENT .SS google\-runtime\-float .sp Finds uses of \fBlong double\fP and suggests against their use due to lack of portability. .sp The corresponding style guide rule: \% .SS google\-runtime\-int .sp Finds uses of \fBshort\fP, \fBlong\fP and \fBlong long\fP and suggest replacing them with \fBu?intXX(_t)?\fP\&. .sp The corresponding style guide rule: \%\&. .sp Corresponding cpplint.py check: \fIruntime/int\fP\&. .SS Options .INDENT 0.0 .TP .B UnsignedTypePrefix A string specifying the unsigned type prefix. Default is \fIuint\fP\&. .UNINDENT .INDENT 0.0 .TP .B SignedTypePrefix A string specifying the signed type prefix. Default is \fIint\fP\&. .UNINDENT .INDENT 0.0 .TP .B TypeSuffix A string specifying the type suffix. Default is an empty string. .UNINDENT .SS google\-runtime\-operator .sp Finds overloads of unary \fBoperator &\fP\&. .sp \% .sp Corresponding cpplint.py check name: \fIruntime/operator\fP\&. .SS google\-upgrade\-googletest\-case .sp Finds uses of deprecated Google Test version 1.9 APIs with names containing \fBcase\fP and replaces them with equivalent APIs with \fBsuite\fP\&. .sp All names containing \fBcase\fP are being replaced to be consistent with the meanings of \(dqtest case\(dq and \(dqtest suite\(dq as used by the International Software Testing Qualifications Board and ISO 29119. .sp The new names are a part of Google Test version 1.9 (release pending). It is recommended that users update their dependency to version 1.9 and then use this check to remove deprecated names. .sp The affected APIs are: .INDENT 0.0 .IP \(bu 2 Member functions of \fBtesting::Test\fP, \fBtesting::TestInfo\fP, \fBtesting::TestEventListener\fP, \fBtesting::UnitTest\fP, and any type inheriting from these types .IP \(bu 2 The macros \fBTYPED_TEST_CASE\fP, \fBTYPED_TEST_CASE_P\fP, \fBREGISTER_TYPED_TEST_CASE_P\fP, and \fBINSTANTIATE_TYPED_TEST_CASE_P\fP .IP \(bu 2 The type alias \fBtesting::TestCase\fP .UNINDENT .sp Examples of fixes created by this check: .INDENT 0.0 .INDENT 3.5 .sp .EX class FooTest : public testing::Test { public: static void SetUpTestCase(); static void TearDownTestCase(); }; TYPED_TEST_CASE(BarTest, BarTypes); .EE .UNINDENT .UNINDENT .sp becomes .INDENT 0.0 .INDENT 3.5 .sp .EX class FooTest : public testing::Test { public: static void SetUpTestSuite(); static void TearDownTestSuite(); }; TYPED_TEST_SUITE(BarTest, BarTypes); .EE .UNINDENT .UNINDENT .sp For better consistency of user code, the check renames both virtual and non\-virtual member functions with matching names in derived types. The check tries to provide only a warning when a fix cannot be made safely, as is the case with some template and macro uses. .SS hicpp\-avoid\-c\-arrays .sp The hicpp\-avoid\-c\-arrays check is an alias, please see modernize\-avoid\-c\-arrays \%<> for more information. It partly enforces the rule 4.1.1 \%\&. .SS hicpp\-avoid\-goto .sp The \fIhicpp\-avoid\-goto\fP check is an alias, please see cppcoreguidelines\-avoid\-goto \%<> for more information. It enforces the rule 6.3.1 \%\&. .SS hicpp\-braces\-around\-statements .sp The \fIhicpp\-braces\-around\-statements\fP check is an alias, please see readability\-braces\-around\-statements \%<> for more information. It enforces the rule 6.1.1 \%\&. .SS hicpp\-deprecated\-headers .sp The \fIhicpp\-deprecated\-headers\fP check is an alias, please see modernize\-deprecated\-headers \%<> for more information. It enforces the rule 1.3.3 \%\&. .SS hicpp\-exception\-baseclass .sp Ensure that every value that in a \fBthrow\fP expression is an instance of \fBstd::exception\fP\&. .sp This enforces rule 15.1 \% of the High Integrity C++ Coding Standard. .INDENT 0.0 .INDENT 3.5 .sp .EX class custom_exception {}; void throwing() noexcept(false) { // Problematic throw expressions. throw int(42); throw custom_exception(); } class mathematical_error : public std::exception {}; void throwing2() noexcept(false) { // These kind of throws are ok. throw mathematical_error(); throw std::runtime_error(); throw std::exception(); } .EE .UNINDENT .UNINDENT .SS hicpp\-explicit\-conversions .sp This check is an alias for google\-explicit\-constructor \%<>\&. .sp Used to enforce parts of rule 5.4.1 \%\&. This check will enforce that constructors and conversion operators are marked \fBexplicit\fP\&. Other forms of casting checks are implemented in other places. The following checks can be used to check for more forms of casting: .INDENT 0.0 .IP \(bu 2 cppcoreguidelines\-pro\-type\-static\-cast\-downcast \%<> .IP \(bu 2 cppcoreguidelines\-pro\-type\-reinterpret\-cast \%<> .IP \(bu 2 cppcoreguidelines\-pro\-type\-const\-cast \%<> .IP \(bu 2 cppcoreguidelines\-pro\-type\-cstyle\-cast \%<> .UNINDENT .SS hicpp\-function\-size .sp This check is an alias for readability\-function\-size \%<>\&. Useful to enforce multiple sections on function complexity. .INDENT 0.0 .IP \(bu 2 rule 8.2.2 \% .IP \(bu 2 rule 8.3.1 \% .IP \(bu 2 rule 8.3.2 \% .UNINDENT .SS hicpp\-ignored\-remove\-result .sp Ensure that the result of \fBstd::remove\fP, \fBstd::remove_if\fP and \fBstd::unique\fP are not ignored according to rule 17.5.1 \%\&. .sp The mutating algorithms \fBstd::remove\fP, \fBstd::remove_if\fP and both overloads of \fBstd::unique\fP operate by swapping or moving elements of the range they are operating over. On completion, they return an iterator to the last valid element. In the majority of cases the correct behavior is to use this result as the first operand in a call to \fBstd::erase\fP\&. .sp This check is a subset of bugprone\-unused\-return\-value \%<> and depending on used options it can be superfluous to enable both checks. .SS Options .INDENT 0.0 .TP .B AllowCastToVoid Controls whether casting return values to \fBvoid\fP is permitted. Default: \fItrue\fP\&. .UNINDENT .SS hicpp\-invalid\-access\-moved .sp This check is an alias for bugprone\-use\-after\-move \%<>\&. .sp Implements parts of the rule 8.4.1 \% to check if moved\-from objects are accessed. .SS hicpp\-member\-init .sp This check is an alias for cppcoreguidelines\-pro\-type\-member\-init \%<>\&. Implements the check for rule 12.4.2 \% to initialize class members in the right order. .SS hicpp\-move\-const\-arg .sp The \fIhicpp\-move\-const\-arg\fP check is an alias, please see performance\-move\-const\-arg \%<> for more information. It enforces the rule 17.3.1 \%\&. .SS hicpp\-multiway\-paths\-covered .sp This check discovers situations where code paths are not fully\-covered. It furthermore suggests using \fBif\fP instead of \fBswitch\fP if the code will be more clear. The rule 6.1.2 \% and rule 6.1.4 \% of the High Integrity C++ Coding Standard are enforced. .sp \fBif\-else if\fP chains that miss a final \fBelse\fP branch might lead to unexpected program execution and be the result of a logical error. If the missing \fBelse\fP branch is intended you can leave it empty with a clarifying comment. This warning can be noisy on some code bases, so it is disabled by default. .INDENT 0.0 .INDENT 3.5 .sp .EX void f1() { int i = determineTheNumber(); if(i > 0) { // Some Calculation } else if (i < 0) { // Precondition violated or something else. } // ... } .EE .UNINDENT .UNINDENT .sp Similar arguments hold for \fBswitch\fP statements which do not cover all possible code paths. .INDENT 0.0 .INDENT 3.5 .sp .EX // The missing default branch might be a logical error. It can be kept empty // if there is nothing to do, making it explicit. void f2(int i) { switch (i) { case 0: // something break; case 1: // something else break; } // All other numbers? } // Violates this rule as well, but already emits a compiler warning (\-Wswitch). enum Color { Red, Green, Blue, Yellow }; void f3(enum Color c) { switch (c) { case Red: // We can\(aqt drive for now. break; case Green: // We are allowed to drive. break; } // Other cases missing } .EE .UNINDENT .UNINDENT .sp The rule 6.1.4 \% requires every \fBswitch\fP statement to have at least two \fBcase\fP labels other than a \fIdefault\fP label. Otherwise, the \fBswitch\fP could be better expressed with an \fBif\fP statement. Degenerated \fBswitch\fP statements without any labels are caught as well. .INDENT 0.0 .INDENT 3.5 .sp .EX // Degenerated switch that could be better written as \(gaif\(ga int i = 42; switch(i) { case 1: // do something here default: // do something else here } // Should rather be the following: if (i == 1) { // do something here } else { // do something here } .EE .UNINDENT .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .EX // A completely degenerated switch will be diagnosed. int i = 42; switch(i) {} .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B WarnOnMissingElse Boolean flag that activates a warning for missing \fBelse\fP branches. Default is \fIfalse\fP\&. .UNINDENT .SS hicpp\-named\-parameter .sp This check is an alias for readability\-named\-parameter \%<>\&. .sp Implements rule 8.2.1 \%\&. .SS hicpp\-new\-delete\-operators .sp This check is an alias for misc\-new\-delete\-overloads \%<>\&. Implements rule 12.3.1 \% to ensure the \fInew\fP and \fIdelete\fP operators have the correct signature. .SS hicpp\-no\-array\-decay .sp The \fIhicpp\-no\-array\-decay\fP check is an alias, please see cppcoreguidelines\-pro\-bounds\-array\-to\-pointer\-decay \%<> for more information. It enforces the rule 4.1.1 \%\&. .SS hicpp\-no\-assembler .sp Checks for assembler statements. Use of inline assembly should be avoided since it restricts the portability of the code. .sp This enforces rule 7.5.1 \% of the High Integrity C++ Coding Standard. .SS hicpp\-no\-malloc .sp The \fIhicpp\-no\-malloc\fP check is an alias, please see cppcoreguidelines\-no\-malloc \%<> for more information. It enforces the rule 5.3.2 \%\&. .SS hicpp\-noexcept\-move .sp This check is an alias for performance\-noexcept\-move\-constructor \%<>\&. Checks rule 12.5.4 \% to mark move assignment and move construction \fInoexcept\fP\&. .SS hicpp\-signed\-bitwise .sp Finds uses of bitwise operations on signed integer types, which may lead to undefined or implementation defined behavior. .sp The according rule is defined in the High Integrity C++ Standard, Section 5.6.1 \%\&. .SS Options .INDENT 0.0 .TP .B IgnorePositiveIntegerLiterals If this option is set to \fItrue\fP, the check will not warn on bitwise operations with positive integer literals, e.g. \fI~0\fP, \fI2 << 1\fP, etc. Default value is \fIfalse\fP\&. .UNINDENT .SS hicpp\-special\-member\-functions .sp This check is an alias for cppcoreguidelines\-special\-member\-functions \%<>\&. Checks that special member functions have the correct signature, according to rule 12.5.7 \%\&. .SS hicpp\-static\-assert .sp The \fIhicpp\-static\-assert\fP check is an alias, please see misc\-static\-assert \%<> for more information. It enforces the rule 7.1.10 \%\&. .SS hicpp\-undelegated\-constructor .sp This check is an alias for bugprone\-undelegated\-constructor \%<>\&. Partially implements rule 12.4.5 \% to find misplaced constructor calls inside a constructor. .INDENT 0.0 .INDENT 3.5 .sp .EX struct Ctor { Ctor(); Ctor(int); Ctor(int, int); Ctor(Ctor *i) { // All Ctor() calls result in a temporary object Ctor(); // did you intend to call a delegated constructor? Ctor(0); // did you intend to call a delegated constructor? Ctor(1, 2); // did you intend to call a delegated constructor? foo(); } }; .EE .UNINDENT .UNINDENT .SS hicpp\-uppercase\-literal\-suffix .sp The hicpp\-uppercase\-literal\-suffix check is an alias, please see readability\-uppercase\-literal\-suffix \%<> for more information. .sp Partially implements rule 4.2.1 \% to ensure that the \fBU\fP suffix is writeln properly. .SS hicpp\-use\-auto .sp The \fIhicpp\-use\-auto\fP check is an alias, please see modernize\-use\-auto \%<> for more information. It enforces the rule 7.1.8 \%\&. .SS hicpp\-use\-emplace .sp The \fIhicpp\-use\-emplace\fP check is an alias, please see modernize\-use\-emplace \%<> for more information. It enforces the rule 17.4.2 \%\&. .SS hicpp\-use\-equals\-default .sp This check is an alias for modernize\-use\-equals\-default \%<>\&. Implements rule 12.5.1 \% to explicitly default special member functions. .SS hicpp\-use\-equals\-delete .sp This check is an alias for modernize\-use\-equals\-delete \%<>\&. Implements rule 12.5.1 \% to explicitly default or delete special member functions. .SS hicpp\-use\-noexcept .sp The \fIhicpp\-use\-noexcept\fP check is an alias, please see modernize\-use\-noexcept \%<> for more information. It enforces the rule 1.3.5 \%\&. .SS hicpp\-use\-nullptr .sp The \fIhicpp\-use\-nullptr\fP check is an alias, please see modernize\-use\-nullptr \%<> for more information. It enforces the rule 2.5.3 \%\&. .SS hicpp\-use\-override .sp This check is an alias for modernize\-use\-override \%<>\&. Implements rule 10.2.1 \% to declare a virtual function \fIoverride\fP when overriding. .SS hicpp\-vararg .sp The \fIhicpp\-vararg\fP check is an alias, please see cppcoreguidelines\-pro\-type\-vararg \%<> for more information. It enforces the rule 14.1.1 \%\&. .SS linuxkernel\-must\-check\-errs .sp Checks Linux kernel code to see if it uses the results from the functions in \fBlinux/err.h\fP\&. Also checks to see if code uses the results from functions that directly return a value from one of these error functions. .sp This is important in the Linux kernel because \fBERR_PTR\fP, \fBPTR_ERR\fP, \fBIS_ERR\fP, \fBIS_ERR_OR_NULL\fP, \fBERR_CAST\fP, and \fBPTR_ERR_OR_ZERO\fP return values must be checked, since positive pointers and negative error codes are being used in the same context. These functions are marked with \fB__attribute__((warn_unused_result))\fP, but some kernel versions do not have this warning enabled for clang. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX /* Trivial unused call to an ERR function */ PTR_ERR_OR_ZERO(some_function_call()); /* A function that returns ERR_PTR. */ void *fn() { ERR_PTR(\-EINVAL); } /* An invalid use of fn. */ fn(); .EE .UNINDENT .UNINDENT .SS llvm\-else\-after\-return .sp The \fIllvm\-else\-after\-return\fP check is an alias, please see readability\-else\-after\-return \%<> for more information. .SS llvm\-header\-guard .sp Finds and fixes header guards that do not adhere to LLVM style. .SS llvm\-include\-order .sp Checks the correct order of \fB#includes\fP\&. .sp See \% .SS llvm\-namespace\-comment .sp \fIgoogle\-readability\-namespace\-comments\fP redirects here as an alias for this check. .sp Checks that long namespaces have a closing comment. .sp \% .sp \% .INDENT 0.0 .INDENT 3.5 .sp .EX namespace n1 { void f(); } // becomes namespace n1 { void f(); } // namespace n1 .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B ShortNamespaceLines Requires the closing brace of the namespace definition to be followed by a closing comment if the body of the namespace has more than \fIShortNamespaceLines\fP lines of code. The value is an unsigned integer that defaults to \fI1U\fP\&. .UNINDENT .INDENT 0.0 .TP .B SpacesBeforeComments An unsigned integer specifying the number of spaces before the comment closing a namespace definition. Default is \fI1U\fP\&. .UNINDENT .INDENT 0.0 .TP .B AllowOmittingNamespaceComments When \fItrue\fP, the check will accept if no namespace comment is present. The check will only fail if the specified namespace comment is different than expected. Default is \fIfalse\fP\&. .UNINDENT .SS llvm\-prefer\-isa\-or\-dyn\-cast\-in\-conditionals .sp Looks at conditionals and finds and replaces cases of \fBcast<>\fP, which will assert rather than return a null pointer, and \fBdyn_cast<>\fP where the return value is not captured. Additionally, finds and replaces cases that match the pattern \fBvar && isa(var)\fP, where \fBvar\fP is evaluated twice. .INDENT 0.0 .INDENT 3.5 .sp .EX // Finds these: if (auto x = cast(y)) {} // is replaced by: if (auto x = dyn_cast(y)) {} if (cast(y)) {} // is replaced by: if (isa(y)) {} if (dyn_cast(y)) {} // is replaced by: if (isa(y)) {} if (var && isa(var)) {} // is replaced by: if (isa_and_nonnull(var.foo())) {} // Other cases are ignored, e.g.: if (auto f = cast(y)\->foo()) {} if (cast(y)\->foo()) {} if (X.cast(y)) {} .EE .UNINDENT .UNINDENT .SS llvm\-prefer\-register\-over\-unsigned .sp Finds historical use of \fBunsigned\fP to hold vregs and physregs and rewrites them to use \fBRegister\fP\&. .sp Currently this works by finding all variables of unsigned integer type whose initializer begins with an implicit cast from \fBRegister\fP to \fBunsigned\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .EX void example(MachineOperand &MO) { unsigned Reg = MO.getReg(); ... } .EE .UNINDENT .UNINDENT .sp becomes: .INDENT 0.0 .INDENT 3.5 .sp .EX void example(MachineOperand &MO) { Register Reg = MO.getReg(); ... } .EE .UNINDENT .UNINDENT .SS llvm\-prefer\-static\-over\-anonymous\-namespace .sp Finds function and variable declarations inside anonymous namespace and suggests replacing them with \fBstatic\fP declarations. .sp The LLVM Coding Standards \% recommend keeping anonymous namespaces as small as possible and only use them for class declarations. For functions and variables the \fBstatic\fP specifier should be preferred for restricting visibility. .sp For example non\-compliant code: .INDENT 0.0 .INDENT 3.5 .sp .EX namespace { class StringSort { public: StringSort(...) bool operator<(const char *RHS) const; }; // warning: place method definition outside of an anonymous namespace bool StringSort::operator<(const char *RHS) const {} // warning: prefer using \(aqstatic\(aq for restricting visibility void runHelper() {} // warning: prefer using \(aqstatic\(aq for restricting visibility int myVariable = 42; } .EE .UNINDENT .UNINDENT .sp Should become: .INDENT 0.0 .INDENT 3.5 .sp .EX // Small anonymous namespace for class declaration namespace { class StringSort { public: StringSort(...) bool operator<(const char *RHS) const; }; } // placed method definition outside of the anonymous namespace bool StringSort::operator<(const char *RHS) const {} // used \(aqstatic\(aq instead of an anonymous namespace static void runHelper() {} // used \(aqstatic\(aq instead of an anonymous namespace static int myVariable = 42; .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B AllowVariableDeclarations When \fItrue\fP, allow variable declarations to be in anonymous namespace. Default value is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B AllowMemberFunctionsInClass When \fItrue\fP, only methods defined in anonymous namespace outside of the corresponding class will be warned. Default value is \fItrue\fP\&. .UNINDENT .SS llvm\-qualified\-auto .sp The \fIllvm\-qualified\-auto check\fP is an alias, please see readability\-qualified\-auto \%<> for more information. .SS llvm\-twine\-local .sp Looks for local \fBTwine\fP variables which are prone to use after frees and should be generally avoided. .INDENT 0.0 .INDENT 3.5 .sp .EX static Twine Moo = Twine(\(dqbark\(dq) + \(dqbah\(dq; // becomes static std::string Moo = (Twine(\(dqbark\(dq) + \(dqbah\(dq).str(); .EE .UNINDENT .UNINDENT .sp The \fBTwine\fP does not own the memory of its contents, so it is not recommended to use \fBTwine\fP created from temporary strings or string literals. .INDENT 0.0 .INDENT 3.5 .sp .EX static Twine getModuleIdentifier(StringRef moduleName) { return moduleName + \(dq_module\(dq; } void foo() { Twine result = getModuleIdentifier(std::string{\(dqabc\(dq} + \(dqdef\(dq); // temporary std::string is destroyed here, result is dangling } .EE .UNINDENT .UNINDENT .sp After applying this fix\-it hints, the code will use \fBstd::string\fP instead of \fBTwine\fP for local variables. However, \fBTwine\fP has lots of methods that are incompatible with \fBstd::string\fP, so the user may need to adjust the code manually after applying the fix\-it hints. .SS llvm\-mlir\-op\-builder .sp Checks for uses of MLIR\(aqs old/to be deprecated \fBOpBuilder::create\fP form and suggests using \fBT::create\fP instead. .SS Example .INDENT 0.0 .INDENT 3.5 .sp .EX builder.create(builder.getUnknownLoc(), \(dqbaz\(dq); .EE .UNINDENT .UNINDENT .sp Transforms to: .INDENT 0.0 .INDENT 3.5 .sp .EX FooOp::create(builder, builder.getUnknownLoc(), \(dqbaz\(dq); .EE .UNINDENT .UNINDENT .SS llvm\-use\-ranges .sp Finds calls to STL library iterator algorithms that could be replaced with LLVM range\-based algorithms from \fBllvm/ADT/STLExtras.h\fP\&. .SS Example .INDENT 0.0 .INDENT 3.5 .sp .EX auto it = std::find(vec.begin(), vec.end(), value); bool all = std::all_of(vec.begin(), vec.end(), [](int x) { return x > 0; }); .EE .UNINDENT .UNINDENT .sp Transforms to: .INDENT 0.0 .INDENT 3.5 .sp .EX auto it = llvm::find(vec, value); bool all = llvm::all_of(vec, [](int x) { return x > 0; }); .EE .UNINDENT .UNINDENT .SS Supported algorithms .sp Calls to the following STL algorithms are checked: .sp \fBstd::all_of\fP, \fBstd::any_of\fP, \fBstd::binary_search\fP, \fBstd::copy\fP, \fBstd::copy_if\fP, \fBstd::count\fP, \fBstd::count_if\fP, \fBstd::equal\fP, \fBstd::fill\fP, \fBstd::find\fP, \fBstd::find_if\fP, \fBstd::find_if_not\fP, \fBstd::for_each\fP, \fBstd::includes\fP, \fBstd::is_sorted\fP, \fBstd::lower_bound\fP, \fBstd::max_element\fP, \fBstd::min_element\fP, \fBstd::mismatch\fP, \fBstd::none_of\fP, \fBstd::partition\fP, \fBstd::partition_point\fP, \fBstd::remove_if\fP, \fBstd::replace\fP, \fBstd::stable_sort\fP, \fBstd::transform\fP, \fBstd::uninitialized_copy\fP, \fBstd::unique\fP, \fBstd::upper_bound\fP\&. .sp The check will add the necessary \fB#include \(dqllvm/ADT/STLExtras.h\(dq\fP directive when applying fixes. .SS llvmlibc\-callee\-namespace .sp Checks all calls resolve to functions within correct namespace. .INDENT 0.0 .INDENT 3.5 .sp .EX // Implementation inside the LIBC_NAMESPACE namespace. // Correct if: // \- LIBC_NAMESPACE is a macro // \- LIBC_NAMESPACE expansion starts with \(ga__llvm_libc\(ga namespace LIBC_NAMESPACE { // Allow calls with the fully qualified name. LIBC_NAMESPACE::strlen(\(dqhello\(dq); // Allow calls to compiler provided functions. (void)__builtin_abs(\-1); // Bare calls are allowed as long as they resolve to the correct namespace. strlen(\(dqworld\(dq); // Disallow calling into functions in the global namespace. ::strlen(\(dq!\(dq); } // namespace LIBC_NAMESPACE .EE .UNINDENT .UNINDENT .SS llvmlibc\-implementation\-in\-namespace .sp Checks that all declarations in the llvm\-libc implementation are within the correct namespace. .INDENT 0.0 .INDENT 3.5 .sp .EX // Implementation inside the LIBC_NAMESPACE_DECL namespace. // Correct if: // \- LIBC_NAMESPACE_DECL is a macro // \- LIBC_NAMESPACE_DECL expansion starts with \(ga[[gnu::visibility(\(dqhidden\(dq)]] __llvm_libc\(ga namespace LIBC_NAMESPACE_DECL { void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {} // Namespaces within LIBC_NAMESPACE_DECL namespace are allowed. namespace inner { int localVar = 0; } // Functions with C linkage are allowed. extern \(dqC\(dq void str_fuzz() {} } // Incorrect: implementation not in the LIBC_NAMESPACE_DECL namespace. void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {} // Incorrect: outer most namespace is not the LIBC_NAMESPACE_DECL macro. namespace something_else { void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {} } // Incorrect: outer most namespace expansion does not start with \(ga[[gnu::visibility(\(dqhidden\(dq)]] __llvm_libc\(ga. #define LIBC_NAMESPACE_DECL custom_namespace namespace LIBC_NAMESPACE_DECL { void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {} } .EE .UNINDENT .UNINDENT .SS llvmlibc\-inline\-function\-decl .sp Checks that all implicitly and explicitly inline functions in header files are tagged with the \fBLIBC_INLINE\fP macro, except for functions implicit to classes or deleted functions. See the libc style guide \% for more information about this macro. .SS llvmlibc\-restrict\-system\-libc\-headers .sp Finds includes of system libc headers not provided by the compiler within llvm\-libc implementations. .INDENT 0.0 .INDENT 3.5 .sp .EX #include // Not allowed because it is part of system libc. #include // Allowed because it is provided by the compiler. #include \(dqinternal/stdio.h\(dq // Allowed because it is NOT part of system libc. .EE .UNINDENT .UNINDENT .sp This check is necessary because accidentally including system libc headers can lead to subtle and hard to detect bugs. For example consider a system libc whose \fBdirent\fP struct has slightly different field ordering than llvm\-libc. While this will compile successfully, this can cause issues during runtime because they are ABI incompatible. .SS Options .INDENT 0.0 .TP .B Includes A string containing a comma separated glob list of allowed include filenames. Similar to the \-checks glob list for running clang\-tidy itself, the two wildcard characters are \fI*\fP and \fI\-\fP, to include and exclude globs, respectively. The default is \fI\-*\fP, which disallows all includes. .sp This can be used to allow known safe includes such as Linux development headers. See portability\-restrict\-system\-includes \%<> for more details. .UNINDENT .SS misc\-anonymous\-namespace\-in\-header .sp Finds anonymous namespaces in headers. .sp Anonymous namespaces in headers can lead to One Definition Rule (ODR) violations because each translation unit including the header will get its own unique version of the symbols. This increases binary size and can cause confusing link\-time errors. .SS References .sp This check corresponds to the CERT C++ Coding Standard rule DCL59\-CPP. Do not define an unnamed namespace in a header file \%\&. .sp Corresponding cpplint.py check name: \fIbuild/namespaces\fP\&. .SS misc\-confusable\-identifiers .sp Warn about confusable identifiers, i.e. identifiers that are visually close to each other, but use different Unicode characters. This detects a potential attack described in CVE\-2021\-42574 \%\&. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX int fo; // Initial character is U+0066 (LATIN SMALL LETTER F). int 𝐟o; // Initial character is U+1D41F (MATHEMATICAL BOLD SMALL F) not U+0066 (LATIN SMALL LETTER F). .EE .UNINDENT .UNINDENT .SS misc\-const\-correctness .sp This check implements detection of local variables which could be declared as \fBconst\fP but are not. Declaring variables as \fBconst\fP is required or recommended by many coding guidelines, such as: ES.25 \% from the C++ Core Guidelines. .sp Please note that this check\(aqs analysis is type\-based only. Variables that are not modified but used to create a non\-const handle that might escape the scope are not diagnosed as potential \fBconst\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .EX // Declare a variable, which is not \(ga\(gaconst\(ga\(ga ... int i = 42; // but use it as read\-only. This means that \(gai\(ga can be declared \(ga\(gaconst\(ga\(ga. int result = i * i; // Before transformation int const result = i * i; // After transformation .EE .UNINDENT .UNINDENT .sp The check can analyze values, pointers and references and pointees: .INDENT 0.0 .INDENT 3.5 .sp .EX // Normal values like built\-ins or objects. int potential_const_int = 42; // Before transformation int const potential_const_int = 42; // After transformation int copy_of_value = potential_const_int; MyClass could_be_const; // Before transformation MyClass const could_be_const; // After transformation could_be_const.const_qualified_method(); // References can be declared const as well. int &reference_value = potential_const_int; // Before transformation int const& reference_value = potential_const_int; // After transformation int another_copy = reference_value; // The similar semantics of pointers are analyzed. int *pointer_variable = &potential_const_int; // Before transformation int const*const pointer_variable = &potential_const_int; // After transformation, both pointer itself and pointee are supported. int last_copy = *pointer_variable; .EE .UNINDENT .UNINDENT .sp The automatic code transformation is only applied to variables that are declared in single declarations. You may want to prepare your code base with readability\-isolate\-declaration \%<> first. .sp Note that there is the check cppcoreguidelines\-avoid\-non\-const\-global\-variables \%<> to enforce \fBconst\fP correctness on all globals. .SS Limitations .sp The check does not run on \fIC\fP code. .sp The check will not analyze templated variables or variables that are instantiation dependent. Different instantiations can result in different \fBconst\fP correctness properties and in general it is not possible to find all instantiations of a template. The template might be used differently in an independent translation unit. .SS Options .INDENT 0.0 .TP .B AnalyzeValues Enable or disable the analysis of ordinary value variables, like \fBint i = 42;\fP\&. Default is \fItrue\fP\&. .INDENT 7.0 .INDENT 3.5 .sp .EX // Warning int i = 42; // No warning int const i = 42; // Warning int a[] = {42, 42, 42}; // No warning int const a[] = {42, 42, 42}; .EE .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B AnalyzeReferences Enable or disable the analysis of reference variables, like \fBint &ref = i;\fP\&. Default is \fItrue\fP\&. .INDENT 7.0 .INDENT 3.5 .sp .EX int i = 42; // Warning int& ref = i; // No warning int const& ref = i; .EE .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B AnalyzePointers Enable or disable the analysis of pointers variables, like \fBint *ptr = &i;\fP\&. For specific checks, see \fBWarnPointersAsValues\fP and \fBWarnPointersAsPointers\fP\&. Default is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B WarnPointersAsValues This option enables the suggestion for \fBconst\fP of the pointer itself. Pointer values have two possibilities to be \fBconst\fP, the pointer and the value pointing to. Default is \fIfalse\fP\&. .INDENT 7.0 .INDENT 3.5 .sp .EX int value = 42; // Warning const int * pointer_variable = &value; // No warning const int *const pointer_variable = &value; .EE .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B WarnPointersAsPointers This option enables the suggestion for \fBconst\fP of the value pointing to. Default is \fItrue\fP\&. .sp Requires \fBAnalyzePointers\fP to be \fItrue\fP\&. .INDENT 7.0 .INDENT 3.5 .sp .EX int value = 42; // No warning const int *const pointer_variable = &value; // Warning int *const pointer_variable = &value; .EE .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B TransformValues Provides fixit\-hints for value types that automatically add \fBconst\fP if its a single declaration. Default is \fItrue\fP\&. .INDENT 7.0 .INDENT 3.5 .sp .EX // Before int value = 42; // After int const value = 42; // Before int a[] = {42, 42, 42}; // After int const a[] = {42, 42, 42}; // Result is modified later in its life\-time. No diagnostic and fixit hint will be emitted. int result = value * 3; result \-= 10; .EE .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B TransformReferences Provides fixit\-hints for reference types that automatically add \fBconst\fP if its a single declaration. Default is \fItrue\fP\&. .INDENT 7.0 .INDENT 3.5 .sp .EX // This variable could still be a constant. But because there is a non\-const reference to // it, it can not be transformed (yet). int value = 42; // The reference \(aqref_value\(aq is not modified and can be made \(aqconst int &ref_value = value;\(aq // Before int &ref_value = value; // After int const &ref_value = value; // Result is modified later in its life\-time. No diagnostic and fixit hint will be emitted. int result = ref_value * 3; result \-= 10; .EE .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B TransformPointersAsValues Provides fixit\-hints for pointers if their pointee is not changed. This does not analyze if the value\-pointed\-to is unchanged! Default is \fIfalse\fP\&. .sp Requires \(aqWarnPointersAsValues\(aq to be \(aqtrue\(aq. .INDENT 7.0 .INDENT 3.5 .sp .EX int value = 42; // Before const int * pointer_variable = &value; // After const int *const pointer_variable = &value; // Before const int * a[] = {&value, &value}; // After const int *const a[] = {&value, &value}; // Before int *ptr_value = &value; // After int *const ptr_value = &value; int result = 100 * (*ptr_value); // Does not modify the pointer itself. // This modification of the pointee is still allowed and not diagnosed. *ptr_value = 0; // The following pointer may not become a \(aqint *const\(aq. int *changing_pointee = &value; changing_pointee = &result; .EE .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B TransformPointersAsPointers Provides fix\-it hints for pointers if the value it pointing to is not changed. Default is \fIfalse\fP\&. .sp Requires \fBWarnPointersAsPointers\fP to be \fItrue\fP\&. .INDENT 7.0 .INDENT 3.5 .sp .EX int value = 42; // Before int * pointer_variable = &value; // After const int * pointer_variable = &value; // Before int * a[] = {&value, &value}; // After const int * a[] = {&value, &value}; .EE .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B AllowedTypes A semicolon\-separated list of names of types that will be excluded from const\-correctness checking. Regular expressions are accepted, e.g. \fB[Rr]ef(erence)?$\fP matches every type with suffix \fBRef\fP, \fBref\fP, \fBReference\fP and \fBreference\fP\&. If a name in the list contains the sequence \fI::\fP, it is matched against the qualified type name (i.e. \fBnamespace::Type\fP), otherwise it is matched against only the type name (i.e. \fBType\fP). Default is empty string. .UNINDENT .SS misc\-coroutine\-hostile\-raii .sp Detects when objects of certain hostile RAII types persists across suspension points in a coroutine. Such hostile types include scoped\-lockable types and types belonging to a configurable denylist. .sp Some objects require that they be destroyed on the same thread that created them. Traditionally this requirement was often phrased as \(dqmust be a local variable\(dq, under the assumption that local variables always work this way. However this is incorrect with C++20 coroutines, since an intervening \fBco_await\fP may cause the coroutine to suspend and later be resumed on another thread. .sp The lifetime of an object that requires being destroyed on the same thread must not encompass a \fBco_await\fP or \fBco_yield\fP point. If you create/destroy an object, you must do so without allowing the coroutine to suspend in the meantime. .sp Following types are considered as hostile: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 Scoped\-lockable types: A scoped\-lockable object persisting across a suspension point is problematic as the lock held by this object could be unlocked by a different thread. This would be undefined behaviour. This includes all types annotated with the \fBscoped_lockable\fP attribute. .IP \(bu 2 Types belonging to a configurable denylist. .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .EX // Call some async API while holding a lock. task coro() { const std::lock_guard l(&mu_); // Oops! The async Bar function may finish on a different // thread from the one that created the lock_guard (and called // Mutex::Lock). After suspension, Mutex::Unlock will be called on the wrong thread. co_await Bar(); } .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B RAIITypesList A semicolon\-separated list of qualified types which should not be allowed to persist across suspension points. Eg: \fImy::lockable;a::b;::my::other::lockable\fP The default value of this option is \fIstd::lock_guard;std::scoped_lock\fP\&. .UNINDENT .INDENT 0.0 .TP .B AllowedAwaitablesList A semicolon\-separated list of qualified types of awaitables types which can be safely awaited while having hostile RAII objects in scope. .sp \fBco_await\fP\-ing an expression of \fBawaitable\fP type is considered safe if the \fBawaitable\fP type is part of this list. RAII objects persisting across such a \fBco_await\fP expression are considered safe and hence are not flagged. .sp Example usage: .INDENT 7.0 .INDENT 3.5 .sp .EX // Consider option AllowedAwaitablesList = \(dqsafe_awaitable\(dq struct safe_awaitable { bool await_ready() noexcept { return false; } void await_suspend(std::coroutine_handle<>) noexcept {} void await_resume() noexcept {} }; auto wait() { return safe_awaitable{}; } task coro() { // This persists across both the co_await\(aqs but is not flagged // because the awaitable is considered safe to await on. const std::lock_guard l(&mu_); co_await safe_awaitable{}; co_await wait(); } .EE .UNINDENT .UNINDENT .sp Eg: \fImy::safe::awaitable;other::awaitable\fP Default is an empty string. .UNINDENT .INDENT 0.0 .TP .B AllowedCallees A semicolon\-separated list of callee function names which can be safely awaited while having hostile RAII objects in scope. Example usage: .INDENT 7.0 .INDENT 3.5 .sp .EX // Consider option AllowedCallees = \(dqnoop\(dq task noop() { co_return; } task coro() { // This persists across the co_await but is not flagged // because the awaitable is considered safe to await on. const std::lock_guard l(&mu_); co_await noop(); } .EE .UNINDENT .UNINDENT .sp Eg: \fImy::safe::await;other::await\fP Default is an empty string. .UNINDENT .SS misc\-definitions\-in\-headers .sp Finds non\-extern non\-inline function and variable definitions in header files, which can lead to potential ODR violations in case these headers are included from multiple translation units. .INDENT 0.0 .INDENT 3.5 .sp .EX // Foo.h int a = 1; // Warning: variable definition. extern int d; // OK: extern variable. namespace N { int e = 2; // Warning: variable definition. } // Warning: variable definition. const char* str = \(dqfoo\(dq; // OK: internal linkage variable definitions are ignored for now. // Although these might also cause ODR violations, we can be less certain and // should try to keep the false\-positive rate down. static int b = 1; const int c = 1; const char* const str2 = \(dqfoo\(dq; constexpr int k = 1; namespace { int x = 1; } // Warning: function definition. int g() { return 1; } // OK: inline function definition is allowed to be defined multiple times. inline int e() { return 1; } class A { public: int f1() { return 1; } // OK: implicitly inline member function definition is allowed. int f2(); static int d; }; // Warning: not an inline member function definition. int A::f2() { return 1; } // OK: class static data member declaration is allowed. int A::d = 1; // OK: function template is allowed. template T f3() { T a = 1; return a; } // Warning: full specialization of a function template is not allowed. template <> int f3() { int a = 1; return a; } template struct B { void f1(); }; // OK: member function definition of a class template is allowed. template void B::f1() {} class CE { constexpr static int i = 5; // OK: inline variable definition. }; inline int i = 5; // OK: inline variable definition. constexpr int f10() { return 0; } // OK: constexpr function implies inline. // OK: C++14 variable templates are inline. template constexpr T pi = T(3.1415926L); .EE .UNINDENT .UNINDENT .sp When \fBclang\-tidy\fP is invoked with the \fI\-\-fix\-notes\fP option, this check provides fixes that automatically add the \fBinline\fP keyword to discovered functions. Please note that the addition of the \fBinline\fP keyword to variables is not currently supported by this check. .SS misc\-header\-include\-cycle .sp Check detects cyclic \fB#include\fP dependencies between user\-defined headers. .INDENT 0.0 .INDENT 3.5 .sp .EX // Header A.hpp #pragma once #include \(dqB.hpp\(dq // Header B.hpp #pragma once #include \(dqC.hpp\(dq // Header C.hpp #pragma once #include \(dqA.hpp\(dq // Include chain: A\->B\->C\->A .EE .UNINDENT .UNINDENT .sp Header files are a crucial part of many C++ programs as they provide a way to organize declarations and definitions shared across multiple source files. However, header files can also create problems when they become entangled in complex dependency cycles. Such cycles can cause issues with compilation times, unnecessary rebuilds, and make it harder to understand the overall structure of the code. .sp To address these issues, a check has been developed to detect cyclic dependencies between header files, also known as \(dqinclude cycles\(dq. An include cycle occurs when a header file \fIA\fP includes header file \fIB\fP, and \fIB\fP (or any subsequent included header file) includes back header file \fIA\fP, resulting in a circular dependency cycle. .sp This check operates at the preprocessor level and specifically analyzes user\-defined headers and their dependencies. It focuses solely on detecting include cycles while disregarding other types or function dependencies. This specialized analysis helps identify and prevent issues related to header file organization. .sp By detecting include cycles early in the development process, developers can identify and resolve these issues before they become more difficult and time\-consuming to fix. This can lead to faster compile times, improved code quality, and a more maintainable codebase overall. Additionally, by ensuring that header files are organized in a way that avoids cyclic dependencies, developers can make their code easier to understand and modify over time. .sp It\(aqs worth noting that only user\-defined headers their dependencies are analyzed, system includes such as standard library headers and third\-party library headers are excluded. System includes are usually well\-designed and free of include cycles, and ignoring them helps to focus on potential issues within the project\(aqs own codebase. This limitation doesn\(aqt diminish the ability to detect \fB#include\fP cycles within the analyzed code. .sp Developers should carefully review any warnings or feedback provided by this solution. While the analysis aims to identify and prevent include cycles, there may be situations where exceptions or modifications are necessary. It\(aqs important to exercise judgment and consider the specific context of the codebase when making adjustments. .SS Options .INDENT 0.0 .TP .B IgnoredFilesList Provides a way to exclude specific files/headers from the warnings raised by a check. This can be achieved by specifying a semicolon\-separated list of regular expressions or filenames. This option can be used as an alternative to \fB//NOLINT\fP when using it is not possible. The default value of this option is an empty string, indicating that no files are ignored by default. .UNINDENT .SS misc\-include\-cleaner .sp Checks for unused and missing includes. Generates findings only for the main file of a translation unit. Findings correspond to \%\&. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX // foo.h class Foo{}; // bar.h #include \(dqbaz.h\(dq class Bar{}; // baz.h class Baz{}; // main.cc #include \(dqbar.h\(dq // OK: uses class Bar from bar.h #include \(dqfoo.h\(dq // warning: unused include \(dqfoo.h\(dq Bar bar; Baz baz; // warning: missing include \(dqbaz.h\(dq .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IgnoreHeaders A semicolon\-separated list of regexes to disable insertion/removal of header files that match this regex as a suffix. E.g., \fIfoo/.*\fP disables insertion/removal for all headers under the directory \fIfoo\fP\&. Default is an empty string, no headers will be ignored. .UNINDENT .INDENT 0.0 .TP .B DeduplicateFindings A boolean that controls whether the check should deduplicate findings for the same symbol. Defaults to \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B UnusedIncludes A boolean that controls whether the check should report unused includes (includes that are not used directly). Defaults to \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B MissingIncludes A boolean that controls whether the check should report missing includes (header files from which symbols are used but which are not directly included). Defaults to \fItrue\fP\&. .UNINDENT .SS misc\-misleading\-bidirectional .sp Warns about unterminated bidirectional unicode sequence, detecting potential attack as described in the Trojan Source \% attack. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX #include int main() { bool isAdmin = false; /*‮ } ⁦if (isAdmin)⁩ ⁦ begin admins only */ std::cout << \(dqYou are an admin.\en\(dq; /* end admins only ‮ { ⁦*/ return 0; } .EE .UNINDENT .UNINDENT .SS misc\-misleading\-identifier .sp Finds identifiers that contain Unicode characters with right\-to\-left direction, which can be confusing as they may change the understanding of a whole statement line, as described in Trojan Source \%\&. .sp An example of such misleading code follows: .INDENT 0.0 .INDENT 3.5 .sp .EX #include short int א = (short int)0; short int ג = (short int)12345; int main() { int א = ג; // a local variable, set to zero? printf(\(dqג is %d\en\(dq, ג); printf(\(dqא is %d\en\(dq, א); } .EE .UNINDENT .UNINDENT .SS misc\-misplaced\-const .sp This check diagnoses when a \fBconst\fP qualifier is applied to a \fBtypedef\fP/ \fBusing\fP to a pointer type rather than to the pointee, because such constructs are often misleading to developers because the \fBconst\fP applies to the pointer rather than the pointee. .sp For instance, in the following code, the resulting type is \fBint * const\fP rather than \fBconst int *\fP: .INDENT 0.0 .INDENT 3.5 .sp .EX typedef int *int_ptr; void f(const int_ptr ptr) { *ptr = 0; // potentially quite unexpectedly the int can be modified here ptr = 0; // does not compile } .EE .UNINDENT .UNINDENT .sp The check does not diagnose when the underlying \fBtypedef\fP/\fBusing\fP type is a pointer to a \fBconst\fP type or a function pointer type. This is because the \fBconst\fP qualifier is less likely to be mistaken because it would be redundant (or disallowed) on the underlying pointee type. .SS misc\-multiple\-inheritance .sp Warns if a class inherits from multiple classes that are not pure virtual. .sp For example, declaring a class that inherits from multiple concrete classes is disallowed: .INDENT 0.0 .INDENT 3.5 .sp .EX class Base_A { public: virtual int foo() { return 0; } }; class Base_B { public: virtual int bar() { return 0; } }; // Warning class Bad_Child1 : public Base_A, Base_B {}; .EE .UNINDENT .UNINDENT .sp A class that inherits from a pure virtual is allowed: .INDENT 0.0 .INDENT 3.5 .sp .EX class Interface_A { public: virtual int foo() = 0; }; class Interface_B { public: virtual int bar() = 0; }; // No warning class Good_Child1 : public Interface_A, Interface_B { virtual int foo() override { return 0; } virtual int bar() override { return 0; } }; .EE .UNINDENT .UNINDENT .SS References .sp See the features disallowed in Fuchsia at \% .SS misc\-new\-delete\-overloads .sp \fIcert\-dcl54\-cpp\fP redirects here as an alias for this check. .sp The check flags overloaded operator \fBnew()\fP and operator \fBdelete()\fP functions that do not have a corresponding free store function defined within the same scope. For instance, the check will flag a class implementation of a non\-placement operator \fBnew()\fP when the class does not also define a non\-placement operator \fBdelete()\fP function as well. .sp The check does not flag implicitly\-defined operators, deleted or private operators, or placement operators. .sp This check corresponds to CERT C++ Coding Standard rule DCL54\-CPP. Overload allocation and deallocation functions as a pair in the same scope \%\&. .SS misc\-no\-recursion .sp Finds strongly connected functions (by analyzing the call graph for SCC\(aqs (Strongly Connected Components) that are loops), diagnoses each function in the cycle, and displays one example of a possible call graph loop (recursion). .sp References: .INDENT 0.0 .IP \(bu 2 CERT C++ Coding Standard rule DCL56\-CPP. Avoid cycles during initialization of static objects \%\&. .IP \(bu 2 JPL Institutional Coding Standard for the C Programming Language (JPL DOCID D\-60411) rule \fI2.4 Do not use direct or indirect recursion\fP\&. .IP \(bu 2 OpenCL Specification, Version 1.2 rule 6.9 Restrictions: i. Recursion is not supported. \%\&. .UNINDENT .SS Limitations .INDENT 0.0 .IP \(bu 2 The check does not handle calls done through function pointers .IP \(bu 2 The check does not handle C++ destructors .UNINDENT .SS misc\-non\-copyable\-objects .sp \fIcert\-fio38\-c\fP redirects here as an alias for this check. .sp Flags dereferences and non\-pointer declarations of objects that are not meant to be passed by value, such as C FILE objects or POSIX \fBpthread_mutex_t\fP objects. .SS References .sp This check corresponds to CERT C++ Coding Standard rule FIO38\-C. Do not copy a FILE object \%\&. .SS misc\-non\-private\-member\-variables\-in\-classes .sp \fIcppcoreguidelines\-non\-private\-member\-variables\-in\-classes\fP redirects here as an alias for this check. .sp Finds classes that contain non\-static data members in addition to user\-declared non\-static member functions and diagnose all data members declared with a non\-\fBpublic\fP access specifier. The data members should be declared as \fBprivate\fP and accessed through member functions instead of exposed to derived classes or class consumers. .SS Options .INDENT 0.0 .TP .B IgnoreClassesWithAllMemberVariablesBeingPublic When \fItrue\fP, allows to completely ignore classes if \fBall\fP the member variables in that class declared with a \fBpublic\fP access specifier. Default is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B IgnorePublicMemberVariables When \fItrue\fP, allows to ignore (not diagnose) \fBall\fP the member variables declared with a \fBpublic\fP access specifier. Default is \fIfalse\fP\&. .UNINDENT .SS misc\-override\-with\-different\-visibility .sp Finds virtual function overrides with different visibility than the function in the base class. This includes for example if a virtual function declared as \fBprivate\fP is overridden and declared as \fBpublic\fP in a subclass. The detected change is the modification of visibility resulting from keywords \fBpublic\fP, \fBprotected\fP, \fBprivate\fP at overridden virtual functions. The check applies to any normal virtual function and optionally to destructors or operators. Use of the \fBusing\fP keyword is not considered as visibility change by this check. .INDENT 0.0 .INDENT 3.5 .sp .EX class A { public: virtual void f_pub(); private: virtual void f_priv(); }; class B: public A { public: void f_priv(); // warning: changed visibility from private to public private: void f_pub(); // warning: changed visibility from public to private }; class C: private A { // no warning: f_pub becomes private in this case but this is from the // private inheritance }; class D: private A { public: void f_pub(); // warning: changed visibility from private to public // \(aqf_pub\(aq would have private access but is forced to be // public }; .EE .UNINDENT .UNINDENT .sp If the visibility is changed in this way, it can indicate bad design or programming error. .sp If a virtual function is private in a subclass but public in the base class, it can still be accessed from a pointer to the subclass if the pointer is converted to the base type. Probably private inheritance can be used instead. .sp A protected virtual function that is made public in a subclass may have valid use cases but similar (not exactly same) effect can be achieved with the \fBusing\fP keyword. .SS Options .INDENT 0.0 .TP .B DisallowedVisibilityChange Controls what kind of change to the visibility will be detected by the check. Possible values are \fIany\fP, \fIwidening\fP, \fInarrowing\fP\&. For example the \fIwidening\fP option will produce warning only if the visibility is changed from more restrictive (\fBprivate\fP) to less restrictive (\fBpublic\fP). Default value is \fIany\fP\&. .UNINDENT .INDENT 0.0 .TP .B CheckDestructors If \fItrue\fP, the check does apply to destructors too. Otherwise destructors are ignored by the check. Default value is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B CheckOperators If \fItrue\fP, the check does apply to overloaded C++ operators (as virtual member functions) too. This includes other special member functions (like conversions) too. This option is probably useful only in rare cases because operators and conversions are not often virtual functions. Default value is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B IgnoredFunctions This option can be used to ignore the check at specific functions. To configure this option, a semicolon\-separated list of function names should be provided. The list can contain regular expressions, in this way it is possible to select all functions of a specific class (like \fIMyClass::.*\fP) or a specific function of any class (like \fImy_function\fP or \fI::.*::my_function\fP). The function names are matched at the base class. Default value is empty string. .UNINDENT .SS misc\-predictable\-rand .sp Warns for the usage of \fBstd::rand()\fP\&. Pseudorandom number generators use mathematical algorithms to produce a sequence of numbers with good statistical properties, but the numbers produced are not genuinely random. The \fBstd::rand()\fP function takes a seed (number), runs a mathematical operation on it and returns the result. By manipulating the seed the result can be predictable. .SS References .sp This check corresponds to the CERT C Coding Standard rules MSC30\-C. Do not use the rand() function for generating pseudorandom numbers \%\&. MSC50\-CPP. Do not use std::rand() for generating pseudorandom numbers \%\&. .SS misc\-redundant\-expression .sp Detect redundant expressions which are typically errors due to copy\-paste. .sp Depending on the operator expressions may be .INDENT 0.0 .IP \(bu 2 redundant, .IP \(bu 2 always \fBtrue\fP, .IP \(bu 2 always \fBfalse\fP, .IP \(bu 2 always a constant (zero or one). .UNINDENT .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX ((x+1) | (x+1)) // (x+1) is redundant (p\->x == p\->x) // always true (p\->x < p\->x) // always false (speed \- speed + 1 == 12) // speed \- speed is always zero int b = a | 4 | a // identical expr on both sides ((x=1) | (x=1)) // expression is identical (DEFINE_1 | DEFINE_1) // same macro on the both sides ((DEF_1 + DEF_2) | (DEF_1+DEF_2)) // expressions differ in spaces only .EE .UNINDENT .UNINDENT .sp Floats are handled except in the case that NaNs are checked like so: .INDENT 0.0 .INDENT 3.5 .sp .EX int TestFloat(float F) { if (F == F) // Identical float values used return 1; return 0; } int TestFloat(float F) { // Testing NaN. if (F != F && F == F) // does not warn return 1; return 0; } .EE .UNINDENT .UNINDENT .SS misc\-static\-assert .sp \fIcert\-dcl03\-c\fP redirects here as an alias for this check. .sp Replaces \fBassert()\fP with \fBstatic_assert()\fP if the condition is evaluable at compile time. .sp The condition of \fBstatic_assert()\fP is evaluated at compile time which is safer and more efficient. .SS misc\-throw\-by\-value\-catch\-by\-reference .sp \fIcert\-err09\-cpp\fP and \fIcert\-err61\-cpp\fP redirect here as aliases of this check. .sp Finds violations of the rule \(dqThrow by value, catch by reference\(dq presented for example in \(dqC++ Coding Standards\(dq by H. Sutter and A. Alexandrescu, as well as the CERT C++ Coding Standard rule ERR61\-CPP. Catch exceptions by lvalue reference \%\&. .INDENT 0.0 .TP .B Exceptions: .INDENT 7.0 .IP \(bu 2 Throwing string literals will not be flagged despite being a pointer. They are not susceptible to slicing and the usage of string literals is idiomatic. .IP \(bu 2 Catching character pointers (\fBchar\fP, \fBwchar_t\fP, unicode character types) will not be flagged to allow catching string literals. .IP \(bu 2 Moved named values will not be flagged as not throwing an anonymous temporary. In this case we can be sure that the user knows that the object can\(aqt be accessed outside catch blocks handling the error. .IP \(bu 2 Throwing function parameters will not be flagged as not throwing an anonymous temporary. This allows helper functions for throwing. .IP \(bu 2 Re\-throwing caught exception variables will not be flagged as not throwing an anonymous temporary. Although this can usually be done by just writing \fBthrow;\fP it happens often enough in real code. .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B CheckThrowTemporaries Triggers detection of violations of the CERT recommendation ERR09\-CPP. Throw anonymous temporaries. Default is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B WarnOnLargeObject Also warns for any large, trivial object caught by value. Catching a large object by value is not dangerous but affects the performance negatively. The maximum size of an object allowed to be caught without warning can be set using the \fIMaxSize\fP option. Default is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B MaxSize Determines the maximum size of an object allowed to be caught without warning. Only applicable if \fBWarnOnLargeObject\fP is set to \fItrue\fP\&. If the option is set by the user to \fIstd::numeric_limits::max()\fP then it reverts to the default value. Default is the size of \fIsize_t\fP\&. .UNINDENT .SS misc\-unconventional\-assign\-operator .sp Finds declarations of assign operators with the wrong return and/or argument types and definitions with good return type but wrong \fBreturn\fP statements. .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 The return type must be \fBClass&\fP\&. .IP \(bu 2 The assignment may be from the class type by value, const lvalue reference, non\-const rvalue reference, or from a completely different type (e.g. \fBint\fP). .IP \(bu 2 Private and deleted operators are ignored. .IP \(bu 2 The operator must always return \fB*this\fP\&. .UNINDENT .UNINDENT .UNINDENT .SS misc\-uniqueptr\-reset\-release .sp Find and replace \fBunique_ptr::reset(release())\fP with \fBstd::move()\fP\&. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX std::unique_ptr x, y; x.reset(y.release()); \-> x = std::move(y); .EE .UNINDENT .UNINDENT .sp If \fBy\fP is already rvalue, \fBstd::move()\fP is not added. \fBx\fP and \fBy\fP can also be \fBstd::unique_ptr*\fP\&. .SS Options .INDENT 0.0 .TP .B IncludeStyle A string specifying which include\-style is used, \fIllvm\fP or \fIgoogle\fP\&. Default is \fIllvm\fP\&. .UNINDENT .SS misc\-unused\-alias\-decls .sp Finds unused namespace alias declarations. .INDENT 0.0 .INDENT 3.5 .sp .EX namespace my_namespace { class C {}; } namespace unused_alias = ::my_namespace; .EE .UNINDENT .UNINDENT .SS misc\-unused\-parameters .sp Finds unused function parameters. Unused parameters may signify a bug in the code (e.g. when a different parameter is used instead). The suggested fixes either comment parameter name out or remove the parameter completely, if all callers of the function are in the same translation unit and can be updated. .sp The check is similar to the \fI\-Wunused\-parameter\fP compiler diagnostic and can be used to prepare a codebase to enabling of that diagnostic. By default the check is more permissive (see \fBStrictMode\fP \%<#\:cmdoption-arg-StrictMode>). .INDENT 0.0 .INDENT 3.5 .sp .EX void a(int i) { /*some code that doesn\(aqt use \(gai\(ga*/ } // becomes void a(int /*i*/) { /*some code that doesn\(aqt use \(gai\(ga*/ } .EE .UNINDENT .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .EX static void staticFunctionA(int i); static void staticFunctionA(int i) { /*some code that doesn\(aqt use \(gai\(ga*/ } // becomes static void staticFunctionA() static void staticFunctionA() { /*some code that doesn\(aqt use \(gai\(ga*/ } .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B StrictMode When \fIfalse\fP (default value), the check will ignore trivially unused parameters, i.e. when the corresponding function has an empty body (and in case of constructors \- no constructor initializers). When the function body is empty, an unused parameter is unlikely to be unnoticed by a human reader, and there\(aqs basically no place for a bug to hide. .UNINDENT .INDENT 0.0 .TP .B IgnoreVirtual Determines whether virtual method parameters should be inspected. Set to \fItrue\fP to ignore them. Default is \fIfalse\fP\&. .UNINDENT .SS misc\-unused\-using\-decls .sp Finds unused \fBusing\fP declarations. .sp Unused \fBusing\fP declarations in header files will not be diagnosed since these using declarations are part of the header\(aqs public API. Allowed header file extensions can be configured via the global option \fIHeaderFileExtensions\fP\&. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX // main.cpp namespace n { class C; } using n::C; // Never actually used. .EE .UNINDENT .UNINDENT .SS misc\-use\-anonymous\-namespace .sp Finds instances of \fBstatic\fP functions or variables declared at global scope that could instead be moved into an anonymous namespace. .sp Anonymous namespaces are the \(dqsuperior alternative\(dq according to the C++ Standard. \fBstatic\fP was proposed for deprecation, but later un\-deprecated to keep C compatibility [1]. \fBstatic\fP is an overloaded term with different meanings in different contexts, so it can create confusion. .sp The following uses of \fBstatic\fP will \fInot\fP be diagnosed: .INDENT 0.0 .IP \(bu 2 Functions or variables in header files, since anonymous namespaces in headers is considered an antipattern. Allowed header file extensions can be configured via the global option \fIHeaderFileExtensions\fP\&. .IP \(bu 2 \fBconst\fP or \fBconstexpr\fP variables, since they already have implicit internal linkage in C++. .UNINDENT .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX // Bad static void foo(); static int x; // Good namespace { void foo(); int x; } // namespace .EE .UNINDENT .UNINDENT .sp [1] Undeprecating static \% .SS misc\-use\-internal\-linkage .sp Detects variables, functions, and classes that can be marked as static or (in C++) moved into an anonymous namespace to enforce internal linkage. .sp Any entity that\(aqs only used within a single file should be given internal linkage. Doing so gives the compiler more information, allowing it to better remove dead code and perform more aggressive optimizations. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX int v1; // can be marked as static void fn1() {} // can be marked as static // already declared as extern extern int v2; void fn3(); // without function body in all declaration, maybe external linkage void fn3(); // === C++\-specific === struct S1 {}; // can be moved into anonymous namespace namespace { // already in anonymous namespace int v2; void fn2(); struct S2 {}; } // export declarations export void fn4() {} export namespace t { void fn5() {} } export int v2; export class C {}; .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B FixMode Selects what kind of a fix the check should provide. The default is \fIUseStatic\fP\&. .INDENT 7.0 .IP \(bu 2 \fINone\fP Don\(aqt fix automatically. .IP \(bu 2 \fIUseStatic\fP Add \fBstatic\fP for internal linkage variable and function. .UNINDENT .UNINDENT .INDENT 0.0 .TP .B AnalyzeFunctions Whether to suggest giving functions internal linkage. Default is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B AnalyzeVariables Whether to suggest giving variables internal linkage. Default is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B AnalyzeTypes (C++ only) Whether to suggest giving user\-defined types (structs, classes, unions, and enums) internal linkage. Default is \fItrue\fP\&. .UNINDENT .SS modernize\-avoid\-bind .sp The check finds uses of \fBstd::bind\fP and \fBboost::bind\fP and replaces them with lambdas. Lambdas will use value\-capture unless reference capture is explicitly requested with \fBstd::ref\fP or \fBboost::ref\fP\&. .sp It supports arbitrary callables including member functions, function objects, and free functions, and all variations thereof. Anything that you can pass to the first argument of \fBbind\fP should be diagnosable. Currently, the only known case where a fix\-it is unsupported is when the same placeholder is specified multiple times in the parameter list. .sp Given: .INDENT 0.0 .INDENT 3.5 .sp .EX int add(int x, int y) { return x + y; } .EE .UNINDENT .UNINDENT .sp Then: .INDENT 0.0 .INDENT 3.5 .sp .EX void f() { int x = 2; auto clj = std::bind(add, x, _1); } .EE .UNINDENT .UNINDENT .sp is replaced by: .INDENT 0.0 .INDENT 3.5 .sp .EX void f() { int x = 2; auto clj = [=](auto && arg1) { return add(x, arg1); }; } .EE .UNINDENT .UNINDENT .sp \fBstd::bind\fP can be hard to read and can result in larger object files and binaries due to type information that will not be produced by equivalent lambdas. .SS Options .INDENT 0.0 .TP .B PermissiveParameterList If the option is set to \fItrue\fP, the check will append \fBauto&&...\fP to the end of every placeholder parameter list. Without this, it is possible for a fix\-it to perform an incorrect transformation in the case where the result of the \fBbind\fP is used in the context of a type erased functor such as \fBstd::function\fP which allows mismatched arguments. Default is is \fIfalse\fP\&. .UNINDENT .sp For example: .INDENT 0.0 .INDENT 3.5 .sp .EX int add(int x, int y) { return x + y; } int foo() { std::function ignore_args = std::bind(add, 2, 2); return ignore_args(3, 3); } .EE .UNINDENT .UNINDENT .sp is valid code, and returns \fI4\fP\&. The actual values passed to \fBignore_args\fP are simply ignored. Without \fBPermissiveParameterList\fP, this would be transformed into .INDENT 0.0 .INDENT 3.5 .sp .EX int add(int x, int y) { return x + y; } int foo() { std::function ignore_args = [] { return add(2, 2); } return ignore_args(3, 3); } .EE .UNINDENT .UNINDENT .sp which will \fInot\fP compile, since the lambda does not contain an \fBoperator()\fP that accepts 2 arguments. With permissive parameter list, it instead generates .INDENT 0.0 .INDENT 3.5 .sp .EX int add(int x, int y) { return x + y; } int foo() { std::function ignore_args = [](auto&&...) { return add(2, 2); } return ignore_args(3, 3); } .EE .UNINDENT .UNINDENT .sp which is correct. .sp This check requires using C++14 or higher to run. .SS modernize\-avoid\-c\-arrays .sp \fIcppcoreguidelines\-avoid\-c\-arrays\fP redirects here as an alias for this check. .sp \fIhicpp\-avoid\-c\-arrays\fP redirects here as an alias for this check. .sp Finds C\-style array types and recommend to use \fBstd::array<>\fP / \fBstd::vector<>\fP\&. All types of C arrays are diagnosed. .sp For parameters of incomplete C\-style array type, it would be better to use \fBstd::span\fP / \fBgsl::span\fP as replacement. .sp However, fix\-it are potentially dangerous in header files and are therefore not emitted right now. .INDENT 0.0 .INDENT 3.5 .sp .EX int a[] = {1, 2}; // warning: do not declare C\-style arrays, use \(aqstd::array\(aq instead int b[1]; // warning: do not declare C\-style arrays, use \(aqstd::array\(aq instead void foo() { int c[b[0]]; // warning: do not declare C VLA arrays, use \(aqstd::vector\(aq instead } template class array { T d[Size]; // warning: do not declare C\-style arrays, use \(aqstd::array\(aq instead int e[1]; // warning: do not declare C\-style arrays, use \(aqstd::array\(aq instead }; array d; // warning: do not declare C\-style arrays, use \(aqstd::array\(aq instead using k = int[4]; // warning: do not declare C\-style arrays, use \(aqstd::array\(aq instead .EE .UNINDENT .UNINDENT .sp However, the \fBextern \(dqC\(dq\fP code is ignored, since it is common to share such headers between C code, and C++ code. .INDENT 0.0 .INDENT 3.5 .sp .EX // Some header extern \(dqC\(dq { int f[] = {1, 2}; // not diagnosed int j[1]; // not diagnosed inline void bar() { { int j[j[0]]; // not diagnosed } } } .EE .UNINDENT .UNINDENT .sp Similarly, the \fBmain()\fP function is ignored. Its second and third parameters can be either \fBchar* argv[]\fP or \fBchar** argv\fP, but cannot be \fBstd::array<>\fP\&. .SS Options .INDENT 0.0 .TP .B AllowStringArrays When set to \fItrue\fP (default is \fIfalse\fP), variables of character array type with deduced length, initialized directly from string literals, will be ignored. This option doesn\(aqt affect cases where length can\(aqt be deduced, resembling pointers, as seen in class members and parameters. Example: .INDENT 7.0 .INDENT 3.5 .sp .EX const char name[] = \(dqSome name\(dq; .EE .UNINDENT .UNINDENT .UNINDENT .SS modernize\-avoid\-c\-style\-cast .sp Finds usages of C\-style casts. .sp C\-style casts can perform a variety of different conversions (\fBconst_cast\fP, \fBstatic_cast\fP, \fBreinterpret_cast\fP, or a combination). This makes them dangerous as the intent is not clear, and they can silently perform unsafe conversions between incompatible types. .sp This check is similar to \fI\-Wold\-style\-cast\fP, but it suggests automated fixes in some cases. The reported locations should not be different from the ones generated by \fI\-Wold\-style\-cast\fP\&. .SS Examples .INDENT 0.0 .INDENT 3.5 .sp .EX class A { public: std::string v; }; A a; double *num = (double*)(&a); // Compiles! Hides danger // num = static_cast(&a); // Won\(aqt compile (good!) num = reinterpret_cast(&a); // Compiles, danger is explicit .EE .UNINDENT .UNINDENT .SS References .sp Corresponding cpplint.py check name: \fIreadability/casting\fP\&. .SS modernize\-avoid\-setjmp\-longjmp .sp Flags all call expressions involving \fBsetjmp()\fP and \fBlongjmp()\fP in C++ code. .sp Exception handling with \fBthrow\fP and \fBcatch\fP should be used instead. .SS References .sp This check corresponds to the CERT C++ Coding Standard rule ERR52\-CPP. Do not use setjmp() or longjmp() \%\&. .SS modernize\-avoid\-variadic\-functions .sp Find all function definitions (but not declarations) of C\-style variadic functions. .sp Instead of C\-style variadic functions, C++ function parameter pack should be used. .SS References .sp This check corresponds to the CERT C++ Coding Standard rule DCL50\-CPP. Do not define a C\-style variadic function \%\&. .SS modernize\-concat\-nested\-namespaces .sp Checks for use of nested namespaces such as \fBnamespace a { namespace b { ... } }\fP and suggests changing to the more concise syntax introduced in C++17: \fBnamespace a::b { ... }\fP\&. Inline namespaces are not modified. .sp For example: .INDENT 0.0 .INDENT 3.5 .sp .EX namespace n1 { namespace n2 { void t(); } } namespace n3 { namespace n4 { namespace n5 { void t(); } } namespace n6 { namespace n7 { void t(); } } } // in c++20 namespace n8 { inline namespace n9 { void t(); } } .EE .UNINDENT .UNINDENT .sp Will be modified to: .INDENT 0.0 .INDENT 3.5 .sp .EX namespace n1::n2 { void t(); } namespace n3 { namespace n4::n5 { void t(); } namespace n6::n7 { void t(); } } // in c++20 namespace n8::inline n9 { void t(); } .EE .UNINDENT .UNINDENT .SS modernize\-deprecated\-headers .sp Some headers from C library were deprecated in C++ and are no longer welcome in C++ codebases. Some have no effect in C++. For more details refer to the C++14 Standard [depr.c.headers] section. .sp This check replaces C standard library headers with their C++ alternatives and removes redundant ones. .INDENT 0.0 .INDENT 3.5 .sp .EX // C++ source file... #include #include // becomes #include // No \(aqstdbool.h\(aq here. .EE .UNINDENT .UNINDENT .sp Important note: the Standard doesn\(aqt guarantee that the C++ headers declare all the same functions in the global namespace. The check in its current form can break the code that uses library symbols from the global namespace. .INDENT 0.0 .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP // deprecated since C++11 .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP // deprecated since C++11 .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP // deprecated since C++11 .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .UNINDENT .sp If the specified standard is older than C++11 the check will only replace headers deprecated before C++11, otherwise \-\- every header that appeared in the previous list. .sp These headers don\(aqt have effect in C++: .INDENT 0.0 .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .UNINDENT .sp The checker ignores \fIinclude\fP directives within \fIextern \(dqC\(dq { ... }\fP blocks, since a library might want to expose some API for C and C++ libraries. .INDENT 0.0 .INDENT 3.5 .sp .EX // C++ source file... extern \(dqC\(dq { #include // Left intact. #include // Left intact. } .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B CheckHeaderFile \fIclang\-tidy\fP cannot know if the header file included by the currently analyzed C++ source file is not included by any other C source files. Hence, to omit false\-positives and wrong fixit\-hints, we ignore emitting reports into header files. One can set this option to \fItrue\fP if they know that the header files in the project are only used by C++ source files. Default is \fIfalse\fP\&. .UNINDENT .SS modernize\-deprecated\-ios\-base\-aliases .sp Detects usage of the deprecated member types of \fBstd::ios_base\fP and replaces those that have a non\-deprecated equivalent. .TS box center; l|l. T{ Deprecated member type T} T{ Replacement T} _ T{ \fBstd::ios_base::io_state\fP T} T{ \fBstd::ios_base::iostate\fP T} _ T{ \fBstd::ios_base::open_mode\fP T} T{ \fBstd::ios_base::openmode\fP T} _ T{ \fBstd::ios_base::seek_dir\fP T} T{ \fBstd::ios_base::seekdir\fP T} _ T{ \fBstd::ios_base::streamoff\fP T} T{ T} _ T{ \fBstd::ios_base::streampos\fP T} T{ T} .TE .SS modernize\-loop\-convert .sp This check converts \fBfor(...; ...; ...)\fP loops to use the new range\-based loops in C++11. .sp Three kinds of loops can be converted: .INDENT 0.0 .IP \(bu 2 Loops over statically allocated arrays. .IP \(bu 2 Loops over containers, using iterators. .IP \(bu 2 Loops over array\-like containers, using \fBoperator[]\fP and \fBat()\fP\&. .UNINDENT .SS MinConfidence option .SS risky .sp In loops where the container expression is more complex than just a reference to a declared expression (a variable, function, enum, etc.), and some part of it appears elsewhere in the loop, we lower our confidence in the transformation due to the increased risk of changing semantics. Transformations for these loops are marked as \fIrisky\fP, and thus will only be converted if the minimum required confidence level is set to \fIrisky\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .EX int arr[10][20]; int l = 5; for (int j = 0; j < 20; ++j) int k = arr[l][j] + l; // using l outside arr[l] is considered risky for (int i = 0; i < obj.getVector().size(); ++i) obj.foo(10); // using \(aqobj\(aq is considered risky .EE .UNINDENT .UNINDENT .sp See Range\-based loops evaluate end() only once for an example of an incorrect transformation when the minimum required confidence level is set to \fIrisky\fP\&. .SS reasonable (Default) .sp If a loop calls \fB\&.end()\fP or \fB\&.size()\fP after each iteration, the transformation for that loop is marked as \fIreasonable\fP, and thus will be converted if the required confidence level is set to \fIreasonable\fP (default) or lower. .INDENT 0.0 .INDENT 3.5 .sp .EX // using size() is considered reasonable for (int i = 0; i < container.size(); ++i) cout << container[i]; .EE .UNINDENT .UNINDENT .SS safe .sp Any other loops that do not match the above criteria to be marked as \fIrisky\fP or \fIreasonable\fP are marked \fIsafe\fP, and thus will be converted if the required confidence level is set to \fIsafe\fP or lower. .INDENT 0.0 .INDENT 3.5 .sp .EX int arr[] = {1,2,3}; for (int i = 0; i < 3; ++i) cout << arr[i]; .EE .UNINDENT .UNINDENT .SS Example .sp Original: .INDENT 0.0 .INDENT 3.5 .sp .EX const int N = 5; int arr[] = {1,2,3,4,5}; vector v; v.push_back(1); v.push_back(2); v.push_back(3); // safe conversion for (int i = 0; i < N; ++i) cout << arr[i]; // reasonable conversion for (vector::iterator it = v.begin(); it != v.end(); ++it) cout << *it; // reasonable conversion for (vector::iterator it = begin(v); it != end(v); ++it) cout << *it; // reasonable conversion for (vector::iterator it = std::begin(v); it != std::end(v); ++it) cout << *it; // reasonable conversion for (int i = 0; i < v.size(); ++i) cout << v[i]; // reasonable conversion for (int i = 0; i < size(v); ++i) cout << v[i]; .EE .UNINDENT .UNINDENT .sp After applying the check with minimum confidence level set to \fIreasonable\fP (default): .INDENT 0.0 .INDENT 3.5 .sp .EX const int N = 5; int arr[] = {1,2,3,4,5}; vector v; v.push_back(1); v.push_back(2); v.push_back(3); // safe conversion for (auto & elem : arr) cout << elem; // reasonable conversion for (auto & elem : v) cout << elem; // reasonable conversion for (auto & elem : v) cout << elem; .EE .UNINDENT .UNINDENT .SS Reverse Iterator Support .sp The converter is also capable of transforming iterator loops which use \fBrbegin\fP and \fBrend\fP for looping backwards over a container. Out of the box this will automatically happen in C++20 mode using the \fBranges\fP library, however the check can be configured to work without C++20 by specifying a function to reverse a range and optionally the header file where that function lives. .SS Options .INDENT 0.0 .TP .B UseCxx20ReverseRanges When set to true convert loops when in C++20 or later mode using \fBstd::views::reverse\fP\&. Default value is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B MakeReverseRangeFunction Specify the function used to reverse an iterator pair, the function should accept a class with \fBrbegin\fP and \fBrend\fP methods and return a class with \fBbegin\fP and \fBend\fP methods that call the \fBrbegin\fP and \fBrend\fP methods respectively. Common examples are \fBstd::views::reverse\fP and \fBllvm::reverse\fP\&. Default value is an empty string. .UNINDENT .INDENT 0.0 .TP .B MakeReverseRangeHeader Specifies the header file where \fBMakeReverseRangeFunction\fP is declared. For the previous examples this option would be set to \fBrange/v3/view/reverse.hpp\fP and \fBllvm/ADT/STLExtras.h\fP respectively. If this is an empty string and \fBMakeReverseRangeFunction\fP is set, the check will proceed on the assumption that the function is already available in the translation unit. This can be wrapped in angle brackets to signify to add the include as a system include. Default value is an empty string. .UNINDENT .INDENT 0.0 .TP .B IncludeStyle A string specifying which include\-style is used, \fIllvm\fP or \fIgoogle\fP\&. Default is \fIllvm\fP\&. .UNINDENT .SS Limitations .sp There are certain situations where the tool may erroneously perform transformations that remove information and change semantics. Users of the tool should be aware of the behavior and limitations of the check outlined by the cases below. .SS Comments inside loop headers .sp Comments inside the original loop header are ignored and deleted when transformed. .INDENT 0.0 .INDENT 3.5 .sp .EX for (int i = 0; i < N; /* This will be deleted */ ++i) { } .EE .UNINDENT .UNINDENT .SS Range\-based loops evaluate end() only once .sp The C++11 range\-based for loop calls \fB\&.end()\fP only once during the initialization of the loop. If in the original loop \fB\&.end()\fP is called after each iteration the semantics of the transformed loop may differ. .INDENT 0.0 .INDENT 3.5 .sp .EX // The following is semantically equivalent to the C++11 range\-based for loop, // therefore the semantics of the header will not change. for (iterator it = container.begin(), e = container.end(); it != e; ++it) { } // Instead of calling .end() after each iteration, this loop will be // transformed to call .end() only once during the initialization of the loop, // which may affect semantics. for (iterator it = container.begin(); it != container.end(); ++it) { } .EE .UNINDENT .UNINDENT .sp As explained above, calling member functions of the container in the body of the loop is considered \fIrisky\fP\&. If the called member function modifies the container the semantics of the converted loop will differ due to \fB\&.end()\fP being called only once. .INDENT 0.0 .INDENT 3.5 .sp .EX bool flag = false; for (vector::iterator it = vec.begin(); it != vec.end(); ++it) { // Add a copy of the first element to the end of the vector. if (!flag) { // This line makes this transformation \(aqrisky\(aq. vec.push_back(*it); flag = true; } cout << *it; } .EE .UNINDENT .UNINDENT .sp The original code above prints out the contents of the container including the newly added element while the converted loop, shown below, will only print the original contents and not the newly added element. .INDENT 0.0 .INDENT 3.5 .sp .EX bool flag = false; for (auto & elem : vec) { // Add a copy of the first element to the end of the vector. if (!flag) { // This line makes this transformation \(aqrisky\(aq vec.push_back(elem); flag = true; } cout << elem; } .EE .UNINDENT .UNINDENT .sp Semantics will also be affected if \fB\&.end()\fP has side effects. For example, in the case where calls to \fB\&.end()\fP are logged the semantics will change in the transformed loop if \fB\&.end()\fP was originally called after each iteration. .INDENT 0.0 .INDENT 3.5 .sp .EX iterator end() { num_of_end_calls++; return container.end(); } .EE .UNINDENT .UNINDENT .SS Overloaded operator\->() with side effects .sp Similarly, if \fBoperator\->()\fP was overloaded to have side effects, such as logging, the semantics will change. If the iterator\(aqs \fBoperator\->()\fP was used in the original loop it will be replaced with \fB.\fP instead due to the implicit dereference as part of the range\-based for loop. Therefore any side effect of the overloaded \fBoperator\->()\fP will no longer be performed. .INDENT 0.0 .INDENT 3.5 .sp .EX for (iterator it = c.begin(); it != c.end(); ++it) { it\->func(); // Using operator\->() } // Will be transformed to: for (auto & elem : c) { elem.func(); // No longer using operator\->() } .EE .UNINDENT .UNINDENT .SS Pointers and references to containers .sp While most of the check\(aqs risk analysis is dedicated to determining whether the iterator or container was modified within the loop, it is possible to circumvent the analysis by accessing and modifying the container through a pointer or reference. .sp If the container were directly used instead of using the pointer or reference the following transformation would have only been applied at the \fIrisky\fP level since calling a member function of the container is considered \fIrisky\fP\&. The check cannot identify expressions associated with the container that are different than the one used in the loop header, therefore the transformation below ends up being performed at the \fIsafe\fP level. .INDENT 0.0 .INDENT 3.5 .sp .EX vector vec; vector *ptr = &vec; vector &ref = vec; for (vector::iterator it = vec.begin(), e = vec.end(); it != e; ++it) { if (!flag) { // Accessing and modifying the container is considered risky, but the risk // level is not raised here. ptr\->push_back(*it); ref.push_back(*it); flag = true; } } .EE .UNINDENT .UNINDENT .SS OpenMP .sp As range\-based for loops are only available since OpenMP 5, this check should not be used on code with a compatibility requirement of OpenMP prior to version 5. It is \fBintentional\fP that this check does not make any attempts to exclude incorrect diagnostics on OpenMP for loops prior to OpenMP 5. .sp To prevent this check to be applied (and to break) OpenMP for loops but still be applied to non\-OpenMP for loops the usage of \fBNOLINT\fP (see Suppressing Undesired Diagnostics \%<#\:clang-tidy-nolint>) on the specific for loops is recommended. .SS modernize\-macro\-to\-enum .sp Replaces groups of adjacent macros with an unscoped anonymous enum. Using an unscoped anonymous enum ensures that everywhere the macro token was used previously, the enumerator name may be safely used. .sp This check can be used to enforce the C++ core guideline Enum.1: Prefer enumerations over macros \%, within the constraints outlined below. .sp Potential macros for replacement must meet the following constraints: .INDENT 0.0 .IP \(bu 2 Macros must expand only to integral literal tokens or expressions of literal tokens. The expression may contain any of the unary operators \fB\-\fP, \fB+\fP, \fB~\fP or \fB!\fP, any of the binary operators \fB,\fP, \fB\-\fP, \fB+\fP, \fB*\fP, \fB/\fP, \fB%\fP, \fB&\fP, \fB|\fP, \fB^\fP, \fB<\fP, \fB>\fP, \fB<=\fP, \fB>=\fP, \fB==\fP, \fB!=\fP, \fB||\fP, \fB&&\fP, \fB<<\fP, \fB>>\fP or \fB<=>\fP, the ternary operator \fB?:\fP and its GNU extension \%\&. Parenthesized expressions are also recognized. This recognizes most valid expressions. In particular, expressions with the \fBsizeof\fP operator are not recognized. .IP \(bu 2 Macros must be defined on sequential source file lines, or with only comment lines in between macro definitions. .IP \(bu 2 Macros must all be defined in the same source file. .IP \(bu 2 Macros must not be defined within a conditional compilation block. (Conditional include guards are exempt from this constraint.) .IP \(bu 2 Macros must not be defined adjacent to other preprocessor directives. .IP \(bu 2 Macros must not be used in any conditional preprocessing directive. .IP \(bu 2 Macros must not be used as arguments to other macros. .IP \(bu 2 Macros must not be undefined. .IP \(bu 2 Macros must be defined at the top\-level, not inside any declaration or definition. .UNINDENT .sp Each cluster of macros meeting the above constraints is presumed to be a set of values suitable for replacement by an anonymous enum. From there, a developer can give the anonymous enum a name and continue refactoring to a scoped enum if desired. Comments on the same line as a macro definition or between subsequent macro definitions are preserved in the output. No formatting is assumed in the provided replacements, although clang\-tidy can optionally format all fixes. .sp \fBWarning:\fP .INDENT 0.0 .INDENT 3.5 Initializing expressions are assumed to be valid initializers for an enum. C requires that enum values fit into an \fBint\fP, but this may not be the case for some accepted constant expressions. For instance \fB1 << 40\fP will not fit into an \fBint\fP when the size of an \fBint\fP is 32 bits. .UNINDENT .UNINDENT .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX #define RED 0xFF0000 #define GREEN 0x00FF00 #define BLUE 0x0000FF #define TM_NONE (\-1) // No method selected. #define TM_ONE 1 // Use tailored method one. #define TM_TWO 2 // Use tailored method two. Method two // is preferable to method one. #define TM_THREE 3 // Use tailored method three. .EE .UNINDENT .UNINDENT .sp becomes .INDENT 0.0 .INDENT 3.5 .sp .EX enum { RED = 0xFF0000, GREEN = 0x00FF00, BLUE = 0x0000FF }; enum { TM_NONE = (\-1), // No method selected. TM_ONE = 1, // Use tailored method one. TM_TWO = 2, // Use tailored method two. Method two // is preferable to method one. TM_THREE = 3 // Use tailored method three. }; .EE .UNINDENT .UNINDENT .SS modernize\-make\-shared .sp This check finds the creation of \fBstd::shared_ptr\fP objects by explicitly calling the constructor and a \fBnew\fP expression, and replaces it with a call to \fBstd::make_shared\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .EX auto my_ptr = std::shared_ptr(new MyPair(1, 2)); // becomes auto my_ptr = std::make_shared(1, 2); .EE .UNINDENT .UNINDENT .sp This check also finds calls to \fBstd::shared_ptr::reset()\fP with a \fBnew\fP expression, and replaces it with a call to \fBstd::make_shared\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .EX my_ptr.reset(new MyPair(1, 2)); // becomes my_ptr = std::make_shared(1, 2); .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B MakeSmartPtrFunction A string specifying the name of make\-shared\-ptr function. Default is \fIstd::make_shared\fP\&. .UNINDENT .INDENT 0.0 .TP .B MakeSmartPtrFunctionHeader A string specifying the corresponding header of make\-shared\-ptr function. Default is \fI\fP\&. .UNINDENT .INDENT 0.0 .TP .B IncludeStyle A string specifying which include\-style is used, \fIllvm\fP or \fIgoogle\fP\&. Default is \fIllvm\fP\&. .UNINDENT .INDENT 0.0 .TP .B IgnoreMacros If set to \fItrue\fP, the check will not give warnings inside macros. Default is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B IgnoreDefaultInitialization If set to \fIfalse\fP, the check does not suggest edits that will transform default initialization into value initialization, as this can cause performance regressions. Default is \fItrue\fP\&. .UNINDENT .SS modernize\-make\-unique .sp This check finds the creation of \fBstd::unique_ptr\fP objects by explicitly calling the constructor and a \fBnew\fP expression, and replaces it with a call to \fBstd::make_unique\fP, introduced in C++14. .INDENT 0.0 .INDENT 3.5 .sp .EX auto my_ptr = std::unique_ptr(new MyPair(1, 2)); // becomes auto my_ptr = std::make_unique(1, 2); .EE .UNINDENT .UNINDENT .sp This check also finds calls to \fBstd::unique_ptr::reset()\fP with a \fBnew\fP expression, and replaces it with a call to \fBstd::make_unique\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .EX my_ptr.reset(new MyPair(1, 2)); // becomes my_ptr = std::make_unique(1, 2); .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B MakeSmartPtrFunction A string specifying the name of make\-unique\-ptr function. Default is \fIstd::make_unique\fP\&. .UNINDENT .INDENT 0.0 .TP .B MakeSmartPtrFunctionHeader A string specifying the corresponding header of make\-unique\-ptr function. Default is \fI\fP\&. .UNINDENT .INDENT 0.0 .TP .B IncludeStyle A string specifying which include\-style is used, \fIllvm\fP or \fIgoogle\fP\&. Default is \fIllvm\fP\&. .UNINDENT .INDENT 0.0 .TP .B IgnoreMacros If set to \fItrue\fP, the check will not give warnings inside macros. Default is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B IgnoreDefaultInitialization If set to \fIfalse\fP, the check does not suggest edits that will transform default initialization into value initialization, as this can cause performance regressions. Default is \fItrue\fP\&. .UNINDENT .SS modernize\-min\-max\-use\-initializer\-list .sp Replaces nested \fBstd::min\fP and \fBstd::max\fP calls with an initializer list where applicable. .sp For instance, consider the following code: .INDENT 0.0 .INDENT 3.5 .sp .EX int a = std::max(std::max(i, j), k); .EE .UNINDENT .UNINDENT .sp The check will transform the above code to: .INDENT 0.0 .INDENT 3.5 .sp .EX int a = std::max({i, j, k}); .EE .UNINDENT .UNINDENT .SS Performance Considerations .sp While this check simplifies the code and makes it more readable, it may cause performance degradation for non\-trivial types due to the need to copy objects into the initializer list. .sp To avoid this, it is recommended to use \fIstd::ref\fP or \fIstd::cref\fP for non\-trivial types: .INDENT 0.0 .INDENT 3.5 .sp .EX std::string b = std::max({std::ref(i), std::ref(j), std::ref(k)}); .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IncludeStyle A string specifying which include\-style is used, \fIllvm\fP or \fIgoogle\fP\&. Default is \fIllvm\fP\&. .UNINDENT .INDENT 0.0 .TP .B IgnoreNonTrivialTypes A boolean specifying whether to ignore non\-trivial types. Default is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B IgnoreTrivialTypesOfSizeAbove An integer specifying the size (in bytes) above which trivial types are ignored. Default is \fI32\fP\&. .UNINDENT .SS modernize\-pass\-by\-value .sp With move semantics added to the language and the standard library updated with move constructors added for many types it is now interesting to take an argument directly by value, instead of by const\-reference, and then copy. This check allows the compiler to take care of choosing the best way to construct the copy. .sp The transformation is usually beneficial when the calling code passes an \fIrvalue\fP and assumes the move construction is a cheap operation. This short example illustrates how the construction of the value happens: .INDENT 0.0 .INDENT 3.5 .sp .EX void foo(std::string s); std::string get_str(); void f(const std::string &str) { foo(str); // lvalue \-> copy construction foo(get_str()); // prvalue \-> move construction } .EE .UNINDENT .UNINDENT .sp \fBNote:\fP .INDENT 0.0 .INDENT 3.5 Currently, only constructors are transformed to make use of pass\-by\-value. Contributions that handle other situations are welcome! .UNINDENT .UNINDENT .SS Pass\-by\-value in constructors .sp Replaces the uses of const\-references constructor parameters that are copied into class fields. The parameter is then moved with \fIstd::move()\fP\&. .sp Since \fBstd::move()\fP is a library function declared in \fI\fP it may be necessary to add this include. The check will add the include directive when necessary. .INDENT 0.0 .INDENT 3.5 .sp .EX #include class Foo { public: \- Foo(const std::string &Copied, const std::string &ReadOnly) \- : Copied(Copied), ReadOnly(ReadOnly) + Foo(std::string Copied, const std::string &ReadOnly) + : Copied(std::move(Copied)), ReadOnly(ReadOnly) {} private: std::string Copied; const std::string &ReadOnly; }; std::string get_cwd(); void f(const std::string &Path) { // The parameter corresponding to \(aqget_cwd()\(aq is move\-constructed. By // using pass\-by\-value in the Foo constructor we managed to avoid a // copy\-construction. Foo foo(get_cwd(), Path); } .EE .UNINDENT .UNINDENT .sp If the parameter is used more than once no transformation is performed since moved objects have an undefined state. It means the following code will be left untouched: .INDENT 0.0 .INDENT 3.5 .sp .EX #include void pass(const std::string &S); struct Foo { Foo(const std::string &S) : Str(S) { pass(S); } std::string Str; }; .EE .UNINDENT .UNINDENT .SS Limitations .sp A situation where the generated code can be wrong is when the object referenced is modified before the assignment in the init\-list through a \(dqhidden\(dq reference. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX std::string s(\(dqfoo\(dq); struct Base { Base() { s = \(dqbar\(dq; } }; struct Derived : Base { \- Derived(const std::string &S) : Field(S) + Derived(std::string S) : Field(std::move(S)) { } std::string Field; }; void f() { \- Derived d(s); // d.Field holds \(dqbar\(dq + Derived d(s); // d.Field holds \(dqfoo\(dq } .EE .UNINDENT .UNINDENT .SS Note about delayed template parsing .sp When delayed template parsing is enabled, constructors part of templated contexts; templated constructors, constructors in class templates, constructors of inner classes of template classes, etc., are not transformed. Delayed template parsing is enabled by default on Windows as a Microsoft extension: Clang Compiler User\(aqs Manual \- Microsoft extensions \%\&. .sp Delayed template parsing can be enabled using the \fI\-fdelayed\-template\-parsing\fP flag and disabled using \fI\-fno\-delayed\-template\-parsing\fP\&. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX template class C { std::string S; public: = // using \-fdelayed\-template\-parsing (default on Windows) = C(const std::string &S) : S(S) {} + // using \-fno\-delayed\-template\-parsing (default on non\-Windows systems) + C(std::string S) : S(std::move(S)) {} }; .EE .UNINDENT .UNINDENT .sp \fBSee also:\fP .INDENT 0.0 .INDENT 3.5 For more information about the pass\-by\-value idiom, read: Want Speed? Pass by Value \%\&. .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IncludeStyle A string specifying which include\-style is used, \fIllvm\fP or \fIgoogle\fP\&. Default is \fIllvm\fP\&. .UNINDENT .INDENT 0.0 .TP .B ValuesOnly When \fItrue\fP, the check only warns about copied parameters that are already passed by value. Default is \fIfalse\fP\&. .UNINDENT .SS modernize\-raw\-string\-literal .sp This check selectively replaces string literals containing escaped characters with raw string literals. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX const char *const Quotes{\(dqembedded \e\(dqquotes\e\(dq\(dq}; const char *const Paragraph{\(dqLine one.\enLine two.\enLine three.\en\(dq}; const char *const SingleLine{\(dqSingle line.\en\(dq}; const char *const TrailingSpace{\(dqLook here \-> \en\(dq}; const char *const Tab{\(dqOne\etTwo\en\(dq}; const char *const Bell{\(dqHello!\ea And welcome!\(dq}; const char *const Path{\(dqC:\e\eProgram Files\e\eVendor\e\eApplication.exe\(dq}; const char *const RegEx{\(dq\e\ew\e\e([a\-z]\e\e)\(dq}; .EE .UNINDENT .UNINDENT .sp becomes .INDENT 0.0 .INDENT 3.5 .sp .EX const char *const Quotes{R\(dq(embedded \(dqquotes\(dq)\(dq}; const char *const Paragraph{\(dqLine one.\enLine two.\enLine three.\en\(dq}; const char *const SingleLine{\(dqSingle line.\en\(dq}; const char *const TrailingSpace{\(dqLook here \-> \en\(dq}; const char *const Tab{\(dqOne\etTwo\en\(dq}; const char *const Bell{\(dqHello!\ea And welcome!\(dq}; const char *const Path{R\(dq(C:\eProgram Files\eVendor\eApplication.exe)\(dq}; const char *const RegEx{R\(dq(\ew\e([a\-z]\e))\(dq}; .EE .UNINDENT .UNINDENT .sp The presence of any of the following escapes can cause the string to be converted to a raw string literal: \fB\e\e\fP, \fB\e\(aq\fP, \fB\e\(dq\fP, \fB\e?\fP, and octal or hexadecimal escapes for printable ASCII characters. .sp A string literal containing only escaped newlines is a common way of writing lines of text output. Introducing physical newlines with raw string literals in this case is likely to impede readability. These string literals are left unchanged. .sp An escaped horizontal tab, form feed, or vertical tab prevents the string literal from being converted. The presence of a horizontal tab, form feed or vertical tab in source code is not visually obvious. .SS Options .INDENT 0.0 .TP .B DelimiterStem Custom delimiter to escape characters in raw string literals. It is used in the following construction: \fBR\(dqstem_delimiter(contents)stem_delimiter\(dq\fP\&. The default value is \fIlit\fP\&. .UNINDENT .INDENT 0.0 .TP .B ReplaceShorterLiterals Controls replacing shorter non\-raw string literals with longer raw string literals. Setting this option to \fItrue\fP enables the replacement. The default value is \fIfalse\fP (shorter literals are not replaced). .UNINDENT .SS modernize\-redundant\-void\-arg .sp Find and remove redundant \fBvoid\fP argument lists. .INDENT 0.0 .TP .B Examples: .TS box center; l|l. T{ Initial code T} T{ Code with applied fixes T} _ T{ \fBint f(void);\fP T} T{ \fBint f();\fP T} _ T{ \fBint (*f(void))(void);\fP T} T{ \fBint (*f())();\fP T} _ T{ \fBtypedef int (*f_t(void))(void);\fP T} T{ \fBtypedef int (*f_t())();\fP T} _ T{ \fBvoid (C::*p)(void);\fP T} T{ \fBvoid (C::*p)();\fP T} _ T{ \fBC::C(void) {}\fP T} T{ \fBC::C() {}\fP T} _ T{ \fBC::~C(void) {}\fP T} T{ \fBC::~C() {}\fP T} .TE .UNINDENT .SS modernize\-replace\-auto\-ptr .sp This check replaces the uses of the deprecated class \fBstd::auto_ptr\fP by \fBstd::unique_ptr\fP (introduced in C++11). The transfer of ownership, done by the copy\-constructor and the assignment operator, is changed to match \fBstd::unique_ptr\fP usage by using explicit calls to \fBstd::move()\fP\&. .sp Migration example: .INDENT 0.0 .INDENT 3.5 .sp .EX \-void take_ownership_fn(std::auto_ptr int_ptr); +void take_ownership_fn(std::unique_ptr int_ptr); void f(int x) { \- std::auto_ptr a(new int(x)); \- std::auto_ptr b; + std::unique_ptr a(new int(x)); + std::unique_ptr b; \- b = a; \- take_ownership_fn(b); + b = std::move(a); + take_ownership_fn(std::move(b)); } .EE .UNINDENT .UNINDENT .sp Since \fBstd::move()\fP is a library function declared in \fB\fP it may be necessary to add this include. The check will add the include directive when necessary. .SS Limitations .INDENT 0.0 .IP \(bu 2 If headers modification is not activated or if a header is not allowed to be changed this check will produce broken code (compilation error), where the headers\(aq code will stay unchanged while the code using them will be changed. .IP \(bu 2 Client code that declares a reference to an \fBstd::auto_ptr\fP coming from code that can\(aqt be migrated (such as a header coming from a 3\s-2\urd\d\s0 party library) will produce a compilation error after migration. This is because the type of the reference will be changed to \fBstd::unique_ptr\fP but the type returned by the library won\(aqt change, binding a reference to \fBstd::unique_ptr\fP from an \fBstd::auto_ptr\fP\&. This pattern doesn\(aqt make much sense and usually \fBstd::auto_ptr\fP are stored by value (otherwise what is the point in using them instead of a reference or a pointer?). .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .EX // <3rd\-party header...> std::auto_ptr get_value(); const std::auto_ptr & get_ref(); // \-std::auto_ptr a(get_value()); +std::unique_ptr a(get_value()); // ok, unique_ptr constructed from auto_ptr \-const std::auto_ptr & p = get_ptr(); +const std::unique_ptr & p = get_ptr(); // won\(aqt compile .EE .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 Non\-instantiated templates aren\(aqt modified. .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .EX template void f() { std::auto_ptr p; } // only \(aqf()\(aq (or similar) will trigger the replacement. .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IncludeStyle A string specifying which include\-style is used, \fIllvm\fP or \fIgoogle\fP\&. Default is \fIllvm\fP\&. .UNINDENT .SS modernize\-replace\-disallow\-copy\-and\-assign\-macro .sp Finds macro expansions of \fBDISALLOW_COPY_AND_ASSIGN(Type)\fP and replaces them with a deleted copy constructor and a deleted assignment operator. .sp Before the \fBdelete\fP keyword was introduced in C++11 it was common practice to declare a copy constructor and an assignment operator as private members. This effectively makes them unusable to the public API of a class. .sp With the advent of the \fBdelete\fP keyword in C++11 we can abandon the \fBprivate\fP access of the copy constructor and the assignment operator and delete the methods entirely. .sp When running this check on a code like this: .INDENT 0.0 .INDENT 3.5 .sp .EX class Foo { private: DISALLOW_COPY_AND_ASSIGN(Foo); }; .EE .UNINDENT .UNINDENT .sp It will be transformed to this: .INDENT 0.0 .INDENT 3.5 .sp .EX class Foo { private: Foo(const Foo &) = delete; const Foo &operator=(const Foo &) = delete; }; .EE .UNINDENT .UNINDENT .SS Limitations .INDENT 0.0 .IP \(bu 2 Notice that the migration example above leaves the \fBprivate\fP access specification untouched. You might want to run the check modernize\-use\-equals\-delete \%<> to get warnings for deleted functions in private sections. .UNINDENT .SS Options .INDENT 0.0 .TP .B MacroName A string specifying the macro name whose expansion will be replaced. Default is \fIDISALLOW_COPY_AND_ASSIGN\fP\&. .UNINDENT .sp See: \% .SS modernize\-replace\-random\-shuffle .sp This check will find occurrences of \fBstd::random_shuffle\fP and replace it with \fBstd::shuffle\fP\&. In C++17 \fBstd::random_shuffle\fP will no longer be available and thus we need to replace it. .sp Below are two examples of what kind of occurrences will be found and two examples of what it will be replaced with. .INDENT 0.0 .INDENT 3.5 .sp .EX std::vector v; // First example std::random_shuffle(vec.begin(), vec.end()); // Second example std::random_shuffle(vec.begin(), vec.end(), randomFunc); .EE .UNINDENT .UNINDENT .sp Both of these examples will be replaced with: .INDENT 0.0 .INDENT 3.5 .sp .EX std::shuffle(vec.begin(), vec.end(), std::mt19937(std::random_device()())); .EE .UNINDENT .UNINDENT .sp The second example will also receive a warning that \fBrandomFunc\fP is no longer supported in the same way as before so if the user wants the same functionality, the user will need to change the implementation of the \fBrandomFunc\fP\&. .sp One thing to be aware of here is that \fBstd::random_device\fP is quite expensive to initialize. So if you are using the code in a performance critical place, you probably want to initialize it elsewhere. .sp Another thing is that the seeding quality of the suggested fix is quite poor: \fBstd::mt19937\fP has an internal state of 624 32\-bit integers, but is only seeded with a single integer. So if you require higher quality randomness, you should consider seeding better, for example: .INDENT 0.0 .INDENT 3.5 .sp .EX std::shuffle(v.begin(), v.end(), []() { std::mt19937::result_type seeds[std::mt19937::state_size]; std::random_device device; std::uniform_int_distribution dist; std::generate(std::begin(seeds), std::end(seeds), [&] { return dist(device); }); std::seed_seq seq(std::begin(seeds), std::end(seeds)); return std::mt19937(seq); }()); .EE .UNINDENT .UNINDENT .SS modernize\-return\-braced\-init\-list .sp Replaces explicit calls to the constructor in a return with a braced initializer list. This way the return type is not needlessly duplicated in the function definition and the return statement. .INDENT 0.0 .INDENT 3.5 .sp .EX Foo bar() { Baz baz; return Foo(baz); } // transforms to: Foo bar() { Baz baz; return {baz}; } .EE .UNINDENT .UNINDENT .SS modernize\-shrink\-to\-fit .sp Replace copy and swap tricks on shrinkable containers with the \fBshrink_to_fit()\fP method call. .sp The \fBshrink_to_fit()\fP method is more readable and more effective than the copy and swap trick to reduce the capacity of a shrinkable container. Note that, the \fBshrink_to_fit()\fP method is only available in C++11 and up. .SS modernize\-type\-traits .sp Converts standard library type traits of the form \fBtraits<...>::type\fP and \fBtraits<...>::value\fP into \fBtraits_t<...>\fP and \fBtraits_v<...>\fP respectively. .sp For example: .INDENT 0.0 .INDENT 3.5 .sp .EX std::is_integral::value std::is_same::value typename std::add_const::type std::make_signed::type .EE .UNINDENT .UNINDENT .sp Would be converted into: .INDENT 0.0 .INDENT 3.5 .sp .EX std::is_integral_v std::is_same_v std::add_const_t std::make_signed_t .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IgnoreMacros If \fItrue\fP don\(aqt diagnose traits defined in macros. .sp Note: Fixes will never be emitted for code inside of macros. .INDENT 7.0 .INDENT 3.5 .sp .EX #define IS_SIGNED(T) std::is_signed::value .EE .UNINDENT .UNINDENT .sp Defaults to \fIfalse\fP\&. .UNINDENT .SS Limitations .sp Does not currently diagnose uses of type traits with nested name specifiers (e.g. \fBstd::chrono::is_clock\fP, \fBstd::chrono::treat_as_floating_point\fP). .SS modernize\-unary\-static\-assert .sp The check diagnoses any \fBstatic_assert\fP declaration with an empty string literal and provides a fix\-it note to replace the declaration with a single\-argument \fBstatic_assert\fP declaration. .sp The check is only applicable for C++17 and later code. .sp The following code: .INDENT 0.0 .INDENT 3.5 .sp .EX void f_textless(int a) { static_assert(sizeof(a) <= 10, \(dq\(dq); } .EE .UNINDENT .UNINDENT .sp is replaced by: .INDENT 0.0 .INDENT 3.5 .sp .EX void f_textless(int a) { static_assert(sizeof(a) <= 10); } .EE .UNINDENT .UNINDENT .SS modernize\-use\-auto .sp This check is responsible for using the \fBauto\fP type specifier for variable declarations to \fIimprove code readability and maintainability\fP\&. For example: .INDENT 0.0 .INDENT 3.5 .sp .EX std::vector::iterator I = my_container.begin(); // transforms to: auto I = my_container.begin(); .EE .UNINDENT .UNINDENT .sp The \fBauto\fP type specifier will only be introduced in situations where the variable type matches the type of the initializer expression. In other words \fBauto\fP should deduce the same type that was originally spelled in the source. However, not every situation should be transformed: .INDENT 0.0 .INDENT 3.5 .sp .EX int val = 42; InfoStruct &I = SomeObject.getInfo(); // Should not become: auto val = 42; auto &I = SomeObject.getInfo(); .EE .UNINDENT .UNINDENT .sp In this example using \fBauto\fP for builtins doesn\(aqt improve readability. In other situations it makes the code less self\-documenting impairing readability and maintainability. As a result, \fBauto\fP is used only introduced in specific situations described below. .SS Iterators .sp Iterator type specifiers tend to be long and used frequently, especially in loop constructs. Since the functions generating iterators have a common format, the type specifier can be replaced without obscuring the meaning of code while improving readability and maintainability. .INDENT 0.0 .INDENT 3.5 .sp .EX for (std::vector::iterator I = my_container.begin(), E = my_container.end(); I != E; ++I) { } // becomes for (auto I = my_container.begin(), E = my_container.end(); I != E; ++I) { } .EE .UNINDENT .UNINDENT .sp The check will only replace iterator type\-specifiers when all of the following conditions are satisfied: .INDENT 0.0 .IP \(bu 2 The iterator is for one of the standard containers in \fBstd\fP namespace: .INDENT 2.0 .IP \(bu 2 \fBarray\fP .IP \(bu 2 \fBdeque\fP .IP \(bu 2 \fBforward_list\fP .IP \(bu 2 \fBlist\fP .IP \(bu 2 \fBvector\fP .IP \(bu 2 \fBmap\fP .IP \(bu 2 \fBmultimap\fP .IP \(bu 2 \fBset\fP .IP \(bu 2 \fBmultiset\fP .IP \(bu 2 \fBunordered_map\fP .IP \(bu 2 \fBunordered_multimap\fP .IP \(bu 2 \fBunordered_set\fP .IP \(bu 2 \fBunordered_multiset\fP .IP \(bu 2 \fBqueue\fP .IP \(bu 2 \fBpriority_queue\fP .IP \(bu 2 \fBstack\fP .UNINDENT .IP \(bu 2 The iterator is one of the possible iterator types for standard containers: .INDENT 2.0 .IP \(bu 2 \fBiterator\fP .IP \(bu 2 \fBreverse_iterator\fP .IP \(bu 2 \fBconst_iterator\fP .IP \(bu 2 \fBconst_reverse_iterator\fP .UNINDENT .IP \(bu 2 In addition to using iterator types directly, typedefs or other ways of referring to those types are also allowed. However, implementation\-specific types for which a type like \fBstd::vector::iterator\fP is itself a typedef will not be transformed. Consider the following examples: .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .EX // The following direct uses of iterator types will be transformed. std::vector::iterator I = MyVec.begin(); { using namespace std; list::iterator I = MyList.begin(); } // The type specifier for J would transform to auto since it\(aqs a typedef // to a standard iterator type. typedef std::map::const_iterator map_iterator; map_iterator J = MyMap.begin(); // The following implementation\-specific iterator type for which // std::vector::iterator could be a typedef would not be transformed. __gnu_cxx::__normal_iterator K = MyVec.begin(); .EE .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 The initializer for the variable being declared is not a braced initializer list. Otherwise, use of \fBauto\fP would cause the type of the variable to be deduced as \fBstd::initializer_list\fP\&. .UNINDENT .SS New expressions .sp Frequently, when a pointer is declared and initialized with \fBnew\fP, the pointee type is written twice: in the declaration type and in the \fBnew\fP expression. In this case, the declaration type can be replaced with \fBauto\fP improving readability and maintainability. .INDENT 0.0 .INDENT 3.5 .sp .EX TypeName *my_pointer = new TypeName(my_param); // becomes auto *my_pointer = new TypeName(my_param); .EE .UNINDENT .UNINDENT .sp The check will also replace the declaration type in multiple declarations, if the following conditions are satisfied: .INDENT 0.0 .IP \(bu 2 All declared variables have the same type (i.e. all of them are pointers to the same type). .IP \(bu 2 All declared variables are initialized with a \fBnew\fP expression. .IP \(bu 2 The types of all the new expressions are the same than the pointee of the declaration type. .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .EX TypeName *my_first_pointer = new TypeName, *my_second_pointer = new TypeName; // becomes auto *my_first_pointer = new TypeName, *my_second_pointer = new TypeName; .EE .UNINDENT .UNINDENT .SS Cast expressions .sp Frequently, when a variable is declared and initialized with a cast, the variable type is written twice: in the declaration type and in the cast expression. In this case, the declaration type can be replaced with \fBauto\fP improving readability and maintainability. .INDENT 0.0 .INDENT 3.5 .sp .EX TypeName *my_pointer = static_cast(my_param); // becomes auto *my_pointer = static_cast(my_param); .EE .UNINDENT .UNINDENT .sp The check handles \fBstatic_cast\fP, \fBdynamic_cast\fP, \fBconst_cast\fP, \fBreinterpret_cast\fP, functional casts, C\-style casts and function templates that behave as casts, such as \fBllvm::dyn_cast\fP, \fBboost::lexical_cast\fP and \fBgsl::narrow_cast\fP\&. Calls to function templates are considered to behave as casts if the first template argument is explicit and is a type, and the function returns that type, or a pointer or reference to it. .SS Limitations .INDENT 0.0 .IP \(bu 2 If the initializer is an explicit conversion constructor, the check will not replace the type specifier even though it would be safe to do so. .IP \(bu 2 User\-defined iterators are not handled at this time. .UNINDENT .SS Options .INDENT 0.0 .TP .B MinTypeNameLength If the option is set to non\-zero (default \fI5\fP), the check will ignore type names having a length less than the option value. The option affects expressions only, not iterators. Spaces between multi\-lexeme type names (\fBlong int\fP) are considered as one. If the \fBRemoveStars\fP option (see below) is set to \fItrue\fP, then \fB*s\fP in the type are also counted as a part of the type name. .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .EX // MinTypeNameLength = 0, RemoveStars=0 int a = static_cast(foo()); // \-\-\-> auto a = ... // length(bool *) = 4 bool *b = new bool; // \-\-\-> auto *b = ... unsigned c = static_cast(foo()); // \-\-\-> auto c = ... // MinTypeNameLength = 5, RemoveStars=0 int a = static_cast(foo()); // \-\-\-> int a = ... bool b = static_cast(foo()); // \-\-\-> bool b = ... bool *pb = static_cast(foo()); // \-\-\-> bool *pb = ... unsigned c = static_cast(foo()); // \-\-\-> auto c = ... // length(long int) = 8 long int d = static_cast(foo()); // \-\-\-> auto d = ... // MinTypeNameLength = 5, RemoveStars=1 int a = static_cast(foo()); // \-\-\-> int a = ... // length(int * * ) = 5 int **pa = static_cast(foo()); // \-\-\-> auto pa = ... bool b = static_cast(foo()); // \-\-\-> bool b = ... bool *pb = static_cast(foo()); // \-\-\-> auto pb = ... unsigned c = static_cast(foo()); // \-\-\-> auto c = ... long int d = static_cast(foo()); // \-\-\-> auto d = ... .EE .UNINDENT .UNINDENT .INDENT 0.0 .TP .B RemoveStars If the option is set to \fItrue\fP (default is \fIfalse\fP), the check will remove stars from the non\-typedef pointer types when replacing type names with \fBauto\fP\&. Otherwise, the check will leave stars. For example: .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .EX TypeName *my_first_pointer = new TypeName, *my_second_pointer = new TypeName; // RemoveStars = 0 auto *my_first_pointer = new TypeName, *my_second_pointer = new TypeName; // RemoveStars = 1 auto my_first_pointer = new TypeName, my_second_pointer = new TypeName; .EE .UNINDENT .UNINDENT .SS modernize\-use\-bool\-literals .sp Finds integer literals which are cast to \fBbool\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .EX bool p = 1; bool f = static_cast(1); std::ios_base::sync_with_stdio(0); bool x = p ? 1 : 0; // transforms to bool p = true; bool f = true; std::ios_base::sync_with_stdio(false); bool x = p ? true : false; .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IgnoreMacros If set to \fItrue\fP, the check will not give warnings inside macros. Default is \fItrue\fP\&. .UNINDENT .SS modernize\-use\-constraints .sp Replace \fBstd::enable_if\fP with C++20 requires clauses. .sp \fBstd::enable_if\fP is a SFINAE mechanism for selecting the desired function or class template based on type traits or other requirements. \fBenable_if\fP changes the meta\-arity of the template, and has other adverse side effects \% in the code. C++20 introduces concepts and constraints as a cleaner language provided solution to achieve the same outcome. .sp This check finds some common \fBstd::enable_if\fP patterns that can be replaced by C++20 requires clauses. The tool can replace some of these patterns automatically, otherwise, the tool will emit a diagnostic without a replacement. The tool can detect the following \fBstd::enable_if\fP patterns .INDENT 0.0 .IP 1. 3 \fBstd::enable_if\fP in the return type of a function .IP 2. 3 \fBstd::enable_if\fP as the trailing template parameter for function templates .UNINDENT .sp Other uses, for example, in class templates for function parameters, are not currently supported by this tool. Other variants such as \fBboost::enable_if\fP are not currently supported by this tool. .sp Below are some examples of code using \fBstd::enable_if\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .EX // enable_if in function return type template std::enable_if_t only_if_t_has_the_trait() { ... } // enable_if in the trailing template parameter template = 0> void another_version() { ... } template typename std::enable_if::type existing_constraint() requires (T::another_value) { return Obj{}; } template = 0> struct my_class {}; .EE .UNINDENT .UNINDENT .sp The tool will replace the above code with, .INDENT 0.0 .INDENT 3.5 .sp .EX // warning: use C++20 requires constraints instead of enable_if [modernize\-use\-constraints] template int only_if_t_has_the_trait() requires T::some_trait { ... } // warning: use C++20 requires constraints instead of enable_if [modernize\-use\-constraints] template void another_version() requires T::some_trait { ... } // The tool will emit a diagnostic for the following, but will // not attempt to replace the code. // warning: use C++20 requires constraints instead of enable_if [modernize\-use\-constraints] template typename std::enable_if::type existing_constraint() requires (T::another_value) { return Obj{}; } // The tool will not emit a diagnostic or attempt to replace the code. template = 0> struct my_class {}; .EE .UNINDENT .UNINDENT .sp \fBNote:\fP .INDENT 0.0 .INDENT 3.5 System headers are not analyzed by this check. .UNINDENT .UNINDENT .SS modernize\-use\-default .sp This check has been renamed to modernize\-use\-equals\-default \%<>\&. .SS modernize\-use\-default\-member\-init .sp This check converts constructors\(aq member initializers into the new default member initializers in C++11. Other member initializers that match the default member initializer are removed. This can reduce repeated code or allow use of \(aq= default\(aq. .INDENT 0.0 .INDENT 3.5 .sp .EX struct A { A() : i(5), j(10.0) {} A(int i) : i(i), j(10.0) {} int i; double j; }; // becomes struct A { A() {} A(int i) : i(i) {} int i{5}; double j{10.0}; }; .EE .UNINDENT .UNINDENT .sp \fBNote:\fP .INDENT 0.0 .INDENT 3.5 Only converts member initializers for built\-in types, enums, and pointers. The \fIreadability\-redundant\-member\-init\fP check will remove redundant member initializers for classes. .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B UseAssignment If this option is set to \fItrue\fP (default is \fIfalse\fP), the check will initialize members with an assignment. For example: .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .EX struct A { A() {} A(int i) : i(i) {} int i = 5; double j = 10.0; }; .EE .UNINDENT .UNINDENT .INDENT 0.0 .TP .B IgnoreMacros If this option is set to \fItrue\fP (default is \fItrue\fP), the check will not warn about members declared inside macros. .UNINDENT .SS modernize\-use\-designated\-initializers .sp Finds initializer lists for aggregate types which could be written as designated initializers instead. .sp With plain initializer lists, it is very easy to introduce bugs when adding new fields in the middle of a struct or class type. The same confusion might arise when changing the order of fields. .sp C++20 supports the designated initializer syntax for aggregate types. By applying it, we can always be sure that aggregates are constructed correctly, because every variable being initialized is referenced by its name. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX struct S { int i, j; }; .EE .UNINDENT .UNINDENT .sp is an aggregate type that should be initialized as .INDENT 0.0 .INDENT 3.5 .sp .EX S s{.i = 1, .j = 2}; .EE .UNINDENT .UNINDENT .sp instead of .INDENT 0.0 .INDENT 3.5 .sp .EX S s{1, 2}; .EE .UNINDENT .UNINDENT .sp which could easily become an issue when \fBi\fP and \fBj\fP are swapped in the declaration of \fBS\fP\&. .sp Even when compiling in a language version older than C++20, depending on your compiler, designated initializers are potentially supported. Therefore, the check is by default restricted to C99/C++20 and above. Check out the options \fI\-Wc99\-designator\fP to get support for mixed designators in initializer list in C and \fI\-Wc++20\-designator\fP for support of designated initializers in older C++ language modes. .SS Options .INDENT 0.0 .TP .B IgnoreMacros The value \fIfalse\fP specifies that components of initializer lists expanded from macros are not checked. The default value is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B IgnoreSingleElementAggregates The value \fIfalse\fP specifies that even initializers for aggregate types with only a single element should be checked. The default value is \fItrue\fP\&. \fBstd::array\fP initializations are always excluded, as the type is a standard library abstraction and not intended to be initialized with designated initializers. .UNINDENT .INDENT 0.0 .TP .B RestrictToPODTypes The value \fItrue\fP specifies that only Plain Old Data (POD) types shall be checked. This makes the check applicable to even older C++ standards. The default value is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B StrictCStandardCompliance When set to \fIfalse\fP, the check will not restrict itself to C99 and above. The default value is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B StrictCppStandardCompliance When set to \fIfalse\fP, the check will not restrict itself to C++20 and above. The default value is \fItrue\fP\&. .UNINDENT .SS modernize\-use\-emplace .sp The check flags insertions to an STL\-style container done by calling the \fBpush_back\fP, \fBpush\fP, or \fBpush_front\fP methods with an explicitly\-constructed temporary of the container element type. In this case, the corresponding \fBemplace\fP equivalent methods result in less verbose and potentially more efficient code. Right now the check doesn\(aqt support \fBinsert\fP\&. It also doesn\(aqt support \fBinsert\fP functions for associative containers because replacing \fBinsert\fP with \fBemplace\fP may result in speed regression \%, but it might get support with some addition flag in the future. .sp The \fBContainersWithPushBack\fP, \fBContainersWithPush\fP, and \fBContainersWithPushFront\fP options are used to specify the container types that support the \fBpush_back\fP, \fBpush\fP, and \fBpush_front\fP operations respectively. The default values for these options are as follows: .INDENT 0.0 .IP \(bu 2 \fBContainersWithPushBack\fP: \fBstd::vector\fP, \fBstd::deque\fP, and \fBstd::list\fP\&. .IP \(bu 2 \fBContainersWithPush\fP: \fBstd::stack\fP, \fBstd::queue\fP, and \fBstd::priority_queue\fP\&. .IP \(bu 2 \fBContainersWithPushFront\fP: \fBstd::forward_list\fP, \fBstd::list\fP, and \fBstd::deque\fP\&. .UNINDENT .sp This check also reports when an \fBemplace\fP\-like method is improperly used, for example using \fBemplace_back\fP while also calling a constructor. This creates a temporary that requires at best a move and at worst a copy. Almost all \fBemplace\fP\-like functions in the STL are covered by this, with \fBtry_emplace\fP on \fBstd::map\fP and \fBstd::unordered_map\fP being the exception as it behaves slightly differently than all the others. More containers can be added with the \fBEmplacyFunctions\fP option, so long as the container defines a \fBvalue_type\fP type, and the \fBemplace\fP\-like functions construct a \fBvalue_type\fP object. .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .EX std::vector v; v.push_back(MyClass(21, 37)); v.emplace_back(MyClass(21, 37)); std::vector> w; w.push_back(std::pair(21, 37)); w.push_back(std::make_pair(21L, 37L)); w.emplace_back(std::make_pair(21L, 37L)); .EE .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .EX std::vector v; v.emplace_back(21, 37); v.emplace_back(21, 37); std::vector> w; w.emplace_back(21, 37); w.emplace_back(21L, 37L); w.emplace_back(21L, 37L); .EE .UNINDENT .UNINDENT .sp By default, the check is able to remove unnecessary \fBstd::make_pair\fP and \fBstd::make_tuple\fP calls from \fBpush_back\fP calls on containers of \fBstd::pair\fP and \fBstd::tuple\fP\&. Custom tuple\-like types can be modified by the \fBTupleTypes\fP option; custom make functions can be modified by the \fBTupleMakeFunctions\fP option. .sp The other situation is when we pass arguments that will be converted to a type inside a container. .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .EX std::vector > v; v.push_back(\(dqabc\(dq); .EE .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .EX std::vector > v; v.emplace_back(\(dqabc\(dq); .EE .UNINDENT .UNINDENT .sp In some cases the transformation would be valid, but the code wouldn\(aqt be exception safe. In this case the calls of \fBpush_back\fP won\(aqt be replaced. .INDENT 0.0 .INDENT 3.5 .sp .EX std::vector> v; v.push_back(std::unique_ptr(new int(0))); auto *ptr = new int(1); v.push_back(std::unique_ptr(ptr)); .EE .UNINDENT .UNINDENT .sp This is because replacing it with \fBemplace_back\fP could cause a leak of this pointer if \fBemplace_back\fP would throw exception before emplacement (e.g. not enough memory to add a new element). .sp For more info read item 42 \- \(dqConsider emplacement instead of insertion.\(dq of Scott Meyers \(dqEffective Modern C++\(dq. .sp The default smart pointers that are considered are \fBstd::unique_ptr\fP, \fBstd::shared_ptr\fP, \fBstd::auto_ptr\fP\&. To specify other smart pointers or other classes use the \fBSmartPointers\fP option. .sp Check also doesn\(aqt fire if any argument of the constructor call would be: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 a bit\-field (bit\-fields can\(aqt bind to rvalue/universal reference) .IP \(bu 2 a \fBnew\fP expression (to avoid leak) .IP \(bu 2 if the argument would be converted via derived\-to\-base cast. .UNINDENT .UNINDENT .UNINDENT .sp This check requires C++11 or higher to run. .SS Options .INDENT 0.0 .TP .B ContainersWithPushBack Semicolon\-separated list of class names of custom containers that support \fBpush_back\fP\&. .UNINDENT .INDENT 0.0 .TP .B ContainersWithPush Semicolon\-separated list of class names of custom containers that support \fBpush\fP\&. .UNINDENT .INDENT 0.0 .TP .B ContainersWithPushFront Semicolon\-separated list of class names of custom containers that support \fBpush_front\fP\&. .UNINDENT .INDENT 0.0 .TP .B IgnoreImplicitConstructors When \fItrue\fP, the check will ignore implicitly constructed arguments of \fBpush_back\fP, e.g. .INDENT 7.0 .INDENT 3.5 .sp .EX std::vector v; v.push_back(\(dqa\(dq); // Ignored when IgnoreImplicitConstructors is \(gatrue\(ga. .EE .UNINDENT .UNINDENT .sp Default is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B SmartPointers Semicolon\-separated list of class names of custom smart pointers. .UNINDENT .INDENT 0.0 .TP .B TupleTypes Semicolon\-separated list of \fBstd::tuple\fP\-like class names. .UNINDENT .INDENT 0.0 .TP .B TupleMakeFunctions Semicolon\-separated list of \fBstd::make_tuple\fP\-like function names. Those function calls will be removed from \fBpush_back\fP calls and turned into \fBemplace_back\fP\&. .UNINDENT .INDENT 0.0 .TP .B EmplacyFunctions Semicolon\-separated list of containers without their template parameters and some \fBemplace\fP\-like method of the container. Example: \fBvector::emplace_back\fP\&. Those methods will be checked for improper use and the check will report when a temporary is unnecessarily created. All STL containers with such member functions are supported by default. .UNINDENT .SS Example .INDENT 0.0 .INDENT 3.5 .sp .EX std::vector> x; x.push_back(MakeMyTuple(1, false, \(aqx\(aq)); x.emplace_back(MakeMyTuple(1, false, \(aqx\(aq)); .EE .UNINDENT .UNINDENT .sp transforms to: .INDENT 0.0 .INDENT 3.5 .sp .EX std::vector> x; x.emplace_back(1, false, \(aqx\(aq); x.emplace_back(1, false, \(aqx\(aq); .EE .UNINDENT .UNINDENT .sp when \fBTupleTypes\fP is set to \fBMyTuple\fP, \fBTupleMakeFunctions\fP is set to \fBMakeMyTuple\fP, and \fBEmplacyFunctions\fP is set to \fBvector::emplace_back\fP\&. .SS modernize\-use\-equals\-default .sp This check replaces default bodies of special member functions with \fB= default;\fP\&. The explicitly defaulted function declarations enable more opportunities in optimization, because the compiler might treat explicitly defaulted functions as trivial. .INDENT 0.0 .INDENT 3.5 .sp .EX struct A { A() {} ~A(); }; A::~A() {} // becomes struct A { A() = default; ~A(); }; A::~A() = default; .EE .UNINDENT .UNINDENT .sp \fBNote:\fP .INDENT 0.0 .INDENT 3.5 Move\-constructor and move\-assignment operator are not supported yet. .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IgnoreMacros If set to \fItrue\fP, the check will not give warnings inside macros and will ignore special members with bodies contain macros or preprocessor directives. Default is \fItrue\fP\&. .UNINDENT .SS modernize\-use\-equals\-delete .sp Identifies unimplemented private special member functions, and recommends using \fB= delete\fP for them. Additionally, it recommends relocating any deleted member function from the \fBprivate\fP to the \fBpublic\fP section. .sp Before the introduction of C++11, the primary method to effectively \(dqerase\(dq a particular function involved declaring it as \fBprivate\fP without providing a definition. This approach would result in either a compiler error (when attempting to call a private function) or a linker error (due to an undefined reference). .sp However, subsequent to the advent of C++11, a more conventional approach emerged for achieving this purpose. It involves flagging functions as \fB= delete\fP and keeping them in the \fBpublic\fP section of the class. .sp To prevent false positives, this check is only active within a translation unit where all other member functions have been implemented. The check will generate partial fixes by introducing \fB= delete\fP, but the user is responsible for manually relocating functions to the \fBpublic\fP section. .INDENT 0.0 .INDENT 3.5 .sp .EX // Example: bad class A { private: A(const A&); A& operator=(const A&); }; // Example: good class A { public: A(const A&) = delete; A& operator=(const A&) = delete; }; .EE .UNINDENT .UNINDENT .INDENT 0.0 .TP .B IgnoreMacros If this option is set to \fItrue\fP (default is \fItrue\fP), the check will not warn about functions declared inside macros. .UNINDENT .SS modernize\-use\-integer\-sign\-comparison .sp Replace comparisons between signed and unsigned integers with their safe C++20 \fBstd::cmp_*\fP alternative, if available. .sp The check provides a replacement only for C++20 or later, otherwise it highlights the problem and expects the user to fix it manually. .sp Examples of fixes created by the check: .INDENT 0.0 .INDENT 3.5 .sp .EX unsigned int func(int a, unsigned int b) { return a == b; } .EE .UNINDENT .UNINDENT .sp becomes .INDENT 0.0 .INDENT 3.5 .sp .EX #include unsigned int func(int a, unsigned int b) { return std::cmp_equal(a, b); } .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IncludeStyle A string specifying which include\-style is used, \fIllvm\fP or \fIgoogle\fP\&. Default is \fIllvm\fP\&. .UNINDENT .INDENT 0.0 .TP .B EnableQtSupport Makes C++17 \fBq20::cmp_*\fP alternative available for Qt\-based applications. Default is \fIfalse\fP\&. .UNINDENT .SS modernize\-use\-nodiscard .sp Adds \fB[[nodiscard]]\fP attributes (introduced in C++17) to member functions in order to highlight at compile time which return values should not be ignored. .sp Member functions need to satisfy the following conditions to be considered by this check: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 no \fB[[nodiscard]]\fP, \fB[[noreturn]]\fP, \fB__attribute__((warn_unused_result))\fP, \fB[[clang::warn_unused_result]]\fP nor \fB[[gcc::warn_unused_result]]\fP attribute, .IP \(bu 2 non\-void return type, .IP \(bu 2 non\-template return types, .IP \(bu 2 const member function, .IP \(bu 2 non\-variadic functions, .IP \(bu 2 no non\-const reference parameters, .IP \(bu 2 no pointer parameters, .IP \(bu 2 no template parameters, .IP \(bu 2 no template function parameters, .IP \(bu 2 not be a member of a class with mutable member variables, .IP \(bu 2 no Lambdas, .IP \(bu 2 no conversion functions. .UNINDENT .UNINDENT .UNINDENT .sp Such functions have no means of altering any state or passing values other than via the return type. Unless the member functions are altering state via some external call (e.g. I/O). .SS Example .INDENT 0.0 .INDENT 3.5 .sp .EX bool empty() const; bool empty(int i) const; .EE .UNINDENT .UNINDENT .sp transforms to: .INDENT 0.0 .INDENT 3.5 .sp .EX [[nodiscard]] bool empty() const; [[nodiscard]] bool empty(int i) const; .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B ReplacementString Specifies a macro to use instead of \fB[[nodiscard]]\fP\&. This is useful when maintaining source code that needs to compile with a pre\-C++17 compiler. .UNINDENT .SS Example .INDENT 0.0 .INDENT 3.5 .sp .EX bool empty() const; bool empty(int i) const; .EE .UNINDENT .UNINDENT .sp transforms to: .INDENT 0.0 .INDENT 3.5 .sp .EX NO_DISCARD bool empty() const; NO_DISCARD bool empty(int i) const; .EE .UNINDENT .UNINDENT .sp if the \fBReplacementString\fP option is set to \fINO_DISCARD\fP\&. .sp \fBNote:\fP .INDENT 0.0 .INDENT 3.5 If the \fBReplacementString\fP is not a C++ attribute, but instead a macro, then that macro must be defined in scope or the fix\-it will not be applied. .UNINDENT .UNINDENT .sp \fBNote:\fP .INDENT 0.0 .INDENT 3.5 For alternative \fB__attribute__\fP syntax options to mark functions as \fB[[nodiscard]]\fP in non\-c++17 source code. See \% .UNINDENT .UNINDENT .SS modernize\-use\-noexcept .sp This check replaces deprecated dynamic exception specifications with the appropriate noexcept specification (introduced in C++11). By default this check will replace \fBthrow()\fP with \fBnoexcept\fP, and \fBthrow([,...])\fP or \fBthrow(...)\fP with \fBnoexcept(false)\fP\&. .SS Example .INDENT 0.0 .INDENT 3.5 .sp .EX void foo() throw(); void bar() throw(int) {} .EE .UNINDENT .UNINDENT .sp transforms to: .INDENT 0.0 .INDENT 3.5 .sp .EX void foo() noexcept; void bar() noexcept(false) {} .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B ReplacementString Users can use \fBReplacementString\fP \%<#\:cmdoption-arg-ReplacementString> to specify a macro to use instead of \fBnoexcept\fP\&. This is useful when maintaining source code that uses custom exception specification marking other than \fBnoexcept\fP\&. Fix\-it hints will only be generated for non\-throwing specifications. .UNINDENT .SS Example .INDENT 0.0 .INDENT 3.5 .sp .EX void bar() throw(int); void foo() throw(); .EE .UNINDENT .UNINDENT .sp transforms to: .INDENT 0.0 .INDENT 3.5 .sp .EX void bar() throw(int); // No fix\-it generated. void foo() NOEXCEPT; .EE .UNINDENT .UNINDENT .sp if the \fBReplacementString\fP \%<#\:cmdoption-arg-ReplacementString> option is set to \fINOEXCEPT\fP\&. .INDENT 0.0 .TP .B UseNoexceptFalse .UNINDENT .sp Enabled by default, disabling will generate fix\-it hints that remove throwing dynamic exception specs, e.g., \fBthrow()\fP, completely without providing a replacement text, except for destructors and delete operators that are \fBnoexcept(true)\fP by default. .SS Example .INDENT 0.0 .INDENT 3.5 .sp .EX void foo() throw(int) {} struct bar { void foobar() throw(int); void operator delete(void *ptr) throw(int); void operator delete[](void *ptr) throw(int); ~bar() throw(int); } .EE .UNINDENT .UNINDENT .sp transforms to: .INDENT 0.0 .INDENT 3.5 .sp .EX void foo() {} struct bar { void foobar(); void operator delete(void *ptr) noexcept(false); void operator delete[](void *ptr) noexcept(false); ~bar() noexcept(false); } .EE .UNINDENT .UNINDENT .sp if the \fBUseNoexceptFalse\fP option is set to \fIfalse\fP\&. .SS modernize\-use\-nullptr .sp The check converts the usage of null pointer constants (e.g. \fBNULL\fP, \fB0\fP) to use the new C++11 and C23 \fBnullptr\fP keyword. .SS Example .INDENT 0.0 .INDENT 3.5 .sp .EX void assignment() { char *a = NULL; char *b = 0; char c = 0; } int *ret_ptr() { return 0; } .EE .UNINDENT .UNINDENT .sp transforms to: .INDENT 0.0 .INDENT 3.5 .sp .EX void assignment() { char *a = nullptr; char *b = nullptr; char c = 0; } int *ret_ptr() { return nullptr; } .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IgnoredTypes Semicolon\-separated list of regular expressions to match pointer types for which implicit casts will be ignored. Default value: \fIstd::_CmpUnspecifiedParam::;^std::__cmp_cat::__unspec\fP\&. .UNINDENT .INDENT 0.0 .TP .B NullMacros Comma\-separated list of macro names that will be transformed along with \fBNULL\fP\&. By default this check will only replace the \fBNULL\fP macro and will skip any similar user\-defined macros. .UNINDENT .SS Example .INDENT 0.0 .INDENT 3.5 .sp .EX #define MY_NULL (void*)0 void assignment() { void *p = MY_NULL; } .EE .UNINDENT .UNINDENT .sp transforms to: .INDENT 0.0 .INDENT 3.5 .sp .EX #define MY_NULL NULL void assignment() { int *p = nullptr; } .EE .UNINDENT .UNINDENT .sp if the \fBNullMacros\fP option is set to \fBMY_NULL\fP\&. .SS modernize\-use\-override .sp Adds \fBoverride\fP (introduced in C++11) to overridden virtual functions and removes \fBvirtual\fP from those functions as it is not required. .sp \fBvirtual\fP on non base class implementations was used to help indicate to the user that a function was virtual. C++ compilers did not use the presence of this to signify an overridden function. .sp In C++11 \fBoverride\fP and \fBfinal\fP keywords were introduced to allow overridden functions to be marked appropriately. Their presence allows compilers to verify that an overridden function correctly overrides a base class implementation. .sp This can be useful as compilers can generate a compile time error when: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 The base class implementation function signature changes. .IP \(bu 2 The user has not created the override with the correct signature. .UNINDENT .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IgnoreDestructors If set to \fItrue\fP, this check will not diagnose destructors. Default is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B IgnoreTemplateInstantiations If set to \fItrue\fP, instructs this check to ignore virtual function overrides that are part of template instantiations. Default is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B AllowOverrideAndFinal If set to \fItrue\fP, this check will not diagnose \fBoverride\fP as redundant with \fBfinal\fP\&. This is useful when code will be compiled by a compiler with warning/error checking flags requiring \fBoverride\fP explicitly on overridden members, such as \fBgcc \-Wsuggest\-override\fP/\fBgcc \-Werror=suggest\-override\fP\&. Default is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B OverrideSpelling Specifies a macro to use instead of \fBoverride\fP\&. This is useful when maintaining source code that also needs to compile with a pre\-C++11 compiler. .UNINDENT .INDENT 0.0 .TP .B FinalSpelling Specifies a macro to use instead of \fBfinal\fP\&. This is useful when maintaining source code that also needs to compile with a pre\-C++11 compiler. .UNINDENT .sp \fBNote:\fP .INDENT 0.0 .INDENT 3.5 For more information on the use of \fBoverride\fP see \% .UNINDENT .UNINDENT .SS modernize\-use\-ranges .sp Detects calls to standard library iterator algorithms that could be replaced with a ranges version instead. .SS Example .INDENT 0.0 .INDENT 3.5 .sp .EX auto Iter1 = std::find(Items.begin(), Items.end(), 0); auto AreSame = std::equal(Items1.cbegin(), Items1.cend(), std::begin(Items2), std::end(Items2)); .EE .UNINDENT .UNINDENT .sp Transforms to: .INDENT 0.0 .INDENT 3.5 .sp .EX auto Iter1 = std::ranges::find(Items, 0); auto AreSame = std::ranges::equal(Items1, Items2); .EE .UNINDENT .UNINDENT .SS Supported algorithms .sp Calls to the following std library algorithms are checked: .sp \fBstd::adjacent_find\fP, \fBstd::all_of\fP, \fBstd::any_of\fP, \fBstd::binary_search\fP, \fBstd::copy_backward\fP, \fBstd::copy_if\fP, \fBstd::copy\fP, \fBstd::destroy\fP, \fBstd::equal_range\fP, \fBstd::equal\fP, \fBstd::fill\fP, \fBstd::find_end\fP, \fBstd::find_if_not\fP, \fBstd::find_if\fP, \fBstd::find\fP, \fBstd::for_each\fP, \fBstd::generate\fP, \fBstd::includes\fP, \fBstd::inplace_merge\fP, \fBstd::iota\fP, \fBstd::is_heap_until\fP, \fBstd::is_heap\fP, \fBstd::is_partitioned\fP, \fBstd::is_permutation\fP, \fBstd::is_sorted_until\fP, \fBstd::is_sorted\fP, \fBstd::lexicographical_compare\fP, \fBstd::lower_bound\fP, \fBstd::make_heap\fP, \fBstd::max_element\fP, \fBstd::merge\fP, \fBstd::min_element\fP, \fBstd::minmax_element\fP, \fBstd::mismatch\fP, \fBstd::move_backward\fP, \fBstd::move\fP, \fBstd::next_permutation\fP, \fBstd::none_of\fP, \fBstd::partial_sort_copy\fP, \fBstd::partition_copy\fP, \fBstd::partition_point\fP, \fBstd::partition\fP, \fBstd::pop_heap\fP, \fBstd::prev_permutation\fP, \fBstd::push_heap\fP, \fBstd::remove_copy_if\fP, \fBstd::remove_copy\fP, \fBstd::remove\fP, \fBstd::remove_if\fP, \fBstd::replace_if\fP, \fBstd::replace\fP, \fBstd::reverse_copy\fP, \fBstd::reverse\fP, \fBstd::rotate\fP, \fBstd::rotate_copy\fP, \fBstd::sample\fP, \fBstd::search\fP, \fBstd::set_difference\fP, \fBstd::set_intersection\fP, \fBstd::set_symmetric_difference\fP, \fBstd::set_union\fP, \fBstd::shift_left\fP, \fBstd::shift_right\fP, \fBstd::sort_heap\fP, \fBstd::sort\fP, \fBstd::stable_partition\fP, \fBstd::stable_sort\fP, \fBstd::transform\fP, \fBstd::uninitialized_copy\fP, \fBstd::uninitialized_default_construct\fP, \fBstd::uninitialized_fill\fP, \fBstd::uninitialized_move\fP, \fBstd::uninitialized_value_construct\fP, \fBstd::unique_copy\fP, \fBstd::unique\fP, \fBstd::upper_bound\fP\&. .sp Note: some range algorithms for \fBvector\fP require C++23 because it uses proxy iterators. .SS Reverse Iteration .sp If calls are made using reverse iterators on containers, The code will be fixed using the \fBstd::views::reverse\fP adaptor. .INDENT 0.0 .INDENT 3.5 .sp .EX auto AreSame = std::equal(Items1.rbegin(), Items1.rend(), std::crbegin(Items2), std::crend(Items2)); .EE .UNINDENT .UNINDENT .sp Transforms to: .INDENT 0.0 .INDENT 3.5 .sp .EX auto AreSame = std::ranges::equal(std::views::reverse(Items1), std::views::reverse(Items2)); .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IncludeStyle A string specifying which include\-style is used, \fIllvm\fP or \fIgoogle\fP\&. Default is \fIllvm\fP\&. .UNINDENT .INDENT 0.0 .TP .B UseReversePipe When \fItrue\fP (default \fIfalse\fP), fixes which involve reverse ranges will use the pipe adaptor syntax instead of the function syntax. .INDENT 7.0 .INDENT 3.5 .sp .EX std::find(Items.rbegin(), Items.rend(), 0); .EE .UNINDENT .UNINDENT .sp Transforms to: .INDENT 7.0 .INDENT 3.5 .sp .EX std::ranges::find(Items | std::views::reverse, 0); .EE .UNINDENT .UNINDENT .UNINDENT .SS modernize\-use\-scoped\-lock .sp Finds uses of \fBstd::lock_guard\fP and suggests replacing them with C++17\(aqs alternative \fBstd::scoped_lock\fP\&. .sp Fix\-its are provided for single declarations of \fBstd::lock_guard\fP and warning is emitted for multiple declarations of \fBstd::lock_guard\fP that can be replaced with a single declaration of \fBstd::scoped_lock\fP\&. .SS Examples .sp Single \fBstd::lock_guard\fP declaration: .INDENT 0.0 .INDENT 3.5 .sp .EX std::mutex M; std::lock_guard L(M); .EE .UNINDENT .UNINDENT .sp Transforms to: .INDENT 0.0 .INDENT 3.5 .sp .EX std::mutex M; std::scoped_lock L(M); .EE .UNINDENT .UNINDENT .sp Single \fBstd::lock_guard\fP declaration with \fBstd::adopt_lock\fP: .INDENT 0.0 .INDENT 3.5 .sp .EX std::mutex M; std::lock(M); std::lock_guard L(M, std::adopt_lock); .EE .UNINDENT .UNINDENT .sp Transforms to: .INDENT 0.0 .INDENT 3.5 .sp .EX std::mutex M; std::lock(M); std::scoped_lock L(std::adopt_lock, M); .EE .UNINDENT .UNINDENT .sp Multiple \fBstd::lock_guard\fP declarations only emit warnings: .INDENT 0.0 .INDENT 3.5 .sp .EX std::mutex M1, M2; std::lock(M1, M2); std::lock_guard Lock1(M1, std::adopt_lock); // warning: use single \(aqstd::scoped_lock\(aq instead of multiple \(aqstd::lock_guard\(aq std::lock_guard Lock2(M2, std::adopt_lock); // note: additional \(aqstd::lock_guard\(aq declared here .EE .UNINDENT .UNINDENT .SS Limitations .sp The check will not emit warnings if \fBstd::lock_guard\fP is used implicitly via \fBtemplate\fP parameter: .INDENT 0.0 .INDENT 3.5 .sp .EX template