diff options
Diffstat (limited to 'clang-tools-extra')
26 files changed, 337 insertions, 99 deletions
diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp index 824ebdf..fe261e7 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -89,6 +89,7 @@ #include "ThrowKeywordMissingCheck.h" #include "TooSmallLoopVariableCheck.h" #include "UncheckedOptionalAccessCheck.h" +#include "UncheckedStringToNumberConversionCheck.h" #include "UndefinedMemoryManipulationCheck.h" #include "UndelegatedConstructorCheck.h" #include "UnhandledExceptionAtNewCheck.h" @@ -261,6 +262,8 @@ public: "bugprone-too-small-loop-variable"); CheckFactories.registerCheck<UncheckedOptionalAccessCheck>( "bugprone-unchecked-optional-access"); + CheckFactories.registerCheck<UncheckedStringToNumberConversionCheck>( + "bugprone-unchecked-string-to-number-conversion"); CheckFactories.registerCheck<UndefinedMemoryManipulationCheck>( "bugprone-undefined-memory-manipulation"); CheckFactories.registerCheck<UndelegatedConstructorCheck>( diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index 59928e5..46bc8ef 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -91,6 +91,7 @@ add_clang_library(clangTidyBugproneModule STATIC ThrowKeywordMissingCheck.cpp TooSmallLoopVariableCheck.cpp UncheckedOptionalAccessCheck.cpp + UncheckedStringToNumberConversionCheck.cpp UndefinedMemoryManipulationCheck.cpp UndelegatedConstructorCheck.cpp UnhandledExceptionAtNewCheck.cpp diff --git a/clang-tools-extra/clang-tidy/cert/StrToNumCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UncheckedStringToNumberConversionCheck.cpp index 95536bb..d1e7b89 100644 --- a/clang-tools-extra/clang-tidy/cert/StrToNumCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UncheckedStringToNumberConversionCheck.cpp @@ -1,4 +1,4 @@ -//===-- StrToNumCheck.cpp - clang-tidy ------------------------------------===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "StrToNumCheck.h" +#include "UncheckedStringToNumberConversionCheck.h" #include "clang/AST/ASTContext.h" #include "clang/AST/FormatString.h" #include "clang/ASTMatchers/ASTMatchFinder.h" @@ -15,9 +15,10 @@ using namespace clang::ast_matchers; -namespace clang::tidy::cert { +namespace clang::tidy::bugprone { -void StrToNumCheck::registerMatchers(MatchFinder *Finder) { +void UncheckedStringToNumberConversionCheck::registerMatchers( + MatchFinder *Finder) { // Match any function call to the C standard library string conversion // functions that do no error checking. Finder->addMatcher( @@ -176,7 +177,8 @@ static StringRef classifyReplacement(ConversionKind K) { llvm_unreachable("Unknown conversion kind"); } -void StrToNumCheck::check(const MatchFinder::MatchResult &Result) { +void UncheckedStringToNumberConversionCheck::check( + const MatchFinder::MatchResult &Result) { const auto *Call = Result.Nodes.getNodeAs<CallExpr>("expr"); const FunctionDecl *FuncDecl = nullptr; ConversionKind Conversion = ConversionKind::None; @@ -228,4 +230,4 @@ void StrToNumCheck::check(const MatchFinder::MatchResult &Result) { << classifyReplacement(Conversion); } -} // namespace clang::tidy::cert +} // namespace clang::tidy::bugprone diff --git a/clang-tools-extra/clang-tidy/bugprone/UncheckedStringToNumberConversionCheck.h b/clang-tools-extra/clang-tidy/bugprone/UncheckedStringToNumberConversionCheck.h new file mode 100644 index 0000000..365b409 --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/UncheckedStringToNumberConversionCheck.h @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_UNCHECKEDSTRINGTONUMBERCONVERSIONCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_UNCHECKEDSTRINGTONUMBERCONVERSIONCHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang::tidy::bugprone { + +/// Guards against use of string conversion functions that do not have +/// reasonable error handling for conversion errors. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone/unchecked-string-to-number-conversion.html +class UncheckedStringToNumberConversionCheck : public ClangTidyCheck { +public: + UncheckedStringToNumberConversionCheck(StringRef Name, + ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus || LangOpts.C99; + } +}; + +} // namespace clang::tidy::bugprone + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_UNCHECKEDSTRINGTONUMBERCONVERSIONCHECK_H diff --git a/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp b/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp index 66fedab..a0d0ac1 100644 --- a/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp @@ -17,6 +17,7 @@ #include "../bugprone/SizeofExpressionCheck.h" #include "../bugprone/SpuriouslyWakeUpFunctionsCheck.h" #include "../bugprone/SuspiciousMemoryComparisonCheck.h" +#include "../bugprone/UncheckedStringToNumberConversionCheck.h" #include "../bugprone/UnhandledSelfAssignmentCheck.h" #include "../bugprone/UnsafeFunctionsCheck.h" #include "../bugprone/UnusedReturnValueCheck.h" @@ -39,7 +40,6 @@ #include "ProperlySeededRandomGeneratorCheck.h" #include "SetLongJmpCheck.h" #include "StaticObjectExceptionCheck.h" -#include "StrToNumCheck.h" #include "ThrownExceptionTypeCheck.h" #include "VariadicFunctionDefCheck.h" @@ -297,7 +297,9 @@ public: // ERR CheckFactories.registerCheck<bugprone::UnusedReturnValueCheck>( "cert-err33-c"); - CheckFactories.registerCheck<StrToNumCheck>("cert-err34-c"); + CheckFactories + .registerCheck<bugprone::UncheckedStringToNumberConversionCheck>( + "cert-err34-c"); // EXP CheckFactories.registerCheck<bugprone::SuspiciousMemoryComparisonCheck>( "cert-exp42-c"); diff --git a/clang-tools-extra/clang-tidy/cert/CMakeLists.txt b/clang-tools-extra/clang-tidy/cert/CMakeLists.txt index e3187b2..eebbf90 100644 --- a/clang-tools-extra/clang-tidy/cert/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/cert/CMakeLists.txt @@ -15,7 +15,6 @@ add_clang_library(clangTidyCERTModule STATIC ProperlySeededRandomGeneratorCheck.cpp SetLongJmpCheck.cpp StaticObjectExceptionCheck.cpp - StrToNumCheck.cpp ThrownExceptionTypeCheck.cpp VariadicFunctionDefCheck.cpp diff --git a/clang-tools-extra/clang-tidy/cert/StrToNumCheck.h b/clang-tools-extra/clang-tidy/cert/StrToNumCheck.h deleted file mode 100644 index 5306bde..0000000 --- a/clang-tools-extra/clang-tidy/cert/StrToNumCheck.h +++ /dev/null @@ -1,31 +0,0 @@ -//===--- StrToNumCheck.h - clang-tidy----------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_STRTONUMCHECK_H -#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_STRTONUMCHECK_H - -#include "../ClangTidyCheck.h" - -namespace clang::tidy::cert { - -/// Guards against use of string conversion functions that do not have -/// reasonable error handling for conversion errors. -/// -/// For the user-facing documentation see: -/// http://clang.llvm.org/extra/clang-tidy/checks/cert/err34-c.html -class StrToNumCheck : public ClangTidyCheck { -public: - StrToNumCheck(StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context) {} - void registerMatchers(ast_matchers::MatchFinder *Finder) override; - void check(const ast_matchers::MatchFinder::MatchResult &Result) override; -}; - -} // namespace clang::tidy::cert - -#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_STRTONUMCHECK_H diff --git a/clang-tools-extra/clang-tidy/google/CMakeLists.txt b/clang-tools-extra/clang-tidy/google/CMakeLists.txt index 2470c08..1d4229e 100644 --- a/clang-tools-extra/clang-tidy/google/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/google/CMakeLists.txt @@ -11,6 +11,7 @@ add_clang_library(clangTidyGoogleModule STATIC DefaultArgumentsCheck.cpp ExplicitConstructorCheck.cpp ExplicitMakePairCheck.cpp + FloatTypesCheck.cpp FunctionNamingCheck.cpp GlobalNamesInHeadersCheck.cpp GlobalVariableDeclarationCheck.cpp diff --git a/clang-tools-extra/clang-tidy/google/FloatTypesCheck.cpp b/clang-tools-extra/clang-tidy/google/FloatTypesCheck.cpp new file mode 100644 index 0000000..3d5fb02 --- /dev/null +++ b/clang-tools-extra/clang-tidy/google/FloatTypesCheck.cpp @@ -0,0 +1,77 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "FloatTypesCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" + +namespace clang { + +using namespace ast_matchers; + +namespace { + +AST_POLYMORPHIC_MATCHER(isValidAndNotInMacro, + AST_POLYMORPHIC_SUPPORTED_TYPES(TypeLoc, + FloatingLiteral)) { + const SourceLocation Loc = Node.getBeginLoc(); + return Loc.isValid() && !Loc.isMacroID(); +} + +AST_MATCHER(TypeLoc, isLongDoubleType) { + TypeLoc TL = Node; + if (const auto QualLoc = Node.getAs<QualifiedTypeLoc>()) + TL = QualLoc.getUnqualifiedLoc(); + + const auto BuiltinLoc = TL.getAs<BuiltinTypeLoc>(); + if (!BuiltinLoc) + return false; + + if (const auto *BT = BuiltinLoc.getTypePtr()) + return BT->getKind() == BuiltinType::LongDouble; + return false; +} + +AST_MATCHER(FloatingLiteral, isLongDoubleLiteral) { + if (const auto *BT = + dyn_cast_if_present<BuiltinType>(Node.getType().getTypePtr())) + return BT->getKind() == BuiltinType::LongDouble; + return false; +} + +} // namespace + +namespace tidy::google::runtime { + +void RuntimeFloatCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(typeLoc(loc(realFloatingPointType()), + isValidAndNotInMacro(), isLongDoubleType()) + .bind("longDoubleTypeLoc"), + this); + Finder->addMatcher(floatLiteral(isValidAndNotInMacro(), isLongDoubleLiteral()) + .bind("longDoubleFloatLiteral"), + this); +} + +void RuntimeFloatCheck::check(const MatchFinder::MatchResult &Result) { + if (const auto *TL = Result.Nodes.getNodeAs<TypeLoc>("longDoubleTypeLoc")) { + diag(TL->getBeginLoc(), "%0 type is not portable and should not be used") + << TL->getType(); + } + + if (const auto *FL = + Result.Nodes.getNodeAs<FloatingLiteral>("longDoubleFloatLiteral")) { + diag(FL->getBeginLoc(), "%0 type from literal suffix 'L' is not portable " + "and should not be used") + << FL->getType(); + } +} + +} // namespace tidy::google::runtime + +} // namespace clang diff --git a/clang-tools-extra/clang-tidy/google/FloatTypesCheck.h b/clang-tools-extra/clang-tidy/google/FloatTypesCheck.h new file mode 100644 index 0000000..b5534c0 --- /dev/null +++ b/clang-tools-extra/clang-tidy/google/FloatTypesCheck.h @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_FLOATTYPESCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_FLOATTYPESCHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang::tidy::google::runtime { + +/// Finds usages of `long double` and suggests against their use due to lack +/// of portability. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/google/runtime-float.html +class RuntimeFloatCheck : public ClangTidyCheck { +public: + RuntimeFloatCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus && !LangOpts.ObjC; + } +}; + +} // namespace clang::tidy::google::runtime + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_FLOATTYPESCHECK_H diff --git a/clang-tools-extra/clang-tidy/google/GoogleTidyModule.cpp b/clang-tools-extra/clang-tidy/google/GoogleTidyModule.cpp index 5343e2b..eb5666b 100644 --- a/clang-tools-extra/clang-tidy/google/GoogleTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/google/GoogleTidyModule.cpp @@ -19,6 +19,7 @@ #include "DefaultArgumentsCheck.h" #include "ExplicitConstructorCheck.h" #include "ExplicitMakePairCheck.h" +#include "FloatTypesCheck.h" #include "FunctionNamingCheck.h" #include "GlobalNamesInHeadersCheck.h" #include "GlobalVariableDeclarationCheck.h" @@ -57,6 +58,8 @@ public: "google-objc-function-naming"); CheckFactories.registerCheck<objc::GlobalVariableDeclarationCheck>( "google-objc-global-variable-declaration"); + CheckFactories.registerCheck<runtime::RuntimeFloatCheck>( + "google-runtime-float"); CheckFactories.registerCheck<runtime::IntegerTypesCheck>( "google-runtime-int"); CheckFactories.registerCheck<runtime::OverloadedUnaryAndCheck>( diff --git a/clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp b/clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp index 9692fcb..d87e352 100644 --- a/clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp @@ -39,7 +39,7 @@ namespace { // - LoopCounterName: The entire for loop (as ForStmt). // - LoopParentName: The body of function f (as CompoundStmt). // - VectorVarDeclName: 'v' (as VarDecl). -// - VectorVarDeclStmatName: The entire 'std::vector<T> v;' statement (as +// - VectorVarDeclStmtName: The entire 'std::vector<T> v;' statement (as // DeclStmt). // - PushBackOrEmplaceBackCallName: 'v.push_back(i)' (as cxxMemberCallExpr). // - LoopInitVarName: 'i' (as VarDecl). diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp index 3df4a03..c8b6221 100644 --- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp @@ -186,7 +186,7 @@ static StringRef const StyleNames[] = { m(ptrdiff_t) \ m(void) \ -static StringRef const HungarainNotationPrimitiveTypes[] = { +static StringRef const HungarianNotationPrimitiveTypes[] = { #define STRINGIZE(v) #v, HUNGARIAN_NOTATION_PRIMITIVE_TYPES(STRINGIZE) #undef STRINGIZE @@ -222,7 +222,7 @@ static StringRef const HungarainNotationPrimitiveTypes[] = { m(UINT64) \ m(PVOID) \ -static StringRef const HungarainNotationUserDefinedTypes[] = { +static StringRef const HungarianNotationUserDefinedTypes[] = { #define STRINGIZE(v) #v, HUNGARIAN_NOTATION_USER_DEFINED_TYPES(STRINGIZE) #undef STRINGIZE @@ -488,7 +488,7 @@ void IdentifierNamingCheck::HungarianNotation::loadFileConfig( Buffer = {Section, "PrimitiveType."}; DefSize = Buffer.size(); - for (const auto &PrimType : HungarainNotationPrimitiveTypes) { + for (const auto &PrimType : HungarianNotationPrimitiveTypes) { Buffer.truncate(DefSize); Buffer.append(PrimType); StringRef Val = Options.get(Buffer, ""); @@ -501,7 +501,7 @@ void IdentifierNamingCheck::HungarianNotation::loadFileConfig( Buffer = {Section, "UserDefinedType."}; DefSize = Buffer.size(); - for (const auto &Type : HungarainNotationUserDefinedTypes) { + for (const auto &Type : HungarianNotationUserDefinedTypes) { Buffer.truncate(DefSize); Buffer.append(Type); StringRef Val = Options.get(Buffer, ""); diff --git a/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp index 1d5c6cc..e0640f2 100644 --- a/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp @@ -48,7 +48,7 @@ static int getPrecedence(const BinaryOperator *BinOp) { return 0; } } -static void addParantheses(const BinaryOperator *BinOp, +static void addParentheses(const BinaryOperator *BinOp, const BinaryOperator *ParentBinOp, ClangTidyCheck *Check, const clang::SourceManager &SM, @@ -81,9 +81,9 @@ static void addParantheses(const BinaryOperator *BinOp, } } - addParantheses(dyn_cast<BinaryOperator>(BinOp->getLHS()->IgnoreImpCasts()), + addParentheses(dyn_cast<BinaryOperator>(BinOp->getLHS()->IgnoreImpCasts()), BinOp, Check, SM, LangOpts); - addParantheses(dyn_cast<BinaryOperator>(BinOp->getRHS()->IgnoreImpCasts()), + addParentheses(dyn_cast<BinaryOperator>(BinOp->getRHS()->IgnoreImpCasts()), BinOp, Check, SM, LangOpts); } @@ -92,7 +92,7 @@ void MathMissingParenthesesCheck::check( const auto *BinOp = Result.Nodes.getNodeAs<BinaryOperator>("binOp"); const SourceManager &SM = *Result.SourceManager; const clang::LangOptions &LO = Result.Context->getLangOpts(); - addParantheses(BinOp, nullptr, this, SM, LO); + addParentheses(BinOp, nullptr, this, SM, LO); } } // namespace clang::tidy::readability diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index bd75785..23d757b 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -155,6 +155,12 @@ New checks Finds calls to ``operator[]`` in STL containers and suggests replacing them with safe alternatives. +- New :doc:`google-runtime-float + <clang-tidy/checks/google/runtime-float>` check. + + Finds uses of ``long double`` and suggests against their use due to lack of + portability. + - New :doc:`llvm-mlir-op-builder <clang-tidy/checks/llvm/use-new-mlir-op-builder>` check. @@ -176,6 +182,11 @@ New checks New check aliases ^^^^^^^^^^^^^^^^^ +- Renamed :doc:`cert-err34-c <clang-tidy/checks/cert/err34-c>` to + :doc:`bugprone-unchecked-string-to-number-conversion + <clang-tidy/checks/bugprone/unchecked-string-to-number-conversion>` + keeping initial check as an alias to the new one. + Changes in existing checks ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -201,6 +212,11 @@ Changes in existing checks namespace are treated as the tag or the data part of a user-defined tagged union respectively. +- Improved :doc:`bugprone-unchecked-optional-access + <clang-tidy/checks/bugprone/unchecked-optional-access>` check by supporting + ``NullableValue::makeValue`` and ``NullableValue::makeValueInplace`` to + prevent false-positives for ``BloombergLP::bdlb::NullableValue`` type. + - Improved :doc:`bugprone-unhandled-self-assignment <clang-tidy/checks/bugprone/unhandled-self-assignment>` check by adding an additional matcher that generalizes the copy-and-swap idiom pattern diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/unchecked-string-to-number-conversion.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/unchecked-string-to-number-conversion.rst new file mode 100644 index 0000000..c3ea196 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/unchecked-string-to-number-conversion.rst @@ -0,0 +1,31 @@ +.. title:: clang-tidy - bugprone-unchecked-string-to-number-conversion + +bugprone-unchecked-string-to-number-conversion +============================================== + +This check flags calls to string-to-number conversion functions that do not +verify the validity of the conversion, such as ``atoi()`` or ``scanf()``. It +does not flag calls to ``strtol()``, or other, related conversion functions that +do perform better error checking. + +.. code-block:: c + + #include <stdlib.h> + + void func(const char *buff) { + int si; + + if (buff) { + si = atoi(buff); /* 'atoi' used to convert a string to an integer, but function will + not report conversion errors; consider using 'strtol' instead. */ + } else { + /* Handle error */ + } + } + +References +---------- + +This check corresponds to the CERT C Coding Standard rule +`ERR34-C. Detect errors when converting a string to a number +<https://www.securecoding.cert.org/confluence/display/c/ERR34-C.+Detect+errors+when+converting+a+string+to+a+number>`_. diff --git a/clang-tools-extra/docs/clang-tidy/checks/cert/err34-c.rst b/clang-tools-extra/docs/clang-tidy/checks/cert/err34-c.rst index 362aef2..dc3f632 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/cert/err34-c.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/cert/err34-c.rst @@ -1,28 +1,10 @@ .. title:: clang-tidy - cert-err34-c +.. meta:: + :http-equiv=refresh: 5;URL=../bugprone/unchecked-string-to-number-conversion.html cert-err34-c ============ -This check flags calls to string-to-number conversion functions that do not -verify the validity of the conversion, such as ``atoi()`` or ``scanf()``. It -does not flag calls to ``strtol()``, or other, related conversion functions that -do perform better error checking. - -.. code-block:: c - - #include <stdlib.h> - - void func(const char *buff) { - int si; - - if (buff) { - si = atoi(buff); /* 'atoi' used to convert a string to an integer, but function will - not report conversion errors; consider using 'strtol' instead. */ - } else { - /* Handle error */ - } - } - -This check corresponds to the CERT C Coding Standard rule -`ERR34-C. Detect errors when converting a string to a number -<https://www.securecoding.cert.org/confluence/display/c/ERR34-C.+Detect+errors+when+converting+a+string+to+a+number>`_. +The cert-err34-c check is an alias, please see +`bugprone-unchecked-string-to-number-conversion <../bugprone/unchecked-string-to-number-conversion.html>`_ +for more information. diff --git a/clang-tools-extra/docs/clang-tidy/checks/google/runtime-float.rst b/clang-tools-extra/docs/clang-tidy/checks/google/runtime-float.rst new file mode 100644 index 0000000..4b853ad --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/google/runtime-float.rst @@ -0,0 +1,10 @@ +.. title:: clang-tidy - google-runtime-float + +google-runtime-float +==================== + +Finds uses of ``long double`` and suggests against their use due to lack of +portability. + +The corresponding style guide rule: +https://google.github.io/styleguide/cppguide.html#Floating-Point_Types diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index 9affebc..c490d2e 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -157,6 +157,7 @@ Clang-Tidy Checks :doc:`bugprone-throw-keyword-missing <bugprone/throw-keyword-missing>`, :doc:`bugprone-too-small-loop-variable <bugprone/too-small-loop-variable>`, :doc:`bugprone-unchecked-optional-access <bugprone/unchecked-optional-access>`, + :doc:`bugprone-unchecked-string-to-number-conversion <bugprone/unchecked-string-to-number-conversion>`, :doc:`bugprone-undefined-memory-manipulation <bugprone/undefined-memory-manipulation>`, :doc:`bugprone-undelegated-constructor <bugprone/undelegated-constructor>`, :doc:`bugprone-unhandled-exception-at-new <bugprone/unhandled-exception-at-new>`, @@ -173,7 +174,6 @@ Clang-Tidy Checks :doc:`cert-dcl58-cpp <cert/dcl58-cpp>`, :doc:`cert-env33-c <cert/env33-c>`, :doc:`cert-err33-c <cert/err33-c>`, - :doc:`cert-err34-c <cert/err34-c>`, :doc:`cert-err52-cpp <cert/err52-cpp>`, :doc:`cert-err58-cpp <cert/err58-cpp>`, :doc:`cert-err60-cpp <cert/err60-cpp>`, @@ -238,6 +238,7 @@ Clang-Tidy Checks :doc:`google-readability-avoid-underscore-in-googletest-name <google/readability-avoid-underscore-in-googletest-name>`, :doc:`google-readability-casting <google/readability-casting>`, :doc:`google-readability-todo <google/readability-todo>`, + :doc:`google-runtime-float <google/runtime-float>`, :doc:`google-runtime-int <google/runtime-int>`, :doc:`google-runtime-operator <google/runtime-operator>`, :doc:`google-upgrade-googletest-case <google/upgrade-googletest-case>`, "Yes" @@ -437,6 +438,7 @@ Check aliases :doc:`cert-dcl54-cpp <cert/dcl54-cpp>`, :doc:`misc-new-delete-overloads <misc/new-delete-overloads>`, :doc:`cert-dcl59-cpp <cert/dcl59-cpp>`, :doc:`google-build-namespaces <google/build-namespaces>`, :doc:`cert-err09-cpp <cert/err09-cpp>`, :doc:`misc-throw-by-value-catch-by-reference <misc/throw-by-value-catch-by-reference>`, + :doc:`cert-err34-c <cert/err34-c>`, :doc:`bugprone-unchecked-string-to-number-conversion <bugprone/unchecked-string-to-number-conversion>`, :doc:`cert-err61-cpp <cert/err61-cpp>`, :doc:`misc-throw-by-value-catch-by-reference <misc/throw-by-value-catch-by-reference>`, :doc:`cert-exp42-c <cert/exp42-c>`, :doc:`bugprone-suspicious-memory-comparison <bugprone/suspicious-memory-comparison>`, :doc:`cert-fio38-c <cert/fio38-c>`, :doc:`misc-non-copyable-objects <misc/non-copyable-objects>`, diff --git a/clang-tools-extra/test/clang-apply-replacements/crlf.cpp b/clang-tools-extra/test/clang-apply-replacements/crlf.cpp index f40429e..40c48fd 100644 --- a/clang-tools-extra/test/clang-apply-replacements/crlf.cpp +++ b/clang-tools-extra/test/clang-apply-replacements/crlf.cpp @@ -1,5 +1,6 @@ // RUN: mkdir -p %t.dir/Inputs/crlf -// RUN: cat %S/Inputs/crlf/crlf.cpp > %t.dir/Inputs/crlf/crlf.cpp +// RUN: cp %S/Inputs/crlf/crlf.cpp %t.dir/Inputs/crlf/crlf.cpp +// RUN: chmod u+w %t.dir/Inputs/crlf/crlf.cpp // RUN: sed "s#\$(path)#%/t.dir/Inputs/crlf#" %S/Inputs/crlf/file1.yaml > %t.dir/Inputs/crlf/file1.yaml // RUN: clang-apply-replacements %t.dir/Inputs/crlf // RUN: diff %t.dir/Inputs/crlf/crlf.cpp %S/Inputs/crlf/crlf.cpp.expected diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/Inputs/unchecked-optional-access/bde/types/bdlb_nullablevalue.h b/clang-tools-extra/test/clang-tidy/checkers/bugprone/Inputs/unchecked-optional-access/bde/types/bdlb_nullablevalue.h index 4411bcf..0812677 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/Inputs/unchecked-optional-access/bde/types/bdlb_nullablevalue.h +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/Inputs/unchecked-optional-access/bde/types/bdlb_nullablevalue.h @@ -20,6 +20,14 @@ public: const T &value() const &; T &value() &; + constexpr T &makeValue(); + + template <typename U> + constexpr T &makeValue(U&& v); + + template <typename... ARGS> + constexpr T &makeValueInplace(ARGS &&... args); + // 'operator bool' is inherited from bsl::optional constexpr bool isNull() const noexcept; diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unchecked-optional-access.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unchecked-optional-access.cpp index 4911157..8d70a9d 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unchecked-optional-access.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unchecked-optional-access.cpp @@ -141,6 +141,20 @@ void nullable_value_after_swap(BloombergLP::bdlb::NullableValue<int> &opt1, Bloo } } +void nullable_value_make_value(BloombergLP::bdlb::NullableValue<int> &opt1, BloombergLP::bdlb::NullableValue<int> &opt2) { + if (opt1.isNull()) { + opt1.makeValue(42); + } + + opt1.value(); + + if (opt2.isNull()) { + opt2.makeValueInplace(42); + } + + opt2.value(); +} + void assertion_handler() __attribute__((analyzer_noreturn)); void function_calling_analyzer_noreturn(const bsl::optional<int>& opt) diff --git a/clang-tools-extra/test/clang-tidy/checkers/cert/err34-c.c b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unchecked-string-to-number-conversion.c index e2cfc21..0546e0c 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cert/err34-c.c +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unchecked-string-to-number-conversion.c @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy %s cert-err34-c %t -- -- -std=c11 +// RUN: %check_clang_tidy %s bugprone-unchecked-string-to-number-conversion %t typedef __SIZE_TYPE__ size_t; typedef signed ptrdiff_t; @@ -8,9 +8,9 @@ typedef void * FILE; extern FILE *stdin; -extern int fscanf(FILE * restrict stream, const char * restrict format, ...); -extern int scanf(const char * restrict format, ...); -extern int sscanf(const char * restrict s, const char * restrict format, ...); +extern int fscanf(FILE *stream, const char *format, ...); +extern int scanf(const char *format, ...); +extern int sscanf(const char *s, const char *format, ...); extern double atof(const char *nptr); extern int atoi(const char *nptr); @@ -28,23 +28,23 @@ void f1(const char *in) { double d; long double ld; - // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c] + // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [bugprone-unchecked-string-to-number-conversion] sscanf(in, "%d", &i); - // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoll' instead [cert-err34-c] + // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoll' instead fscanf(stdin, "%lld", &ll); - // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to an unsigned integer value, but function will not report conversion errors; consider using 'strtoul' instead [cert-err34-c] + // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to an unsigned integer value, but function will not report conversion errors; consider using 'strtoul' instead sscanf(in, "%u", &ui); - // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to an unsigned integer value, but function will not report conversion errors; consider using 'strtoull' instead [cert-err34-c] + // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to an unsigned integer value, but function will not report conversion errors; consider using 'strtoull' instead fscanf(stdin, "%llu", &ull); - // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoimax' instead [cert-err34-c] + // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoimax' instead scanf("%jd", &im); - // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to an unsigned integer value, but function will not report conversion errors; consider using 'strtoumax' instead [cert-err34-c] + // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to an unsigned integer value, but function will not report conversion errors; consider using 'strtoumax' instead fscanf(stdin, "%ju", &uim); - // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtof' instead [cert-err34-c] + // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtof' instead sscanf(in, "%f", &f); // to float - // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtod' instead [cert-err34-c] + // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtod' instead fscanf(stdin, "%lg", &d); - // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtold' instead [cert-err34-c] + // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtold' instead sscanf(in, "%Le", &ld); // These are conversions with other modifiers @@ -70,13 +70,13 @@ void f1(const char *in) { } void f2(const char *in) { - // CHECK-MESSAGES: :[[@LINE+1]]:11: warning: 'atoi' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c] + // CHECK-MESSAGES: :[[@LINE+1]]:11: warning: 'atoi' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead int i = atoi(in); // to int - // CHECK-MESSAGES: :[[@LINE+1]]:12: warning: 'atol' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c] + // CHECK-MESSAGES: :[[@LINE+1]]:12: warning: 'atol' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead long l = atol(in); // to long - // CHECK-MESSAGES: :[[@LINE+1]]:18: warning: 'atoll' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoll' instead [cert-err34-c] + // CHECK-MESSAGES: :[[@LINE+1]]:18: warning: 'atoll' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoll' instead long long ll = atoll(in); // to long long - // CHECK-MESSAGES: :[[@LINE+1]]:14: warning: 'atof' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtod' instead [cert-err34-c] + // CHECK-MESSAGES: :[[@LINE+1]]:14: warning: 'atof' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtod' instead double d = atof(in); // to double } diff --git a/clang-tools-extra/test/clang-tidy/checkers/cert/err34-c.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unchecked-string-to-number-conversion.cpp index 1c358bc..c3e5021 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cert/err34-c.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unchecked-string-to-number-conversion.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy %s cert-err34-c %t +// RUN: %check_clang_tidy %s bugprone-unchecked-string-to-number-conversion %t typedef void * FILE; @@ -22,22 +22,22 @@ void f1(const char *in) { int i; long long ll; - // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c] + // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead std::sscanf(in, "%d", &i); - // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoll' instead [cert-err34-c] + // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoll' instead std::fscanf(std::stdin, "%lld", &ll); } void f2(const char *in) { - // CHECK-MESSAGES: :[[@LINE+1]]:11: warning: 'atoi' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c] + // CHECK-MESSAGES: :[[@LINE+1]]:11: warning: 'atoi' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead int i = std::atoi(in); // to int - // CHECK-MESSAGES: :[[@LINE+1]]:12: warning: 'atol' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c] + // CHECK-MESSAGES: :[[@LINE+1]]:12: warning: 'atol' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead long l = std::atol(in); // to long using namespace std; - // CHECK-MESSAGES: :[[@LINE+1]]:18: warning: 'atoll' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoll' instead [cert-err34-c] + // CHECK-MESSAGES: :[[@LINE+1]]:18: warning: 'atoll' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoll' instead long long ll = atoll(in); // to long long - // CHECK-MESSAGES: :[[@LINE+1]]:14: warning: 'atof' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtod' instead [cert-err34-c] + // CHECK-MESSAGES: :[[@LINE+1]]:14: warning: 'atof' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtod' instead double d = atof(in); // to double } diff --git a/clang-tools-extra/test/clang-tidy/checkers/google/runtime-float.cpp b/clang-tools-extra/test/clang-tidy/checkers/google/runtime-float.cpp new file mode 100644 index 0000000..5c9cc11 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/google/runtime-float.cpp @@ -0,0 +1,40 @@ +// RUN: %check_clang_tidy %s google-runtime-float %t + +long double foo; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: 'long double' type is not portable and should not be used [google-runtime-float] + +typedef long double MyLongDouble; +// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: 'long double' type is not portable and should not be used [google-runtime-float] + +typedef long double MyOtherLongDouble; // NOLINT + +template <typename T> +void tmpl() { T i; } + +long volatile double v = 10; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: 'volatile long double' type is not portable and should not be used [google-runtime-float] + +long double h(long const double aaa, long double bbb = 0.5L) { + // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: 'long double' type is not portable and should not be used [google-runtime-float] + // CHECK-MESSAGES: :[[@LINE-2]]:15: warning: 'const long double' type is not portable and should not be used [google-runtime-float] + // CHECK-MESSAGES: :[[@LINE-3]]:38: warning: 'long double' type is not portable and should not be used [google-runtime-float] + // CHECK-MESSAGES: :[[@LINE-4]]:56: warning: 'long double' type from literal suffix 'L' is not portable and should not be used [google-runtime-float] + double x = 0.1; + double y = 0.2L; + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 'long double' type from literal suffix 'L' is not portable and should not be used [google-runtime-float] +#define ldtype long double + ldtype z; + tmpl<long double>(); + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: 'long double' type is not portable and should not be used [google-runtime-float] + return 0; +} + +struct S{}; +constexpr S operator"" _baz(unsigned long long) { + long double j; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'long double' type is not portable and should not be used [google-runtime-float] + MyOtherLongDouble x; + long int a = 1L; + return S{}; +} + diff --git a/clang-tools-extra/test/lit.cfg.py b/clang-tools-extra/test/lit.cfg.py index bc82a14..b503c65 100644 --- a/clang-tools-extra/test/lit.cfg.py +++ b/clang-tools-extra/test/lit.cfg.py @@ -13,7 +13,15 @@ from lit.llvm import llvm_config config.name = "Clang Tools" # testFormat: The test format to use to interpret tests. -config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell) +# We prefer the lit internal shell which provides a better user experience on +# failures and is faster unless the user explicitly disables it with +# LIT_USE_INTERNAL_SHELL=0 env var. +use_lit_shell = True +lit_shell_env = os.environ.get("LIT_USE_INTERNAL_SHELL") +if lit_shell_env: + use_lit_shell = lit.util.pythonize_bool(lit_shell_env) + +config.test_format = lit.formats.ShTest(not use_lit_shell) # suffixes: A list of file extensions to treat as test files. config.suffixes = [ |