Skip to content

Commit ca068b2

Browse files
author
MalavikaSamak
committed
[Wunsafe-buffer-usage] Fix false positive when const sized array is indexed by const evaluated expressions
Do not warn when constant sized array is indexed by expressions that evaluate to a const value. For instance, sizeof(T) expression value can be evaluated at compile time and if an array is indexed by such an expression, it's bounds can be validated. (rdar://140320289)
1 parent 171d3ed commit ca068b2

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

clang/lib/Analysis/UnsafeBufferUsage.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -453,8 +453,11 @@ AST_MATCHER(ArraySubscriptExpr, isSafeArraySubscript) {
453453
return false;
454454
}
455455

456-
if (const auto *IdxLit = dyn_cast<IntegerLiteral>(Node.getIdx())) {
457-
const APInt ArrIdx = IdxLit->getValue();
456+
Expr::EvalResult EVResult;
457+
if (Node.getIdx()->EvaluateAsInt(EVResult, Finder->getASTContext())) {
458+
llvm::APSInt ArrIdx = EVResult.Val.getInt();
459+
// FIXME: ArrIdx.isNegative() we could immediately emit an error as that's a
460+
// bug
458461
if (ArrIdx.isNonNegative() && ArrIdx.getLimitedValue() < limit)
459462
return true;
460463
}

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,35 @@ char access_strings() {
9292
c = array_string[5];
9393
return c;
9494
}
95+
96+
struct T {
97+
int array[10];
98+
};
99+
100+
const int index = 1;
101+
102+
constexpr int get_const(int x) {
103+
if(x < 3)
104+
return ++x;
105+
else
106+
return x + 5;
107+
};
108+
109+
void array_indexed_const_expr(unsigned idx) {
110+
// expected-note@+2 {{change type of 'arr' to 'std::array' to label it for hardening}}
111+
// expected-warning@+1{{'arr' is an unsafe buffer that does not perform bounds checks}}
112+
int arr[10];
113+
arr[sizeof(int)] = 5;
114+
115+
int array[sizeof(T)];
116+
array[sizeof(int)] = 5;
117+
array[sizeof(T) -1 ] = 3;
118+
119+
int k = arr[6 & 5];
120+
k = arr[2 << index];
121+
k = arr[8 << index]; // expected-note {{used in buffer access here}}
122+
k = arr[16 >> 1];
123+
k = arr[get_const(index)];
124+
k = arr[get_const(5)]; // expected-note {{used in buffer access here}}
125+
k = arr[get_const(4)];
126+
}

0 commit comments

Comments
 (0)