Skip to content

[-Wunsafe-buffer-usage] Suppress warning for multi-dimensional constant arrays #118249

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 12 additions & 23 deletions clang/lib/Analysis/UnsafeBufferUsage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -433,36 +433,25 @@ AST_MATCHER(ArraySubscriptExpr, isSafeArraySubscript) {
// already duplicated
// - call both from Sema and from here

const auto *BaseDRE =
dyn_cast<DeclRefExpr>(Node.getBase()->IgnoreParenImpCasts());
const auto *SLiteral =
dyn_cast<StringLiteral>(Node.getBase()->IgnoreParenImpCasts());
uint64_t size;

if (!BaseDRE && !SLiteral)
uint64_t limit;
if (const auto *CATy =
dyn_cast<ConstantArrayType>(Node.getBase()
->IgnoreParenImpCasts()
->getType()
->getUnqualifiedDesugaredType())) {
limit = CATy->getLimitedSize();
} else if (const auto *SLiteral = dyn_cast<StringLiteral>(
Node.getBase()->IgnoreParenImpCasts())) {
limit = SLiteral->getLength() + 1;
} else {
return false;

if (BaseDRE) {
if (!BaseDRE->getDecl())
return false;
const auto *CATy = Finder->getASTContext().getAsConstantArrayType(
BaseDRE->getDecl()->getType());
if (!CATy) {
return false;
}
size = CATy->getLimitedSize();
} else if (SLiteral) {
size = SLiteral->getLength() + 1;
}

if (const auto *IdxLit = dyn_cast<IntegerLiteral>(Node.getIdx())) {
const APInt ArrIdx = IdxLit->getValue();
// FIXME: ArrIdx.isNegative() we could immediately emit an error as that's a
// bug
if (ArrIdx.isNonNegative() && ArrIdx.getLimitedValue() < size)
if (ArrIdx.isNonNegative() && ArrIdx.getLimitedValue() < limit)
return true;
}

return false;
}

Expand Down
40 changes: 40 additions & 0 deletions clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,43 @@ void constant_id_string(unsigned idx) {
unsafe_char = ""[1]; //expected-warning{{unsafe buffer access}}
unsafe_char = ""[idx]; //expected-warning{{unsafe buffer access}}
}

typedef float Float4x4[4][4];

// expected-warning@+1 {{'matrix' is an unsafe buffer that does not perform bounds checks}}
float two_dimension_array(Float4x4& matrix, unsigned idx) {
// expected-warning@+1{{unsafe buffer access}}
float a = matrix[0][4];

a = matrix[0][3];

// expected-note@+1{{used in buffer access here}}
a = matrix[4][0];

a = matrix[idx][0]; // expected-note{{used in buffer access here}}

a = matrix[0][idx]; //expected-warning{{unsafe buffer access}}

a = matrix[idx][idx]; //expected-warning{{unsafe buffer access}} // expected-note{{used in buffer access here}}

return matrix[1][1];
}

typedef float Float2x3x4[2][3][4];
float multi_dimension_array(Float2x3x4& matrix) {
float *f = matrix[0][2];
return matrix[1][2][3];
}

char array_strings[][11] = {
"Apple", "Banana", "Cherry", "Date", "Elderberry"
};

char array_string[] = "123456";

char access_strings() {
char c = array_strings[0][4];
c = array_strings[3][10];
c = array_string[5];
return c;
}
1 change: 0 additions & 1 deletion clang/test/SemaCXX/warn-unsafe-buffer-usage-field-attr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ void test_attribute_multiple_fields (D d) {

int v = d.buf[0]; //expected-warning{{field 'buf' prone to unsafe buffer manipulation}}

//expected-warning@+1{{unsafe buffer access}}
v = d.buf[5]; //expected-warning{{field 'buf' prone to unsafe buffer manipulation}}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ void isArrayDecayToPointerUPC(int a[][10], int (*b)[10]) {
// expected-warning@-2{{'b' is an unsafe pointer used for buffer access}}
int tmp;

tmp = a[5][5] + b[5][5]; // expected-warning2{{unsafe buffer access}} expected-note2{{used in buffer access here}}
tmp = a[5][5] + b[5][5]; // expected-note2{{used in buffer access here}}
}

// parameter having default values:
Expand Down
39 changes: 24 additions & 15 deletions clang/test/SemaCXX/warn-unsafe-buffer-usage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ void testQualifiedParameters(const int * p, const int * const q, const int a[10]
q[1], 1[q], q[-1], // expected-note3{{used in buffer access here}}
a[1], // expected-note{{used in buffer access here}} `a` is of pointer type
b[1][2] // expected-note{{used in buffer access here}} `b[1]` is of array type
// expected-warning@-1{{unsafe buffer access}}
);
}

