[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