[clang] [HLSL] error on out of bounds vector accesses (PR #128952)
Sarah Spall via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 10 09:55:25 PDT 2025
https://github.com/spall updated https://github.com/llvm/llvm-project/pull/128952
>From 656d6e87466bfc85246f7abaedfe6549e566717b Mon Sep 17 00:00:00 2001
From: Sarah Spall <sarahspall at microsoft.com>
Date: Wed, 26 Feb 2025 14:37:06 -0800
Subject: [PATCH 1/7] error on out of bounds vector accesses
---
.../clang/Basic/DiagnosticSemaKinds.td | 5 ++++
clang/include/clang/Sema/Sema.h | 1 +
clang/lib/Sema/SemaChecking.cpp | 24 +++++++++++++++++++
.../Language/VectorOutOfRange-errors.hlsl | 19 +++++++++++++++
4 files changed, 49 insertions(+)
create mode 100644 clang/test/SemaHLSL/Language/VectorOutOfRange-errors.hlsl
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 51301d95e55b9..0989b4c05b86f 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10635,6 +10635,11 @@ 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 warn_vector_index_out_of_range : Warning<
+ "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 476abe86cb2d2..fad3cbddc555b 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 f9926c6b4adab..1cbf428f18366 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -14017,6 +14017,24 @@ void Sema::CheckCastAlign(Expr *Op, QualType T, SourceRange TRange) {
<< TRange << Op->getSourceRange();
}
+void Sema::CheckVectorAccess(const Expr *BaseExpr, const Expr *IndexExpr) {
+ const VectorType *VTy = BaseExpr->getType()->getAs<VectorType>();
+ if (!VTy)
+ return;
+
+ Expr::EvalResult Result;
+ if (!IndexExpr->EvaluateAsInt(Result, Context, Expr::SE_AllowSideEffects))
+ return;
+
+ unsigned DiagID = getLangOpts().HLSL ? diag::err_vector_index_out_of_range
+ : diag::warn_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) {
@@ -14031,6 +14049,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/SemaHLSL/Language/VectorOutOfRange-errors.hlsl b/clang/test/SemaHLSL/Language/VectorOutOfRange-errors.hlsl
new file mode 100644
index 0000000000000..02b5693f4076c
--- /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}}
+}
>From f44e697beb1dfa6a028a8015f3d9587968f3600c Mon Sep 17 00:00:00 2001
From: Sarah Spall <sarahspall at microsoft.com>
Date: Wed, 26 Feb 2025 15:58:44 -0800
Subject: [PATCH 2/7] add warning flag for vector out of bounds warning. fix
test
---
clang/include/clang/Basic/DiagnosticGroups.td | 1 +
clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 ++-
clang/test/SemaHLSL/Language/VectorOutOfRange-errors.hlsl | 6 +++---
3 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 05e39899e6f25..d36f6086edd40 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -930,6 +930,7 @@ def SuperSubClassMismatch : DiagGroup<"super-class-method-mismatch">;
def OverridingMethodMismatch : DiagGroup<"overriding-method-mismatch">;
def VariadicMacros : DiagGroup<"variadic-macros">;
def VectorConversion : DiagGroup<"vector-conversion">; // clang specific
+def VectorOutOfRange : DiagGroup<"vector-out-of-range">;
def VexingParse : DiagGroup<"vexing-parse">;
def VLAUseStaticAssert : DiagGroup<"vla-extension-static-assert">;
def VLACxxExtension : DiagGroup<"vla-cxx-extension", [VLAUseStaticAssert]>;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 0989b4c05b86f..7ff37406b459a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10638,7 +10638,8 @@ def err_sizeless_nonlocal : Error<
def err_vector_index_out_of_range : Error<
"vector element index %0 is out of bounds">;
def warn_vector_index_out_of_range : Warning<
- "vector element index %0 is out of bounds">;
+ "vector element index %0 is out of bounds">,
+ InGroup<VectorOutOfRange>, DefaultIgnore;
def err_vec_builtin_non_vector : Error<
"%select{first two|all}1 arguments to %0 must be vectors">;
diff --git a/clang/test/SemaHLSL/Language/VectorOutOfRange-errors.hlsl b/clang/test/SemaHLSL/Language/VectorOutOfRange-errors.hlsl
index 02b5693f4076c..b4d423fb24bd2 100644
--- a/clang/test/SemaHLSL/Language/VectorOutOfRange-errors.hlsl
+++ b/clang/test/SemaHLSL/Language/VectorOutOfRange-errors.hlsl
@@ -3,17 +3,17 @@
export void fn1() {
int2 A = {1,2};
int X = A[-1];
- // expected-error at -1 {{vector element index '-1' is out of bounds}}
+ // 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}}
+ // 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}}
+ // expected-error at -1 {{vector element index -1 is out of bounds}}
}
>From 8449ac1ed8f53c0cc744d89d6948b1e2deefae32 Mon Sep 17 00:00:00 2001
From: Sarah Spall <spall at planetbauer.com>
Date: Thu, 27 Feb 2025 07:36:48 -0800
Subject: [PATCH 3/7] Update clang/include/clang/Basic/DiagnosticSemaKinds.td
Co-authored-by: Chris B <beanz at abolishcrlf.org>
---
clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 7ff37406b459a..383aafc283603 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10638,7 +10638,7 @@ def err_sizeless_nonlocal : Error<
def err_vector_index_out_of_range : Error<
"vector element index %0 is out of bounds">;
def warn_vector_index_out_of_range : Warning<
- "vector element index %0 is out of bounds">,
+ err_vector_index_out_of_range.Summary>,
InGroup<VectorOutOfRange>, DefaultIgnore;
def err_vec_builtin_non_vector : Error<
>From 14f60af4389828b34a2dab948bf8ad9033180d25 Mon Sep 17 00:00:00 2001
From: Sarah Spall <sarahspall at microsoft.com>
Date: Thu, 27 Feb 2025 15:05:08 -0800
Subject: [PATCH 4/7] make new warning not ignored by default
---
clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 383aafc283603..2f19a3707cb5c 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10639,7 +10639,7 @@ def err_vector_index_out_of_range : Error<
"vector element index %0 is out of bounds">;
def warn_vector_index_out_of_range : Warning<
err_vector_index_out_of_range.Summary>,
- InGroup<VectorOutOfRange>, DefaultIgnore;
+ InGroup<VectorOutOfRange>;
def err_vec_builtin_non_vector : Error<
"%select{first two|all}1 arguments to %0 must be vectors">;
>From 8488243974be5c7575651dae818c69c116535a62 Mon Sep 17 00:00:00 2001
From: Sarah Spall <spall at planetbauer.com>
Date: Tue, 4 Mar 2025 14:19:24 -0800
Subject: [PATCH 5/7] Update clang/lib/Sema/SemaChecking.cpp
Co-authored-by: Aaron Ballman <aaron at aaronballman.com>
---
clang/lib/Sema/SemaChecking.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 1cbf428f18366..867457c35e8ea 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -14018,7 +14018,7 @@ void Sema::CheckCastAlign(Expr *Op, QualType T, SourceRange TRange) {
}
void Sema::CheckVectorAccess(const Expr *BaseExpr, const Expr *IndexExpr) {
- const VectorType *VTy = BaseExpr->getType()->getAs<VectorType>();
+ const auto *VTy = BaseExpr->getType()->getAs<VectorType>();
if (!VTy)
return;
>From 2fa2c7234d14eb4261c687335554769d56cd40c6 Mon Sep 17 00:00:00 2001
From: Sarah Spall <sarahspall at microsoft.com>
Date: Mon, 10 Mar 2025 07:49:09 -0700
Subject: [PATCH 6/7] remove warning and always error
---
clang/include/clang/Basic/DiagnosticGroups.td | 1 -
clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 ---
clang/lib/Sema/SemaChecking.cpp | 3 +--
clang/test/CodeGenCXX/x86_64-arguments.cpp | 2 +-
4 files changed, 2 insertions(+), 7 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index d36f6086edd40..05e39899e6f25 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -930,7 +930,6 @@ def SuperSubClassMismatch : DiagGroup<"super-class-method-mismatch">;
def OverridingMethodMismatch : DiagGroup<"overriding-method-mismatch">;
def VariadicMacros : DiagGroup<"variadic-macros">;
def VectorConversion : DiagGroup<"vector-conversion">; // clang specific
-def VectorOutOfRange : DiagGroup<"vector-out-of-range">;
def VexingParse : DiagGroup<"vexing-parse">;
def VLAUseStaticAssert : DiagGroup<"vla-extension-static-assert">;
def VLACxxExtension : DiagGroup<"vla-cxx-extension", [VLAUseStaticAssert]>;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 2f19a3707cb5c..762b5eb475471 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10637,9 +10637,6 @@ def err_sizeless_nonlocal : Error<
def err_vector_index_out_of_range : Error<
"vector element index %0 is out of bounds">;
-def warn_vector_index_out_of_range : Warning<
- err_vector_index_out_of_range.Summary>,
- InGroup<VectorOutOfRange>;
def err_vec_builtin_non_vector : Error<
"%select{first two|all}1 arguments to %0 must be vectors">;
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 867457c35e8ea..66b7fe2a6d803 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -14026,8 +14026,7 @@ void Sema::CheckVectorAccess(const Expr *BaseExpr, const Expr *IndexExpr) {
if (!IndexExpr->EvaluateAsInt(Result, Context, Expr::SE_AllowSideEffects))
return;
- unsigned DiagID = getLangOpts().HLSL ? diag::err_vector_index_out_of_range
- : diag::warn_vector_index_out_of_range;
+ unsigned DiagID = diag::err_vector_index_out_of_range;
llvm::APSInt index = Result.Val.getInt();
if (index.isNegative() || index >= VTy->getNumElements())
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
}
>From 7ef3654c3d7cda8ce3ab3ce2eb5bb5b5d3cc58aa Mon Sep 17 00:00:00 2001
From: Sarah Spall <sarahspall at microsoft.com>
Date: Mon, 10 Mar 2025 07:57:05 -0700
Subject: [PATCH 7/7] release note
---
clang/docs/ReleaseNotes.rst | 2 ++
1 file changed, 2 insertions(+)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 657340c170503..53b4d3c2ef322 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -193,6 +193,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 a diagnostic for out of bounds vector accesses; Errors by default for compile time statically
+ provable out of bounds vector accesses.
Improvements to Clang's time-trace
----------------------------------
More information about the cfe-commits
mailing list