[clang] fe93da2 - [-Wunsafe-buffer-usage] Emit warnings about unsafe operations on arrays

Rashmi Mudduluru via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 17 16:30:25 PST 2023


Author: Rashmi Mudduluru
Date: 2023-01-17T16:30:13-08:00
New Revision: fe93da22aa7bd57e277571cd692c7c0cc51c0478

URL: https://github.com/llvm/llvm-project/commit/fe93da22aa7bd57e277571cd692c7c0cc51c0478
DIFF: https://github.com/llvm/llvm-project/commit/fe93da22aa7bd57e277571cd692c7c0cc51c0478.diff

LOG: [-Wunsafe-buffer-usage] Emit warnings about unsafe operations on arrays

Differential Revision: https://reviews.llvm.org/D141725/new/

Added: 
    

Modified: 
    clang/lib/Analysis/UnsafeBufferUsage.cpp
    clang/test/SemaCXX/warn-unsafe-buffer-usage.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index 97f81368273e9..fa72d20bea6fe 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -133,6 +133,10 @@ static auto hasPointerType() {
     return hasType(hasCanonicalType(pointerType()));
 }
 
+static auto hasArrayType() {
+    return hasType(hasCanonicalType(arrayType()));
+}
+
 namespace {
 /// Gadget is an individual operation in the code that may be of interest to
 /// this analysis. Each (non-abstract) subclass corresponds to a specific
@@ -292,9 +296,13 @@ class ArraySubscriptGadget : public WarningGadget {
   static Matcher matcher() {
     // FIXME: What if the index is integer literal 0? Should this be
     // a safe gadget in this case?
-    return stmt(arraySubscriptExpr(hasBase(ignoringParenImpCasts(hasPointerType())),
-                                   unless(hasIndex(integerLiteral(equals(0)))))
-                .bind(ArraySubscrTag));
+      // clang-format off
+      return stmt(arraySubscriptExpr(
+            hasBase(ignoringParenImpCasts(
+              anyOf(hasPointerType(), hasArrayType()))),
+            unless(hasIndex(integerLiteral(equals(0)))))
+            .bind(ArraySubscrTag));
+      // clang-format on
   }
 
   const ArraySubscriptExpr *getBaseStmt() const override { return ASE; }
@@ -516,7 +524,8 @@ static std::tuple<FixableGadgetList, WarningGadgetList, DeclUseTracker> findGadg
 #include "clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def"
         // In parallel, match all DeclRefExprs so that to find out
         // whether there are any uncovered by gadgets.
-        declRefExpr(hasPointerType(), to(varDecl())).bind("any_dre"),
+        declRefExpr(anyOf(hasPointerType(), hasArrayType()),
+                    to(varDecl())).bind("any_dre"),
         // Also match DeclStmts because we'll need them when fixing
         // their underlying VarDecls that otherwise don't have
         // any backreferences to DeclStmts.

diff  --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage.cpp
index 476ec73c4f744..87831334746aa 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage.cpp
@@ -49,11 +49,10 @@ void testArraySubscripts(int *p, int **pp) {
 
   int a[10], b[10][10];
 
-  // Not to warn subscripts on arrays
-  foo(a[1], 1[a],
-      b[3][4],
-      4[b][3],
-      4[3[b]]);
+  foo(a[1], 1[a], // expected-warning2{{unchecked operation on raw buffer in expression}}
+  b[3][4],  // expected-warning2{{unchecked operation on raw buffer in expression}}
+  4[b][3],  // expected-warning2{{unchecked operation on raw buffer in expression}}
+  4[3[b]]); // expected-warning2{{unchecked operation on raw buffer in expression}}
 
   // Not to warn when index is zero
   foo(p[0], pp[0][0], 0[0[pp]], 0[pp][0],
@@ -96,8 +95,7 @@ void testQualifiedParameters(const int * p, const int * const q,
   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}}
       a[1],                // expected-warning{{unchecked operation on raw buffer in expression}}     `a` is of pointer type
-      b[1][2],             // expected-warning{{unchecked operation on raw buffer in expression}}     `b[1]` is of array type
-      c[1]                 // `c` is of array type
+      b[1][2]              // expected-warning2{{unchecked operation on raw buffer in expression}}     `b[1]` is of array type
       );
 }
 
@@ -116,27 +114,27 @@ T_t funRetT();
 T_t * funRetTStar();
 
 void testStructMembers(struct T * sp, struct T s, T_t * sp2, T_t s2) {
-  foo(sp->a[1],
-      sp->b[1],     // expected-warning{{unchecked operation on raw buffer in expression}}
-      sp->c.a[1],
-      sp->c.b[1],   // expected-warning{{unchecked operation on raw buffer in expression}}
-      s.a[1],
-      s.b[1],       // expected-warning{{unchecked operation on raw buffer in expression}}
-      s.c.a[1],
-      s.c.b[1],     // expected-warning{{unchecked operation on raw buffer in expression}}
-      sp2->a[1],
-      sp2->b[1],    // expected-warning{{unchecked operation on raw buffer in expression}}
-      sp2->c.a[1],
-      sp2->c.b[1],  // expected-warning{{unchecked operation on raw buffer in expression}}
-      s2.a[1],
-      s2.b[1],      // expected-warning{{unchecked operation on raw buffer in expression}}
-      s2.c.a[1],
-      s2.c.b[1],           // expected-warning{{unchecked operation on raw buffer in expression}}
-      funRetT().a[1],
-      funRetT().b[1],      // expected-warning{{unchecked operation on raw buffer in expression}}
-      funRetTStar()->a[1],
-      funRetTStar()->b[1]  // expected-warning{{unchecked operation on raw buffer in expression}}
-      );
+  foo(sp->a[1],   // expected-warning{{unchecked operation on raw buffer in expression}}
+     sp->b[1],     // expected-warning{{unchecked operation on raw buffer in expression}}
+     sp->c.a[1],   // expected-warning{{unchecked operation on raw buffer in expression}}
+     sp->c.b[1],   // expected-warning{{unchecked operation on raw buffer in expression}}
+     s.a[1],       // expected-warning{{unchecked operation on raw buffer in expression}}
+     s.b[1],       // expected-warning{{unchecked operation on raw buffer in expression}}
+     s.c.a[1],     // expected-warning{{unchecked operation on raw buffer in expression}}
+     s.c.b[1],     // expected-warning{{unchecked operation on raw buffer in expression}}
+     sp2->a[1],    // expected-warning{{unchecked operation on raw buffer in expression}}
+     sp2->b[1],    // expected-warning{{unchecked operation on raw buffer in expression}}
+     sp2->c.a[1],  // expected-warning{{unchecked operation on raw buffer in expression}}
+     sp2->c.b[1],  // expected-warning{{unchecked operation on raw buffer in expression}}
+     s2.a[1],    // expected-warning{{unchecked operation on raw buffer in expression}}
+     s2.b[1],      // expected-warning{{unchecked operation on raw buffer in expression}}
+     s2.c.a[1],           // expected-warning{{unchecked operation on raw buffer in expression}}
+     s2.c.b[1],           // expected-warning{{unchecked operation on raw buffer in expression}}
+     funRetT().a[1],      // expected-warning{{unchecked operation on raw buffer in expression}}
+     funRetT().b[1],      // expected-warning{{unchecked operation on raw buffer in expression}}
+     funRetTStar()->a[1], // expected-warning{{unchecked operation on raw buffer in expression}}
+     funRetTStar()->b[1]  // expected-warning{{unchecked operation on raw buffer in expression}}
+  );
 }
 
 int garray[10];
@@ -148,7 +146,7 @@ void testLambdaCaptureAndGlobal(int * p) {
 
   auto Lam = [p, a]() {
     return p[1] // expected-warning{{unchecked operation on raw buffer in expression}}
-      + a[1] + garray[1]
+      + a[1] + garray[1] // expected-warning2{{unchecked operation on raw buffer in expression}}
       + gp[1];  // expected-warning{{unchecked operation on raw buffer in expression}}
   };
 }
@@ -157,7 +155,7 @@ typedef T_t * T_ptr_t;
 
 void testTypedefs(T_ptr_t p) {
   foo(p[1],      // expected-warning{{unchecked operation on raw buffer in expression}}
-      p[1].a[1], // expected-warning{{unchecked operation on raw buffer in expression}}
+      p[1].a[1], // expected-warning2{{unchecked operation on raw buffer in expression}}
       p[1].b[1]  // expected-warning2{{unchecked operation on raw buffer in expression}}
       );
 }
@@ -165,7 +163,7 @@ void testTypedefs(T_ptr_t p) {
 template<typename T, int N> T f(T t, T * pt, T a[N], T (&b)[N]) {
   foo(pt[1],    // expected-warning{{unchecked operation on raw buffer in expression}}
       a[1],     // expected-warning{{unchecked operation on raw buffer in expression}}
-      b[1]);    // `b` is of array type
+      b[1]);    // expected-warning{{unchecked operation on raw buffer in expression}}
   return &t[1]; // expected-warning{{unchecked operation on raw buffer in expression}}
 }
 
@@ -269,10 +267,48 @@ void testNestedCallableDefinition(int * p) {
      );
 }
 
-void testVariableDecls(int * p) {
+int testVariableDecls(int * p) {
   int * q = p++;      // expected-warning{{unchecked operation on raw buffer in expression}}
   int a[p[1]];        // expected-warning{{unchecked operation on raw buffer in expression}}
   int b = p[1];       // expected-warning{{unchecked operation on raw buffer in expression}}
+  return p[1];        // expected-warning{{unchecked operation on raw buffer in expression}}
+}
+    
+template<typename T> void fArr(T t[]) {
+  foo(t[1]);   // expected-warning{{unchecked operation on raw buffer in expression}}
+  T ar[8];
+  foo(ar[5]);  // expected-warning{{unchecked operation on raw buffer in expression}}
+}
+
+template void fArr<int>(int t[]); // expected-note {{in instantiation of function template specialization 'fArr<int>' requested here}}
+
+  int testReturn(int t[]) {
+  return t[1]; // expected-warning{{unchecked operation on raw buffer in expression}}
+ }
+    
+//FIXME: Array access warnings on 0-indices;ArraySubscriptGadget excludes 0 index for both raw pointers and arrays!
+int testArrayAccesses(int n) {
+          
+  // auto deduced array type
+  int cArr[2][3] = {{1, 2, 3}, {4, 5, 6}};
+  int d = cArr[0][0];
+  foo(cArr[0][0]);
+  foo(cArr[1][2]);     // expected-warning2{{unchecked operation on raw buffer in expression}}
+  auto cPtr = cArr[1][2];  // expected-warning2{{unchecked operation on raw buffer in expression}}
+  foo(cPtr);
+          
+          // Typdefs
+  typedef int A[3];
+  const A tArr = {4, 5, 6};
+  foo(tArr[0], tArr[1]);  // expected-warning{{unchecked operation on raw buffer in expression}}
+  return cArr[0][1];  // expected-warning{{unchecked operation on raw buffer in expression}}
+}
+    
+void testArrayPtrArithmetic(int x[]) {
+  foo (x + 3); // expected-warning{{unchecked operation on raw buffer in expression}}
+         
+  int y[3] = {0, 1, 2};
+  foo(y + 4); // expected-warning{{unchecked operation on raw buffer in expression}}
 }
 
 #endif


        


More information about the cfe-commits mailing list