Author: courbet Date: Thu Feb 28 05:39:01 2019 New Revision: 355089 URL: http://llvm.org/viewvc/llvm-project?rev=355089&view=rev Log: [clang-tidy] bugprone-string-integer-assignment: Reduce false positives.
Summary: Detect a few expressions as likely character expressions, see PR27723. Reviewers: xazax.hun, alexfh Subscribers: rnkovacs, jdoerfert, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58609 Modified: clang-tools-extra/trunk/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp clang-tools-extra/trunk/test/clang-tidy/bugprone-string-integer-assignment.cpp Modified: clang-tools-extra/trunk/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp?rev=355089&r1=355088&r2=355089&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp Thu Feb 28 05:39:01 2019 @@ -45,11 +45,40 @@ void StringIntegerAssignmentCheck::regis this); } +static bool isLikelyCharExpression(const Expr *Argument, + const ASTContext &Ctx) { + const auto *BinOp = dyn_cast<BinaryOperator>(Argument); + if (!BinOp) + return false; + const auto *LHS = BinOp->getLHS()->IgnoreParenImpCasts(); + const auto *RHS = BinOp->getRHS()->IgnoreParenImpCasts(); + // <expr> & <mask>, mask is a compile time constant. + Expr::EvalResult RHSVal; + if (BinOp->getOpcode() == BO_And && + (RHS->EvaluateAsInt(RHSVal, Ctx, Expr::SE_AllowSideEffects) || + LHS->EvaluateAsInt(RHSVal, Ctx, Expr::SE_AllowSideEffects))) + return true; + // <char literal> + (<expr> % <mod>), where <base> is a char literal. + const auto IsCharPlusModExpr = [](const Expr *L, const Expr *R) { + const auto *ROp = dyn_cast<BinaryOperator>(R); + return ROp && ROp->getOpcode() == BO_Rem && isa<CharacterLiteral>(L); + }; + if (BinOp->getOpcode() == BO_Add) { + if (IsCharPlusModExpr(LHS, RHS) || IsCharPlusModExpr(RHS, LHS)) + return true; + } + return false; +} + void StringIntegerAssignmentCheck::check( const MatchFinder::MatchResult &Result) { const auto *Argument = Result.Nodes.getNodeAs<Expr>("expr"); SourceLocation Loc = Argument->getBeginLoc(); + // Try to detect a few common expressions to reduce false positives. + if (isLikelyCharExpression(Argument, *Result.Context)) + return; + auto Diag = diag(Loc, "an integer is interpreted as a character code when assigning " "it to a string; if this is intended, cast the integer to the " Modified: clang-tools-extra/trunk/test/clang-tidy/bugprone-string-integer-assignment.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/bugprone-string-integer-assignment.cpp?rev=355089&r1=355088&r2=355089&view=diff ============================================================================== --- clang-tools-extra/trunk/test/clang-tidy/bugprone-string-integer-assignment.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/bugprone-string-integer-assignment.cpp Thu Feb 28 05:39:01 2019 @@ -59,4 +59,11 @@ int main() { s += toupper(x); s += tolower(x); s += std::tolower(x); + + // Likely character expressions. + s += x & 0xff; + s += 0xff & x; + + s += 'a' + (x % 26); + s += (x % 10) + 'b'; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits