8000 [-Wunsafe-buffer-usage] Fix false warnings when const sized array is … · llvm/llvm-project@3931566 · GitHub
[go: up one dir, main page]

Skip to content

Commit 3931566

Browse files
malavikasamakMalavikaSamak
and
MalavikaSamak
authored
[-Wunsafe-buffer-usage] Fix false warnings when const sized array is safely accessed (array [idx %const]) (#140113)
The -Wunsafe-buffer-usage analysis currently warns when a const sized array is safely accessed, with an index that is bound by the remainder operator. The false alarm is now suppressed. Example: int circular_buffer(int array[10], uint idx) { return array[idx %10]; // Safe operation } rdar://148443453 --------- Co-authored-by: MalavikaSamak <malavika2@apple.com>
1 parent f7ef8dc commit 3931566

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

clang/lib/Analysis/UnsafeBufferUsage.cpp

+16-1
Original file line numberDiff line numberDiff line change
@@ -600,12 +600,27 @@ static bool isSafeArraySubscript(const ArraySubscriptExpr &Node,
600600
} else if (const auto *BE = dyn_cast<BinaryOperator>(IndexExpr)) {
601601
// For an integer expression `e` and an integer constant `n`, `e & n` and
602602
// `n & e` are bounded by `n`:
603-
if (BE->getOpcode() != BO_And)
603+
if (BE->getOpcode() != BO_And && BE->getOpcode() != BO_Rem)
604604
return false;
605605

606606
const Expr *LHS = BE->getLHS();
607607
const Expr *RHS = BE->getRHS();
608608

609+
if (BE->getOpcode() == BO_Rem) {
610+
// If n is a negative number, then n % const can be greater than const
611+
if (!LHS->getType()->isUnsignedIntegerType()) {
612+
return false;
613+
}
614+
615+
if (!RHS->isValueDependent() && RHS->EvaluateAsInt(EVResult, Ctx)) {
616+
llvm::APSInt result = EVResult.Val.getInt();
617+
if (result.isNonNegative() && result.getLimitedValue() <= limit)
618+
return true;
619+
}
620+
621+
return false;
622+
}
623+
609624
if ((!LHS->isValueDependent() &&
610625
LHS->EvaluateAsInt(EVResult, Ctx)) || // case: `n & e`
611626
(!RHS->isValueDependent() &&

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

+15-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,21 @@ void constant_idx_safe0(unsigned idx) {
3535
buffer[0] = 0;
3636
}
3737

38-
int array[10]; // expected-warning {{'array' is an unsafe buffer that does not perform bounds checks}}
38+
int array[10]; // expected-warning 3{{'array' is an unsafe buffer that does not perform bounds checks}}
39+
40+
void circular_access_unsigned(unsigned idx) {
41+
array[idx % 10];
42+
array[idx % 11]; // expected-note {{used in buffer access here}}
43+
array[(idx + 3) % 10];
44+
array[(--idx) % 8];
45+
array[idx & 9 % 10];
46+
array[9 & idx % 11];
47+
array [12 % 10];
48+
}
49+
50+
void circular_access_signed(int idx) {
51+
array[idx % 10]; // expected-note {{used in buffer access here}}
52+
}
3953

4054
void masked_idx1(unsigned long long idx, Foo f) {
4155
// Bitwise and operation

0 commit comments

Comments
 (0)
0