[clang-tools-extra] [clang-tidy] Detect std::rot[lr] pattern within modernize.use-std-bit (PR #186324)
Baranov Victor via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 13 03:07:46 PDT 2026
================
@@ -141,6 +154,48 @@ void UseStdBitCheck::check(const MatchFinder::MatchResult &Result) {
<< IncludeInserter.createIncludeInsertion(
Source.getFileID(MatchedExpr->getBeginLoc()), "<bit>");
}
+ } else if (const auto *MatchedExpr =
+ Result.Nodes.getNodeAs<BinaryOperator>("rotate_expr")) {
+ const auto *MatchedVarDecl = Result.Nodes.getNodeAs<VarDecl>("v");
+ const auto ShiftLeftAmount =
+ Result.Nodes.getNodeAs<IntegerLiteral>("shift_left_amount")->getValue();
+ const auto ShiftRightAmount =
+ Result.Nodes.getNodeAs<IntegerLiteral>("shift_right_amount")
+ ->getValue();
+ const uint64_t MatchedVarSize =
+ Context.getTypeSize(MatchedVarDecl->getType());
+
+ // Overflowing shifts
+ if (ShiftLeftAmount.sge(MatchedVarSize))
+ return;
+ if (ShiftRightAmount.sge(MatchedVarSize))
+ return;
+ // Not a rotation.
+ if (MatchedVarSize != (ShiftLeftAmount + ShiftRightAmount))
+ return;
+
+ const bool NeedsIntCast =
+ MatchedExpr->getType() != MatchedVarDecl->getType();
+ const bool IsRotl = ShiftRightAmount.sge(ShiftLeftAmount);
+
+ const StringRef ReplacementFuncName = IsRotl ? "rotl" : "rotr";
+ const uint64_t ReplacementShiftAmount =
+ (IsRotl ? ShiftLeftAmount : ShiftRightAmount).getZExtValue();
+ auto Diag = diag(MatchedExpr->getBeginLoc(), "use 'std::%0' instead")
+ << ReplacementFuncName;
+ if (auto R = MatchedExpr->getSourceRange();
+ !R.getBegin().isMacroID() && !R.getEnd().isMacroID()) {
+ Diag << FixItHint::CreateReplacement(
+ MatchedExpr->getSourceRange(),
+ llvm::formatv("{3}std::{0}({1}, {2})", ReplacementFuncName,
+ MatchedVarDecl->getName(),
+ ReplacementShiftAmount,
+ NeedsIntCast ? "(int)" : "")
----------------
vbvictor wrote:
I think we should avoid suggesting C-casts in C++. For example, clang suggest `static_cast` as fixes: https://godbolt.org/z/r4qeo4hrq
But the best way is to handle this is a bool option to provide `static_cast<int>()` or not for fixes. (With off by default imho)
https://github.com/llvm/llvm-project/pull/186324
More information about the cfe-commits
mailing list