[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