Skip to content

Commit f7d4148

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 e0ea9fd commit f7d4148

File tree

2 files changed

+35
-2
lines changed

2 files changed

+35
-2
lines changed

clang/lib/Analysis/UnsafeBufferUsage.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,8 +461,9 @@ AST_MATCHER(ArraySubscriptExpr, isSafeArraySubscript) {
461461
size = SLiteral->getLength() + 1;
462462
}
463463

464-
if (const auto *IdxLit = dyn_cast<IntegerLiteral>(Node.getIdx())) {
465-
const APInt ArrIdx = IdxLit->getValue();
464+
Expr::EvalResult EVResult;
465+
if (Node.getIdx()->EvaluateAsInt(EVResult, Finder->getASTContext())) {
466+
llvm::APSInt ArrIdx = EVResult.Val.getInt();
466467
// FIXME: ArrIdx.isNegative() we could immediately emit an error as that's a
467468
// bug
468469
if (ArrIdx.isNonNegative() && ArrIdx.getLimitedValue() < size)

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,35 @@ void constant_id_string(unsigned idx) {
5252
unsafe_char = ""[1]; //expected-warning{{unsafe buffer access}}
5353
unsafe_char = ""[idx]; //expected-warning{{unsafe buffer access}}
5454
}
55+
56+
struct T {
57+
int array[10];
58+
};
59+
60+
const int index = 1;
61+
62+
constexpr int get_const(int x) {
63+
if(x < 3)
64+
return ++x;
65+
else
66+
return x + 5;
67+
};
68+
69+
void array_indexed_const_expr(unsigned idx) {
70+
// expected-note@+2 {{change type of 'arr' to 'std::array' to label it for hardening}}
71+
// expected-warning@+1{{'arr' is an unsafe buffer that does not perform bounds checks}}
72+
int arr[10];
73+
arr[sizeof(int)] = 5;
74+
75+
int array[sizeof(T)];
76+
array[sizeof(int)] = 5;
77+
array[sizeof(T) -1 ] = 3;
78+
79+
int k = arr[6 & 5];
80+
k = arr[2 << index];
81+
k = arr[8 << index]; // expected-note {{used in buffer access here}}
82+
k = arr[16 >> 1];
83+
k = arr[get_const(index)];
84+
k = arr[get_const(5)]; // expected-note {{used in buffer access here}}
85+
k = arr[get_const(4)];
86+
}

0 commit comments

Comments
 (0)