[clang] 04202b9 - [-Wunsafe-buffer-usage] Improve pointer matching pattern

via cfe-commits cfe-commits at lists.llvm.org
Fri Dec 16 20:41:10 PST 2022


Author: ziqingluo-90
Date: 2022-12-16T20:40:59-08:00
New Revision: 04202b94b684963a7b581a4a0f5baa8f7921b564

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

LOG: [-Wunsafe-buffer-usage] Improve pointer matching pattern

Generalize the pointer expression AST matcher in Unsafe Buffer Usage analysis.
Add test cases for various kinds of pointer usages.

Reviewed By: NoQ, aaron.ballman, xazax.hun

Differential Revision: https://reviews.llvm.org/D138318

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 c57b381160159..ba459d2176ad1 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -28,9 +28,7 @@ class Strategy;
 
 // Because we're dealing with raw pointers, let's define what we mean by that.
 static auto hasPointerType() {
-  return anyOf(hasType(pointerType()),
-               hasType(autoType(hasDeducedType(
-                   hasUnqualifiedDesugaredType(pointerType())))));
+    return hasType(hasCanonicalType(pointerType()));
 }
 
 namespace {

diff  --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage.cpp
index b84e05dae2f11..bff9fd666ac62 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage.cpp
@@ -1,4 +1,22 @@
-// RUN: %clang_cc1 -Wunsafe-buffer-usage -verify %s
+// RUN: %clang_cc1 -std=c++20 -Wunsafe-buffer-usage -include %s -verify %s
+#ifndef INCLUDED
+#define INCLUDED
+#pragma clang system_header
+
+// no spanification warnings for system headers
+void foo(...);  // let arguments of `foo` to hold testing expressions
+void testAsSystemHeader(char *p) {
+  ++p;
+
+  auto ap1 = p;
+  auto ap2 = &p;
+
+  foo(p[1],
+      ap1[1],
+      ap2[2][3]);
+}
+
+#else
 
 void testIncrement(char *p) {
   ++p; // expected-warning{{unchecked operation on raw buffer in expression}}
@@ -7,8 +25,6 @@ void testIncrement(char *p) {
   p--; // expected-warning{{unchecked operation on raw buffer in expression}}
 }
 
-void foo(...);   // let arguments of `foo` to hold testing expressions
-
 void * voidPtrCall(void);
 char * charPtrCall(void);
 
@@ -33,7 +49,7 @@ void testArraySubscripts(int *p, int **pp) {
 
   int a[10], b[10][10];
 
-  // not to warn subscripts on arrays
+  // Not to warn subscripts on arrays
   foo(a[0], a[1],
       0[a], 1[a],
       b[3][4],
@@ -54,7 +70,7 @@ void testArraySubscriptsWithAuto(int *p, int **pp) {
 
   auto ap3 = pp;
 
-  foo(pp[0][0]); // expected-warning2{{unchecked operation on raw buffer in expression}}
+  foo(ap3[0][0]); // expected-warning2{{unchecked operation on raw buffer in expression}}
 
   auto ap4 = *pp;
 
@@ -66,3 +82,102 @@ void testUnevaluatedContext(int * p) {
   foo(sizeof(p[1]),             // expected-warning{{unchecked operation on raw buffer in expression}}
       sizeof(decltype(p[1])));  // expected-warning{{unchecked operation on raw buffer in expression}}
 }
+
+void testQualifiedParameters(const int * p, const int * const q,
+			     const int a[10], const int b[10][10],
+			     int (&c)[10]) {
+  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
+      );
+}
+
+struct T {
+  int a[10];
+  int * b;
+  struct {
+    int a[10];
+    int * b;
+  } c;
+};
+
+typedef struct T T_t;
+
+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}}
+      );
+}
+
+int garray[10];
+int * gp = garray;
+int gvar = gp[1];  // TODO: this is not warned
+
+void testLambdaCaptureAndGlobal(int * p) {
+  int a[10];
+
+  auto Lam = [p, a]() {
+    return p[1] // expected-warning2{{unchecked operation on raw buffer in expression}}
+      + a[1] + garray[1]
+      + gp[1];  // expected-warning2{{unchecked operation on raw buffer in expression}}
+  };
+}
+
+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].b[1]  // expected-warning2{{unchecked operation on raw buffer in expression}}
+      );
+}
+
+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
+  return &t[1]; // expected-warning{{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}}
+}
+
+void testPointerToMember() {
+  struct S_t {
+    int x;
+    int * y;
+  } S;
+
+  int S_t::* p = &S_t::x;
+  int * S_t::* q = &S_t::y;
+
+  foo(S.*p,
+      (S.*q)[1]);  // expected-warning{{unchecked operation on raw buffer in expression}}
+}
+#endif


        


More information about the cfe-commits mailing list