[clang] [clang][Sema] Add diagnostics for out-of-bounds vector access (PR #76569)

via cfe-commits cfe-commits at lists.llvm.org
Fri Dec 29 07:30:42 PST 2023


https://github.com/implicitfield created https://github.com/llvm/llvm-project/pull/76569

Fixes #76490

>From 5b95122ede9373bb031061ead75140b9f27bad29 Mon Sep 17 00:00:00 2001
From: implicitfield <114500360+implicitfield at users.noreply.github.com>
Date: Fri, 29 Dec 2023 01:52:49 +0400
Subject: [PATCH] [clang][Sema] Add diagnostics for out-of-bounds vector access

Fixes #76490
---
 .../clang/Basic/DiagnosticSemaKinds.td        |  8 ++++
 clang/lib/Sema/SemaChecking.cpp               | 39 +++++++++++++++++++
 clang/test/Sema/array-bounds-vector.c         | 10 +++++
 3 files changed, 57 insertions(+)
 create mode 100644 clang/test/Sema/array-bounds-vector.c

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index aebb7d9b945c33..4ab03f0d9518fd 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9689,6 +9689,12 @@ def warn_array_index_precedes_bounds : Warning<
 def warn_array_index_exceeds_bounds : Warning<
   "array index %0 is past the end of the array (that has type %1%select{|, cast to %3}2)">,
   InGroup<ArrayBounds>;
+def warn_vector_index_precedes_bounds : Warning<
+  "vector index %0 is before the beginning of the vector">,
+  InGroup<ArrayBounds>;
+def warn_vector_index_exceeds_bounds : Warning<
+  "vector index %0 is past the end of the vector (that has type %1)">,
+  InGroup<ArrayBounds>;
 def warn_ptr_arith_exceeds_max_addressable_bounds : Warning<
   "the pointer incremented by %0 refers past the last possible element for an array in %1-bit "
   "address space containing %2-bit (%3-byte) elements (max possible %4 element%s5)">,
@@ -9699,6 +9705,8 @@ def warn_array_index_exceeds_max_addressable_bounds : Warning<
   InGroup<ArrayBounds>;
 def note_array_declared_here : Note<
   "array %0 declared here">;
+def note_vector_declared_here : Note<
+  "vector %0 declared here">;
 
 def warn_inconsistent_array_form : Warning<
   "argument %0 of type %1 with mismatched bound">,
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index da0570b7b0f1e6..3a52b84e331b85 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -17914,6 +17914,45 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
     index = -index;
   }
 
+  if (EffectiveType->isVectorType()) {
+    if (AllowOnePastEnd) {
+      // Pointer arithmetic on vectors isn't legal, so let's not emit a
+      // diagnostic since we'll produce an error later anyway.
+      return;
+    }
+
+    if (index.isUnsigned() || !index.isNegative()) {
+      const auto *VT = EffectiveType->castAs<VectorType>();
+      if (index.ult(VT->getNumElements()))
+        return;
+
+      DiagRuntimeBehavior(BaseExpr->getBeginLoc(), BaseExpr,
+                          PDiag(diag::warn_vector_index_exceeds_bounds)
+                              << toString(index, 10, true) << VT->desugar()
+                              << IndexExpr->getSourceRange());
+    } else {
+      DiagRuntimeBehavior(BaseExpr->getBeginLoc(), BaseExpr,
+                          PDiag(diag::warn_vector_index_precedes_bounds)
+                              << toString(index, 10, true)
+                              << IndexExpr->getSourceRange());
+    }
+
+    const NamedDecl *ND = nullptr;
+    // Try harder to find a NamedDecl to point at in the note.
+    while (const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
+      BaseExpr = ASE->getBase()->IgnoreParenCasts();
+    if (const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
+      ND = DRE->getDecl();
+    if (const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
+      ND = ME->getMemberDecl();
+
+    if (ND)
+      DiagRuntimeBehavior(ND->getBeginLoc(), BaseExpr,
+                          PDiag(diag::note_vector_declared_here) << ND);
+
+    return;
+  }
+
   if (IsUnboundedArray) {
     if (EffectiveType->isFunctionType())
       return;
diff --git a/clang/test/Sema/array-bounds-vector.c b/clang/test/Sema/array-bounds-vector.c
new file mode 100644
index 00000000000000..e5a940a7d17864
--- /dev/null
+++ b/clang/test/Sema/array-bounds-vector.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -Warray-bounds -verify %s
+
+typedef double float64x1_t __attribute__ ((__vector_size__ (sizeof (double))));
+void foo(double i)
+{
+    float64x1_t j = {i}; // expected-note 2 {{vector 'j' declared here}}
+    double U = j[0];
+    double V = j[1]; // expected-warning {{vector index 1 is past the end of the vector (that has type '__attribute__((__vector_size__(1 * sizeof(double)))) double' (vector of 1 'double' value))}}
+    double W = j[-1]; // expected-warning {{vector index -1 is before the beginning of the vector}}
+}



More information about the cfe-commits mailing list