[clang] [Clang] Optimize -Wunsafe-buffer-usage. (PR #125492)
Ilya Biryukov via cfe-commits
cfe-commits at lists.llvm.org
Fri Feb 28 06:55:29 PST 2025
================
@@ -1948,31 +2294,59 @@ class DerefSimplePtrArithFixableGadget : public FixableGadget {
const IntegerLiteral *Offset = nullptr;
public:
- DerefSimplePtrArithFixableGadget(const MatchFinder::MatchResult &Result)
+ DerefSimplePtrArithFixableGadget(const MatchResult &Result)
: FixableGadget(Kind::DerefSimplePtrArithFixable),
- BaseDeclRefExpr(
- Result.Nodes.getNodeAs<DeclRefExpr>(BaseDeclRefExprTag)),
- DerefOp(Result.Nodes.getNodeAs<UnaryOperator>(DerefOpTag)),
- AddOp(Result.Nodes.getNodeAs<BinaryOperator>(AddOpTag)),
- Offset(Result.Nodes.getNodeAs<IntegerLiteral>(OffsetTag)) {}
-
- static Matcher matcher() {
- // clang-format off
- auto ThePtr = expr(hasPointerType(),
- ignoringImpCasts(declRefExpr(toSupportedVariable()).
- bind(BaseDeclRefExprTag)));
- auto PlusOverPtrAndInteger = expr(anyOf(
- binaryOperator(hasOperatorName("+"), hasLHS(ThePtr),
- hasRHS(integerLiteral().bind(OffsetTag)))
- .bind(AddOpTag),
- binaryOperator(hasOperatorName("+"), hasRHS(ThePtr),
- hasLHS(integerLiteral().bind(OffsetTag)))
- .bind(AddOpTag)));
- return isInUnspecifiedLvalueContext(unaryOperator(
- hasOperatorName("*"),
- hasUnaryOperand(ignoringParens(PlusOverPtrAndInteger)))
- .bind(DerefOpTag));
- // clang-format on
+ BaseDeclRefExpr(Result.getNodeAs<DeclRefExpr>(BaseDeclRefExprTag)),
+ DerefOp(Result.getNodeAs<UnaryOperator>(DerefOpTag)),
+ AddOp(Result.getNodeAs<BinaryOperator>(AddOpTag)),
+ Offset(Result.getNodeAs<IntegerLiteral>(OffsetTag)) {}
+
+ static bool matches(const Stmt *S, llvm::SmallVector<MatchResult> &Results) {
+ bool Found = false;
+ auto IsPtr = [](const Expr *E, MatchResult &R) {
+ if (!E || !hasPointerType(*E))
+ return false;
+ const auto *DRE = dyn_cast<DeclRefExpr>(E->IgnoreImpCasts());
+ if (!DRE || !isSupportedVariable(*DRE))
+ return false;
+ R.addNode(BaseDeclRefExprTag, DynTypedNode::create(*DRE));
+ return true;
+ };
+ const auto PlusOverPtrAndInteger = [&IsPtr](const Expr *E, MatchResult &R) {
+ const auto *BO = dyn_cast<BinaryOperator>(E);
+ if (!BO || BO->getOpcode() != BO_Add)
+ return false;
+
+ const auto *LHS = BO->getLHS();
+ const auto *RHS = BO->getRHS();
+ if (isa<IntegerLiteral>(RHS) && IsPtr(LHS, R)) {
+ R.addNode(OffsetTag, DynTypedNode::create(*RHS));
+ R.addNode(AddOpTag, DynTypedNode::create(*BO));
+ return true;
+ }
+ if (isa<IntegerLiteral>(LHS) && IsPtr(RHS, R)) {
+ R.addNode(OffsetTag, DynTypedNode::create(*LHS));
+ R.addNode(AddOpTag, DynTypedNode::create(*BO));
+ return true;
+ }
+ return false;
+ };
+ const auto InnerMatcher = [&PlusOverPtrAndInteger, &Found,
+ &Results](const Expr *E) {
+ const auto *UO = dyn_cast<UnaryOperator>(E);
+ if (!UO || UO->getOpcode() != UO_Deref)
+ return;
+
+ const auto *Operand = UO->getSubExpr()->IgnoreParens();
+ MatchResult R;
+ if (PlusOverPtrAndInteger(Operand, R)) {
+ R.addNode(DerefOpTag, DynTypedNode::create(*UO));
+ Results.emplace_back(R);
----------------
ilya-biryukov wrote:
NIT: std::move(R) for efficiency.
https://github.com/llvm/llvm-project/pull/125492
More information about the cfe-commits
mailing list