[clang] [HLSL] error on out of bounds vector accesses (PR #128952)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Feb 26 16:01:13 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Sarah Spall (spall)
<details>
<summary>Changes</summary>
Add Sema checking and diagnostics to error on out of bounds vector accesses
Warns if language is not HLSL, adds new warning flag -Wvector-out-of-range
Add tests
Closes #<!-- -->91640
---
Full diff: https://github.com/llvm/llvm-project/pull/128952.diff
5 Files Affected:
- (modified) clang/include/clang/Basic/DiagnosticGroups.td (+1)
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+6)
- (modified) clang/include/clang/Sema/Sema.h (+1)
- (modified) clang/lib/Sema/SemaChecking.cpp (+24)
- (added) clang/test/SemaHLSL/Language/VectorOutOfRange-errors.hlsl (+19)
``````````diff
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 51301d95e55b9..7ff37406b459a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10635,6 +10635,12 @@ 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">,
+ InGroup<VectorOutOfRange>, DefaultIgnore;
+
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..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}}
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/128952
More information about the cfe-commits
mailing list