[clang] [WIP][-Wunsafe-buffer-usage] Generalize DerefSimplePtrArithFixableGadget to non-literals (PR #68038)

via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 2 13:54:35 PDT 2023


https://github.com/jkorous-apple created https://github.com/llvm/llvm-project/pull/68038

None

>From 998d7174049deb0ec319155e3740b2d9031d2ff0 Mon Sep 17 00:00:00 2001
From: Jan Korous <jkorous at apple.com>
Date: Mon, 2 Oct 2023 13:41:24 -0700
Subject: [PATCH] [WIP][-Wunsafe-buffer-usage] Generalize
 DerefSimplePtrArithFixableGadget to non-literals

---
 clang/lib/Analysis/UnsafeBufferUsage.cpp | 30 +++++++++++++++++-------
 1 file changed, 22 insertions(+), 8 deletions(-)

diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index 49cfa7c0d3e3b27..062f57bf36b2c3f 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -986,12 +986,15 @@ class DerefSimplePtrArithFixableGadget : public FixableGadget {
   static constexpr const char *const BaseDeclRefExprTag = "BaseDRE";
   static constexpr const char *const DerefOpTag = "DerefOp";
   static constexpr const char *const AddOpTag = "AddOp";
-  static constexpr const char *const OffsetTag = "Offset";
+  // TODO RHS -> Offset
+  static constexpr const char *const OffsetLiteralTag = "RHSLiteral";
+  static constexpr const char *const OffsetUnsignedTag = "RHSUnsigned";
 
   const DeclRefExpr *BaseDeclRefExpr = nullptr;
   const UnaryOperator *DerefOp = nullptr;
   const BinaryOperator *AddOp = nullptr;
-  const IntegerLiteral *Offset = nullptr;
+  const IntegerLiteral *OffsetLiteral = nullptr;
+  const Expr *OffsetUnsigned = nullptr;
 
 public:
   DerefSimplePtrArithFixableGadget(const MatchFinder::MatchResult &Result)
@@ -1000,7 +1003,11 @@ class DerefSimplePtrArithFixableGadget : public FixableGadget {
             Result.Nodes.getNodeAs<DeclRefExpr>(BaseDeclRefExprTag)),
         DerefOp(Result.Nodes.getNodeAs<UnaryOperator>(DerefOpTag)),
         AddOp(Result.Nodes.getNodeAs<BinaryOperator>(AddOpTag)),
-        Offset(Result.Nodes.getNodeAs<IntegerLiteral>(OffsetTag)) {}
+        OffsetLiteral(Result.Nodes.getNodeAs<IntegerLiteral>(OffsetLiteralTag)),
+        OffsetUnsigned(Result.Nodes.getNodeAs<Expr>(OffsetUnsignedTag)) {
+        assert(OffsetLiteral || OffsetUnsigned && "Expecting some RHS");
+      }
+
 
   static Matcher matcher() {
     // clang-format off
@@ -1009,10 +1016,16 @@ class DerefSimplePtrArithFixableGadget : public FixableGadget {
                                         bind(BaseDeclRefExprTag)));
     auto PlusOverPtrAndInteger = expr(anyOf(
           binaryOperator(hasOperatorName("+"), hasLHS(ThePtr),
-                         hasRHS(integerLiteral().bind(OffsetTag)))
+                hasRHS(
+                  anyOf(
+                    integerLiteral().bind(OffsetLiteralTag),
+                    expr(hasType(isUnsignedInteger())).bind(OffsetUnsignedTag))))
                          .bind(AddOpTag),
           binaryOperator(hasOperatorName("+"), hasRHS(ThePtr),
-                         hasLHS(integerLiteral().bind(OffsetTag)))
+                hasLHS(
+                  anyOf(
+                    integerLiteral().bind(OffsetLiteralTag),
+                    expr(hasType(isUnsignedInteger())).bind(OffsetUnsignedTag))))
                          .bind(AddOpTag)));
     return isInUnspecifiedLvalueContext(unaryOperator(
         hasOperatorName("*"),
@@ -1566,9 +1579,10 @@ DerefSimplePtrArithFixableGadget::getFixits(const Strategy &s) const {
   if (VD && s.lookup(VD) == Strategy::Kind::Span) {
     ASTContext &Ctx = VD->getASTContext();
     // std::span can't represent elements before its begin()
-    if (auto ConstVal = Offset->getIntegerConstantExpr(Ctx))
-      if (ConstVal->isNegative())
-        return std::nullopt;
+    if (OffsetLiteral)
+      if (auto ConstVal = OffsetLiteral->getIntegerConstantExpr(Ctx))
+        if (ConstVal->isNegative())
+          return std::nullopt;
 
     // note that the expr may (oddly) has multiple layers of parens
     // example:



More information about the cfe-commits mailing list