[clang] [Wunsafe-buffer-usage] Fix false positives in handling enums (PR #117370)

via cfe-commits cfe-commits at lists.llvm.org
Fri Nov 22 12:11:28 PST 2024


https://github.com/mxms0 created https://github.com/llvm/llvm-project/pull/117370

Do not warn if the index is an enum and we an determine statically that it's within bounds.

>From 8fed333cf4221dbf1826351da80164db5d209c21 Mon Sep 17 00:00:00 2001
From: mxms <mxms at google.com>
Date: Fri, 22 Nov 2024 15:09:07 -0500
Subject: [PATCH] [Wunsafe-buffer-usage] Fix false positives in handling enums

Do not warn if the index is an enum and we an determine statically that
it's within bounds.
---
 clang/lib/Analysis/UnsafeBufferUsage.cpp        |  7 +++++++
 .../SemaCXX/warn-unsafe-buffer-usage-array.cpp  | 17 +++++++++++++++++
 2 files changed, 24 insertions(+)

diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index 5f36ffa926b269..addb724e2e2c9a 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -463,6 +463,13 @@ AST_MATCHER(ArraySubscriptExpr, isSafeArraySubscript) {
       return true;
   }
 
+  // Array index wasn't an integer literal, let's see if it was an enum or
+  // something similar
+  const auto IntConst = Node.getIdx()->getIntegerConstantExpr(Finder->getASTContext());
+  if (IntConst && *IntConst > 0 && *IntConst < size) {
+    return true;
+  }
+
   return false;
 }
 
diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp
index c6c93a27e4b969..a65ecdf39edfcc 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp
@@ -39,6 +39,23 @@ void constant_idx_unsafe(unsigned idx) {
   buffer[10] = 0;       // expected-note{{used in buffer access here}}
 }
 
+enum FooEnum {
+  A = 0,
+  B = 1,
+  C = 2,
+  D
+};
+
+void constant_enum_safe() {
+  int buffer[FooEnum::D] = { 0, 1, 2 };
+  buffer[C] = 0; // no-warning
+}
+
+void constant_enum_unsafe(FooEnum e) {
+  int buffer[FooEnum::D] = { 0, 1, 2 };
+  buffer[e] = 0; // expected-warning{{unsafe buffer access}}
+}
+
 void constant_id_string(unsigned idx) {
   char safe_char = "abc"[1]; // no-warning
   safe_char = ""[0];



More information about the cfe-commits mailing list