diff options
Diffstat (limited to 'clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp')
-rw-r--r-- | clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp | 57 |
1 files changed, 35 insertions, 22 deletions
diff --git a/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp b/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp index 59cc185e..1e31fde1 100644 --- a/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp +++ b/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp @@ -1,9 +1,8 @@ //===--- TooSmallLoopVariableCheck.cpp - clang-tidy -----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -28,6 +27,17 @@ static constexpr llvm::StringLiteral LoopUpperBoundName = static constexpr llvm::StringLiteral LoopIncrementName = llvm::StringLiteral("loopIncrement"); +TooSmallLoopVariableCheck::TooSmallLoopVariableCheck(StringRef Name, + ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + MagnitudeBitsUpperLimit(Options.get<unsigned>( + "MagnitudeBitsUpperLimit", 16)) {} + +void TooSmallLoopVariableCheck::storeOptions( + ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "MagnitudeBitsUpperLimit", MagnitudeBitsUpperLimit); +} + /// \brief The matcher for loops with suspicious integer loop variable. /// /// In this general example, assuming 'j' and 'k' are of integral type: @@ -85,9 +95,9 @@ void TooSmallLoopVariableCheck::registerMatchers(MatchFinder *Finder) { this); } -/// Returns the positive part of the integer width for an integer type. -static unsigned calcPositiveBits(const ASTContext &Context, - const QualType &IntExprType) { +/// Returns the magnitude bits of an integer type. +static unsigned calcMagnitudeBits(const ASTContext &Context, + const QualType &IntExprType) { assert(IntExprType->isIntegerType()); return IntExprType->isUnsignedIntegerType() @@ -95,13 +105,13 @@ static unsigned calcPositiveBits(const ASTContext &Context, : Context.getIntWidth(IntExprType) - 1; } -/// \brief Calculate the upper bound expression's positive bits, but ignore +/// \brief Calculate the upper bound expression's magnitude bits, but ignore /// constant like values to reduce false positives. -static unsigned calcUpperBoundPositiveBits(const ASTContext &Context, - const Expr *UpperBound, - const QualType &UpperBoundType) { +static unsigned calcUpperBoundMagnitudeBits(const ASTContext &Context, + const Expr *UpperBound, + const QualType &UpperBoundType) { // Ignore casting caused by constant values inside a binary operator. - // We are interested in variable values' positive bits. + // We are interested in variable values' magnitude bits. if (const auto *BinOperator = dyn_cast<BinaryOperator>(UpperBound)) { const Expr *RHSE = BinOperator->getRHS()->IgnoreParenImpCasts(); const Expr *LHSE = BinOperator->getLHS()->IgnoreParenImpCasts(); @@ -123,15 +133,15 @@ static unsigned calcUpperBoundPositiveBits(const ASTContext &Context, if (RHSEIsConstantValue && LHSEIsConstantValue) return 0; if (RHSEIsConstantValue) - return calcPositiveBits(Context, LHSEType); + return calcMagnitudeBits(Context, LHSEType); if (LHSEIsConstantValue) - return calcPositiveBits(Context, RHSEType); + return calcMagnitudeBits(Context, RHSEType); - return std::max(calcPositiveBits(Context, LHSEType), - calcPositiveBits(Context, RHSEType)); + return std::max(calcMagnitudeBits(Context, LHSEType), + calcMagnitudeBits(Context, RHSEType)); } - return calcPositiveBits(Context, UpperBoundType); + return calcMagnitudeBits(Context, UpperBoundType); } void TooSmallLoopVariableCheck::check(const MatchFinder::MatchResult &Result) { @@ -150,14 +160,17 @@ void TooSmallLoopVariableCheck::check(const MatchFinder::MatchResult &Result) { ASTContext &Context = *Result.Context; - unsigned LoopVarPosBits = calcPositiveBits(Context, LoopVarType); - unsigned UpperBoundPosBits = - calcUpperBoundPositiveBits(Context, UpperBound, UpperBoundType); + unsigned LoopVarMagnitudeBits = calcMagnitudeBits(Context, LoopVarType); + unsigned UpperBoundMagnitudeBits = + calcUpperBoundMagnitudeBits(Context, UpperBound, UpperBoundType); + + if (UpperBoundMagnitudeBits == 0) + return; - if (UpperBoundPosBits == 0) + if (LoopVarMagnitudeBits > MagnitudeBitsUpperLimit) return; - if (LoopVarPosBits < UpperBoundPosBits) + if (LoopVarMagnitudeBits < UpperBoundMagnitudeBits) diag(LoopVar->getBeginLoc(), "loop variable has narrower type %0 than " "iteration's upper bound %1") << LoopVarType << UpperBoundType; |