-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[Wunsafe-buffer-usage] Fix false positive when const sized array is indexed by const evaluatable expressions #119340
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
Conversation
@llvm/pr-subscribers-clang-analysis @llvm/pr-subscribers-clang Author: Malavika Samak (malavikasamak) ChangesDo 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) Full diff: https://github.com/llvm/llvm-project/pull/119340.diff 2 Files Affected:
diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index 40f529e52b44af..ce973a3f23af38 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -461,8 +461,9 @@ AST_MATCHER(ArraySubscriptExpr, isSafeArraySubscript) {
size = SLiteral->getLength() + 1;
}
- if (const auto *IdxLit = dyn_cast<IntegerLiteral>(Node.getIdx())) {
- const APInt ArrIdx = IdxLit->getValue();
+ Expr::EvalResult EVResult;
+ if (Node.getIdx()->EvaluateAsInt(EVResult, Finder->getASTContext())) {
+ llvm::APSInt ArrIdx = EVResult.Val.getInt();
// FIXME: ArrIdx.isNegative() we could immediately emit an error as that's a
// bug
if (ArrIdx.isNonNegative() && ArrIdx.getLimitedValue() < size)
diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp
index c6c93a27e4b969..ec57b6ace844f0 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp
@@ -52,3 +52,35 @@ void constant_id_string(unsigned idx) {
unsafe_char = ""[1]; //expected-warning{{unsafe buffer access}}
unsafe_char = ""[idx]; //expected-warning{{unsafe buffer access}}
}
+
+struct T {
+ int array[10];
+};
+
+const int index = 1;
+
+constexpr int get_const(int x) {
+ if(x < 3)
+ return ++x;
+ else
+ return x + 5;
+};
+
+void array_indexed_const_expr(unsigned idx) {
+ // expected-note@+2 {{change type of 'arr' to 'std::array' to label it for hardening}}
+ // expected-warning@+1{{'arr' is an unsafe buffer that does not perform bounds checks}}
+ int arr[10];
+ arr[sizeof(int)] = 5;
+
+ int array[sizeof(T)];
+ array[sizeof(int)] = 5;
+ array[sizeof(T) -1 ] = 3;
+
+ int k = arr[6 & 5];
+ k = arr[2 << index];
+ k = arr[8 << index]; // expected-note {{used in buffer access here}}
+ k = arr[16 >> 1];
+ k = arr[get_const(index)];
+ k = arr[get_const(5)]; // expected-note {{used in buffer access here}}
+ k = arr[get_const(4)];
+}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thank you @malavikasamak
…ndexed 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)
f7d4148
to
ca068b2
Compare
…ndexed by const evaluatable expressions (llvm#119340) 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) Co-authored-by: MalavikaSamak <[email protected]> (cherry picked from commit 64c2156)
[Wunsafe-buffer-usage] Fix false positive when const sized array is indexed by const evaluatable expressions (llvm#119340)
This makes clang assert on many inputs. Here's a repro:
|
…ray is indexed by const evaluatable expressions (#119340)" This reverts commit 64c2156. Causes asserts, see #119340 (comment)
Reverted in 7dd34ba for now. |
…st sized array is indexed by const evaluatable expressions (#119340)" This reverts commit 64c2156. Causes asserts, see llvm/llvm-project#119340 (comment)
…rray is indexed by const evaluatable expressions (llvm#119340)"" This reverts commit 7dd34ba. Fixed the assertion violation reported by 7dd34ba
…rray is indexed by const evaluatable expressions (#119340)"" (#123713) This reverts commit 7dd34ba. Fixed the assertion violation reported by 7dd34ba Co-authored-by: MalavikaSamak <[email protected]>
…ray is indexed by const evaluatable expressions (llvm#119340)" This reverts commit 64c2156. Causes asserts, see llvm#119340 (comment) (cherry picked from commit 7dd34ba)
…rray is indexed by const evaluatable expressions (llvm#119340)"" (llvm#123713) This reverts commit 7dd34ba. Fixed the assertion violation reported by 7dd34ba Co-authored-by: MalavikaSamak <[email protected]> (cherry picked from commit 2a8c12b)
If you haven't, it'd be good to also add a minimal regression test for the assert :) |
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)