Skip to content

[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

Merged
merged 1 commit into from
Jan 14, 2025

Conversation

malavikasamak
Copy link
Contributor

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)

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:analysis labels Dec 10, 2024
@llvmbot
Copy link
Member

llvmbot commented Dec 10, 2024

@llvm/pr-subscribers-clang-analysis

@llvm/pr-subscribers-clang

Author: Malavika Samak (malavikasamak)

Changes

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)


Full diff: https://github.com/llvm/llvm-project/pull/119340.diff

2 Files Affected:

  • (modified) clang/lib/Analysis/UnsafeBufferUsage.cpp (+3-2)
  • (modified) clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp (+32)
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)];
+}

Copy link
Contributor

@ziqingluo-90 ziqingluo-90 left a 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)
@malavikasamak malavikasamak force-pushed the msamak-fb-sizeof-array branch from f7d4148 to ca068b2 Compare January 13, 2025 16:02
@malavikasamak malavikasamak merged commit 64c2156 into llvm:main Jan 14, 2025
8 checks passed
malavikasamak added a commit to swiftlang/llvm-project that referenced this pull request Jan 14, 2025
…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)
malavikasamak added a commit to swiftlang/llvm-project that referenced this pull request Jan 14, 2025
[Wunsafe-buffer-usage] Fix false positive when const sized array is indexed by const evaluatable expressions (llvm#119340)
@nico
Copy link
Contributor

nico commented Jan 16, 2025

This makes clang assert on many inputs. Here's a repro:

repro.zip

% ./input_file_parsers-161259.sh
...
Assertion failed: (!isValueDependent() && "Expression evaluator can't be called on a dependent expression."), function EvaluateAsInt, file ExprConstant.cpp, line 16671.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.	Program arguments: /Users/thakis/src/llvm-project/out/gn/bin/clang -cc1 -triple x86_64-unknown-linux-gnu -emit-obj --crel -disable-free -clear-ast-before-backend -main-file-name input_file_parsers.cc -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fmerge-all-constants -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -target-feature +sse3 -tune-cpu generic -debug-info-kind=constructor -dwarf-version=4 -debugger-tuning=gdb -ggnu-pubnames -gsimple-template-names=simple -mllvm -generate-arange-section -debug-forward-template-params -fdebug-compilation-dir=. -split-dwarf-file tmp.dwo -split-dwarf-output tmp.dwo -mllvm -crash-diagnostics-dir=../../tools/clang/crashreports -ffunction-sections -fdata-sections -fno-unique-section-names -fcoverage-compilation-dir=. -nostdinc++ -O2 -std=c++20 -fdeprecated-macro -ferror-limit 19 -fvisibility=hidden -fvisibility-inlines-hidden -fwrapv -pthread -stack-protector 1 -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fno-sized-deallocation -Qn -fcolor-diagnostics -vectorize-loops -vectorize-slp -fuse-ctor-homing -mllvm -instcombine-lower-dbg-declare=0 -mllvm -split-threshold-for-reg-with-hint=0 -fcomplete-member-pointers -faddrsig -x c++ input_file_parsers-161259.cpp -Wno-gnu-line-marker -Wunsafe-buffer-usage
1.	<eof> parser at end of file

nico added a commit that referenced this pull request Jan 16, 2025
…ray is indexed by const evaluatable expressions (#119340)"

This reverts commit 64c2156.
Causes asserts, see
#119340 (comment)
@nico
Copy link
Contributor

nico commented Jan 16, 2025

Reverted in 7dd34ba for now.

github-actions bot pushed a commit to arm/arm-toolchain that referenced this pull request Jan 16, 2025
…st sized array is indexed by const evaluatable expressions (#119340)"

This reverts commit 64c2156.
Causes asserts, see
llvm/llvm-project#119340 (comment)
malavikasamak pushed a commit to malavikasamak/llvm-project-safe-buffers that referenced this pull request Jan 21, 2025
…rray is indexed by const evaluatable expressions (llvm#119340)""

This reverts commit 7dd34ba.

Fixed the assertion violation reported by 7dd34ba
malavikasamak added a commit that referenced this pull request Jan 21, 2025
…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]>
@malavikasamak
Copy link
Contributor Author

malavikasamak commented Jan 21, 2025

@nico Thanks for the reproducer. I have relanded this change with the fix for the failing assert. 2a8c12b. Please let me know if there are any more issues.

malavikasamak pushed a commit to swiftlang/llvm-project that referenced this pull request Jan 22, 2025
…ray is indexed by const evaluatable expressions (llvm#119340)"

This reverts commit 64c2156.
Causes asserts, see
llvm#119340 (comment)

(cherry picked from commit 7dd34ba)
malavikasamak added a commit to swiftlang/llvm-project that referenced this pull request Jan 22, 2025
…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)
@nico
Copy link
Contributor

nico commented Jan 22, 2025

If you haven't, it'd be good to also add a minimal regression test for the assert :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:analysis clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants