ziqingluo-90 created this revision.
ziqingluo-90 added reviewers: aaron.ballman, xazax.hun, steakhal, gribozavr, 
jkorous, NoQ, malavikasamak, t-rasmud.
Herald added a subscriber: rnkovacs.
Herald added a project: All.
ziqingluo-90 requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

For `-Wunsafe-buffer-usage` diagnostics, we want to warn about pointer 
arithmetics since resulting pointers can be used to access buffers.
Therefore, I add an `UnsafeGadget` representing general pointer arithmetic 
operations.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D139233

Files:
  clang/include/clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def
  clang/lib/Analysis/UnsafeBufferUsage.cpp
  clang/test/SemaCXX/warn-unsafe-buffer-usage.cpp

Index: clang/test/SemaCXX/warn-unsafe-buffer-usage.cpp
===================================================================
--- clang/test/SemaCXX/warn-unsafe-buffer-usage.cpp
+++ clang/test/SemaCXX/warn-unsafe-buffer-usage.cpp
@@ -32,7 +32,7 @@
   foo(p[1],             // expected-warning{{unchecked operation on raw buffer in expression}}
       pp[1][1],         // expected-warning2{{unchecked operation on raw buffer in expression}}
       1[1[pp]],         // expected-warning2{{unchecked operation on raw buffer in expression}}
-      1[pp][1]          // expected-warning2{{unchecked operation on raw buffer in expression}}      
+      1[pp][1]          // expected-warning2{{unchecked operation on raw buffer in expression}}
       );
 
   if (p[3]) {           // expected-warning{{unchecked operation on raw buffer in expression}}
@@ -50,7 +50,7 @@
   int a[10], b[10][10];
 
   // Not to warn subscripts on arrays
-  foo(a[1], 1[a],      
+  foo(a[1], 1[a],
       b[3][4],
       4[b][3],
       4[3[b]]);
@@ -135,7 +135,7 @@
 
 int garray[10];
 int * gp = garray;
-int gvar = gp[1];  // FIXME: file scope unsafe buffer access is not warned 
+int gvar = gp[1];  // FIXME: file scope unsafe buffer access is not warned
 
 void testLambdaCaptureAndGlobal(int * p) {
   int a[10];
@@ -163,10 +163,37 @@
   return &t[1]; // expected-warning{{unchecked operation on raw buffer in expression}}
 }
 
+// Testing pointer arithmetic for pointer-to-int, qualified multi-level
+// pointer, pointer to a template type, and auto type
+
+T_ptr_t getPtr();
+
+template<typename T>
+void testPointerArithmetic(int * p, const int **q, T * x) {
+  int a[10];
+  auto y = &a[0];
+
+  foo(p + 1, 1 + p, p - 1,      // expected-warning3{{unchecked operation on raw buffer in expression}}
+      *q + 1, 1 + *q, *q - 1,   // expected-warning3{{unchecked operation on raw buffer in expression}}
+      x + 1, 1 + x, x - 1,      // expected-warning3{{unchecked operation on raw buffer in expression}}
+      y + 1, 1 + y, y - 1,      // expected-warning3{{unchecked operation on raw buffer in expression}}
+      getPtr() + 1, 1 + getPtr(), getPtr() - 1 // expected-warning3{{unchecked operation on raw buffer in expression}}
+      );
+
+  p += 1;  p -= 1;  // expected-warning2{{unchecked operation on raw buffer in expression}}
+  *q += 1; *q -= 1; // expected-warning2{{unchecked operation on raw buffer in expression}}
+  y += 1; y -= 1;   // expected-warning2{{unchecked operation on raw buffer in expression}}
+  x += 1; x -= 1;   // expected-warning2{{unchecked operation on raw buffer in expression}}
+}
+
 void testTemplate(int * p) {
   int *a[10];
   foo(f(p, &p, a, a)[1]); // expected-warning{{unchecked operation on raw buffer in expression}}, \
                              expected-note{{in instantiation of function template specialization 'f<int *, 10>' requested here}}
+
+  const int **q = const_cast<const int **>(&p);
+
+  testPointerArithmetic(p, q, p); //expected-note{{in instantiation of function template specialization 'testPointerArithmetic<int>' requested here}}
 }
 
 // test that nested callable definitions are scanned only once
Index: clang/lib/Analysis/UnsafeBufferUsage.cpp
===================================================================
--- clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -359,6 +359,53 @@
     return {};
   }
 };
+
+/// A pointer arithmetic expression of one of the forms:
+///  \code
+///  ptr + n | n + ptr | ptr - n | ptr += n | ptr -= n
+///  \endcode
+class PointerArithmeticGadget : public UnsafeGadget {
+  const BinaryOperator *PA; // pointer arithmetic expression
+  const Expr * Ptr;         // the pointer expression in `PA`
+
+public:
+    PointerArithmeticGadget(const MatchFinder::MatchResult &Result)
+      : UnsafeGadget(Kind::PointerArithmetic),
+        PA(Result.Nodes.getNodeAs<BinaryOperator>("ptrAdd")),
+        Ptr(Result.Nodes.getNodeAs<Expr>("ptrAddPtr")) {}
+
+  static bool classof(const Gadget *G) {
+    return G->getKind() == Kind::PointerArithmetic;
+  }
+
+  static Matcher matcher() {
+    auto HasIntegerType = anyOf(
+          hasType(isInteger()), hasType(enumType()));
+    auto PtrAtRight = allOf(hasOperatorName("+"),
+                            hasRHS(expr(hasPointerType()).bind("ptrAddPtr")),
+                            hasLHS(HasIntegerType));
+    auto PtrAtLeft = allOf(
+           anyOf(hasOperatorName("+"), hasOperatorName("-"),
+                 hasOperatorName("+="), hasOperatorName("-=")),
+           hasLHS(expr(hasPointerType()).bind("ptrAddPtr")),
+           hasRHS(HasIntegerType));
+
+    return stmt(binaryOperator(anyOf(PtrAtLeft, PtrAtRight)).bind("ptrAdd"));
+  }
+
+  const Stmt *getBaseStmt() const override { return PA; }
+
+  DeclUseList getClaimedVarUseSites() const override {
+    if (const auto *DRE =
+            dyn_cast<DeclRefExpr>(Ptr->IgnoreParenImpCasts())) {
+      return {DRE};
+    }
+
+    return {};
+  }
+  // FIXME: pointer adding zero should be fine
+  //FIXME: this gadge will need a fix-it
+};
 } // namespace
 
 namespace {
Index: clang/include/clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def
===================================================================
--- clang/include/clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def
+++ clang/include/clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def
@@ -22,6 +22,7 @@
 UNSAFE_GADGET(Decrement)
 UNSAFE_GADGET(ArraySubscript)
 UNSAFE_GADGET(UnsafeBufferUsageAttr)
+UNSAFE_GADGET(PointerArithmetic)
 
 #undef SAFE_GADGET
 #undef UNSAFE_GADGET
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to