[clang] f1e3675 - [HLSL] error on out of bounds vector accesses (#128952)

via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 11 07:12:21 PDT 2025


Author: Sarah Spall
Date: 2025-03-11T07:12:18-07:00
New Revision: f1e36759d2e6c26d2d5825f955c51fd595909b52

URL: https://github.com/llvm/llvm-project/commit/f1e36759d2e6c26d2d5825f955c51fd595909b52
DIFF: https://github.com/llvm/llvm-project/commit/f1e36759d2e6c26d2d5825f955c51fd595909b52.diff

LOG: [HLSL] error on out of bounds vector accesses (#128952)

Add Sema checking and diagnostics to error on out of bounds vector
accesses
Add tests
Closes #91640

---------

Co-authored-by: Chris B <beanz at abolishcrlf.org>
Co-authored-by: Aaron Ballman <aaron at aaronballman.com>

Added: 
    clang/test/SemaHLSL/Language/VectorOutOfRange-errors.hlsl

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/include/clang/Sema/Sema.h
    clang/lib/Sema/SemaChecking.cpp
    clang/test/CodeGenCXX/x86_64-arguments.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 145c5972a2043..004f78f22ac36 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -235,6 +235,8 @@ Improvements to Clang's diagnostics
   under the subgroup ``-Wunsafe-buffer-usage-in-libc-call``.
 - Diagnostics on chained comparisons (``a < b < c``) are now an error by default. This can be disabled with
   ``-Wno-error=parentheses``.
+- Adds an error diagnostic for out of bounds vector accesses; produces an error
+  for compile time statically provable out of bounds vector accesses.
 - The ``-Wshift-bool`` warning has been added to warn about shifting a boolean. (#GH28334)
 - Fixed diagnostics adding a trailing ``::`` when printing some source code
   constructs, like base classes.

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8e6e6e892cdd7..4bdbb797c2b86 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10688,6 +10688,9 @@ def err_block_on_vm : Error<
 def err_sizeless_nonlocal : Error<
   "non-local variable with sizeless type %0">;
 
+def err_vector_index_out_of_range : Error<
+  "vector element index %0 is out of bounds">;
+
 def err_vec_builtin_non_vector : Error<
  "%select{first two|all}1 arguments to %0 must be vectors">;
 def err_vec_builtin_incompatible_vector : Error<

diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 9ac26d8728446..c034de0e633da 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -2468,6 +2468,7 @@ class Sema final : public SemaBase {
                         const ArraySubscriptExpr *ASE = nullptr,
                         bool AllowOnePastEnd = true, bool IndexNegated = false);
   void CheckArrayAccess(const Expr *E);
+  void CheckVectorAccess(const Expr *BaseExpr, const Expr *IndexExpr);
 
   bool CheckPointerCall(NamedDecl *NDecl, CallExpr *TheCall,
                         const FunctionProtoType *Proto);

diff  --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index a6cdbbafec666..89932b5d61dc8 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -14054,6 +14054,23 @@ void Sema::CheckCastAlign(Expr *Op, QualType T, SourceRange TRange) {
     << TRange << Op->getSourceRange();
 }
 
+void Sema::CheckVectorAccess(const Expr *BaseExpr, const Expr *IndexExpr) {
+  const auto *VTy = BaseExpr->getType()->getAs<VectorType>();
+  if (!VTy)
+    return;
+
+  Expr::EvalResult Result;
+  if (!IndexExpr->EvaluateAsInt(Result, Context, Expr::SE_AllowSideEffects))
+    return;
+
+  unsigned DiagID = diag::err_vector_index_out_of_range;
+
+  llvm::APSInt index = Result.Val.getInt();
+  if (index.isNegative() || index >= VTy->getNumElements())
+    Diag(BaseExpr->getBeginLoc(), DiagID) << toString(index, 10, true);
+  return;
+}
+
 void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
                             const ArraySubscriptExpr *ASE,
                             bool AllowOnePastEnd, bool IndexNegated) {
@@ -14068,6 +14085,12 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
   const Type *EffectiveType =
       BaseExpr->getType()->getPointeeOrArrayElementType();
   BaseExpr = BaseExpr->IgnoreParenCasts();
+
+  if (BaseExpr->getType()->isVectorType()) {
+    CheckVectorAccess(BaseExpr, IndexExpr);
+    return;
+  }
+
   const ConstantArrayType *ArrayTy =
       Context.getAsConstantArrayType(BaseExpr->getType());
 

diff  --git a/clang/test/CodeGenCXX/x86_64-arguments.cpp b/clang/test/CodeGenCXX/x86_64-arguments.cpp
index ebeba7fd65495..6915e5d6761dd 100644
--- a/clang/test/CodeGenCXX/x86_64-arguments.cpp
+++ b/clang/test/CodeGenCXX/x86_64-arguments.cpp
@@ -215,6 +215,6 @@ union U {
   float f1;
   char __attribute__((__vector_size__(1))) f2;
 };
-int f(union U u) { return u.f2[1]; }
+int f(union U u) { return u.f2[0]; }
 // CHECK-LABEL: define{{.*}} i32 @_ZN6test111fENS_1UE(i32
 }

diff  --git a/clang/test/SemaHLSL/Language/VectorOutOfRange-errors.hlsl b/clang/test/SemaHLSL/Language/VectorOutOfRange-errors.hlsl
new file mode 100644
index 0000000000000..b4d423fb24bd2
--- /dev/null
+++ b/clang/test/SemaHLSL/Language/VectorOutOfRange-errors.hlsl
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -verify
+
+export void fn1() {
+  int2 A = {1,2};
+  int X = A[-1];
+  // expected-error at -1 {{vector element index -1 is out of bounds}}
+}
+
+export void fn2() {
+  int4 A = {1,2,3,4};
+  int X = A[4];
+  // expected-error at -1 {{vector element index 4 is out of bounds}}
+}
+
+export void fn3() {
+  bool2 A = {true,true};
+  bool X = A[-1];
+  // expected-error at -1 {{vector element index -1 is out of bounds}}
+}


        


More information about the cfe-commits mailing list