Expand All @@ -128,29 +127,41 @@ T_t funRetT();
T_t * funRetTStar();

void testStructMembers(struct T * sp, struct T s, T_t * sp2, T_t s2) {
foo(sp->a[1], // expected-warning{{unsafe buffer access}}
foo(sp->a[1],
sp->b[1], // expected-warning{{unsafe buffer access}}
sp->c.a[1], // expected-warning{{unsafe buffer access}}
sp->c.a[1],
sp->c.b[1], // expected-warning{{unsafe buffer access}}
s.a[1], // expected-warning{{unsafe buffer access}}
s.a[1],
s.b[1], // expected-warning{{unsafe buffer access}}
s.c.a[1], // expected-warning{{unsafe buffer access}}
s.c.a[1],
s.c.b[1], // expected-warning{{unsafe buffer access}}
sp2->a[1], // expected-warning{{unsafe buffer access}}
sp2->a[1],
sp2->b[1], // expected-warning{{unsafe buffer access}}
sp2->c.a[1], // expected-warning{{unsafe buffer access}}
sp2->c.a[1],
sp2->c.b[1], // expected-warning{{unsafe buffer access}}
s2.a[1], // expected-warning{{unsafe buffer access}}
s2.a[1],
s2.b[1], // expected-warning{{unsafe buffer access}}
s2.c.a[1], // expected-warning{{unsafe buffer access}}
s2.c.a[1],
s2.c.b[1], // expected-warning{{unsafe buffer access}}
funRetT().a[1], // expected-warning{{unsafe buffer access}}
funRetT().a[1],
funRetT().b[1], // expected-warning{{unsafe buffer access}}
funRetTStar()->a[1], // expected-warning{{unsafe buffer access}}
funRetTStar()->a[1],
funRetTStar()->b[1] // expected-warning{{unsafe buffer access}}
);
}

union Foo {
bool b;
int arr[10];
};

int testUnionMembers(Foo f) {
int a = f.arr[0];
a = f.arr[5];
a = f.arr[10]; // expected-warning{{unsafe buffer access}}
return a;
}

int garray[10]; // expected-warning{{'garray' is an unsafe buffer that does not perform bounds checks}}
int * gp = garray; // expected-warning{{'gp' is an unsafe pointer used for buffer access}}
int gvar = gp[1]; // FIXME: file scope unsafe buffer access is not warned
Expand Down Expand Up @@ -213,7 +224,6 @@ void testTypedefs(T_ptr_t p) {
// expected-warning@-1{{'p' is an unsafe pointer used for buffer access}}
foo(p[1], // expected-note{{used in buffer access here}}
p[1].a[1], // expected-note{{used in buffer access here}}
// expected-warning@-1{{unsafe buffer access}}
p[1].b[1] // expected-note{{used in buffer access here}}
// expected-warning@-1{{unsafe buffer access}}
);
Expand All @@ -223,10 +233,9 @@ template<typename T, int N> T f(T t, T * pt, T a[N], T (&b)[N]) {
// expected-warning@-1{{'t' is an unsafe pointer used for buffer access}}
// expected-warning@-2{{'pt' is an unsafe pointer used for buffer access}}
// expected-warning@-3{{'a' is an unsafe pointer used for buffer access}}
// expected-warning@-4{{'b' is an unsafe buffer that does not perform bounds checks}}
foo(pt[1], // expected-note{{used in buffer access here}}
a[1], // expected-note{{used in buffer access here}}
b[1]); // expected-note{{used in buffer access here}}
b[1]);
return &t[1]; // expected-note{{used in buffer access here}}
}

Expand Down Expand Up @@ -376,7 +385,7 @@ int testArrayAccesses(int n, int idx) {
typedef int A[3];
const A tArr = {4, 5, 6};
foo(tArr[0], tArr[1]);
return cArr[0][1]; // expected-warning{{unsafe buffer access}}
return cArr[0][1];
}

void testArrayPtrArithmetic(int x[]) { // expected-warning{{'x' is an unsafe pointer used for buffer access}}
Expand Down
Loading