Skip to content

Commit da96efb

Browse files
author
MalavikaSamak
committed
Add more tests and a comment explaining the idea behind the change.
1 parent bf1f0b8 commit da96efb

File tree

2 files changed

+12
-8
lines changed

2 files changed

+12
-8
lines changed

clang/lib/Analysis/UnsafeBufferUsage.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -463,24 +463,26 @@ AST_MATCHER(ArraySubscriptExpr, isSafeArraySubscript) {
463463
if (ArrIdx.isNonNegative() && ArrIdx.getLimitedValue() < limit)
464464
return true;
465465
} else if (const auto *BE = dyn_cast<BinaryOperator>(IndexExpr)) {
466+
// For an integer expression `e` and an integer constant `n`, `e & n` and
467+
// `n & e` are bounded by `n`:
466468
if (BE->getOpcode() != BO_And)
467469
return false;
468470

469471
const Expr *LHS = BE->getLHS();
470472
const Expr *RHS = BE->getRHS();
471473

472474
if ((!LHS->isValueDependent() &&
473-
LHS->EvaluateAsInt(EVResult, Finder->getASTContext())) ||
475+
LHS->EvaluateAsInt(EVResult,
476+
Finder->getASTContext())) || // case: `n & e`
474477
(!RHS->isValueDependent() &&
475-
RHS->EvaluateAsInt(EVResult, Finder->getASTContext()))) {
478+
RHS->EvaluateAsInt(EVResult, Finder->getASTContext()))) { // `e & n`
476479
llvm::APSInt result = EVResult.Val.getInt();
477480
if (result.isNonNegative() && result.getLimitedValue() < limit)
478481
return true;
479482
}
480483
return false;
481-
482-
} else
483-
return false;
484+
}
485+
return false;
484486
}
485487

486488
AST_MATCHER_P(CallExpr, hasNumArgs, unsigned, Num) {

clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,14 @@ int array[10]; // expected-warning {{'array' is an unsafe buffer that does not p
3939

4040
void masked_idx1(unsigned long long idx, Foo f) {
4141
// Bitwise and operation
42-
array[idx & 5] = 10; // no warning
42+
array[idx & 5] = 10; // no-warning
43+
array[5 &idx] = 12; // no-warning
4344
array[idx & 11 & 5] = 3; // no warning
4445
array[idx & 11] = 20; // expected-note{{used in buffer access here}}
4546
array[idx &=5]; // expected-note{{used in buffer access here}}
46-
array[f.x & 5];
47+
array[f.x & 5]; // no-warning
48+
array[5 & f.x]; // no-warning
49+
array[f.x & (-5)]; // expected-note{{used in buffer access here}}
4750
}
4851

4952
typedef unsigned long long uint64_t;
@@ -63,7 +66,6 @@ void masked_idx_safe(unsigned long long idx) {
6366
array2[6 & idx & (idx + 1) & 5]; // expected-note{{used in buffer access here}}
6467
}
6568

66-
6769
void constant_idx_unsafe(unsigned idx) {
6870
int buffer[10]; // expected-warning{{'buffer' is an unsafe buffer that does not perform bounds checks}}
6971
// expected-note@-1{{change type of 'buffer' to 'std::array' to label it for hardening}}

0 commit comments

Comments
 (0)