[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