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@-1 {{vector element index -1 is out of bounds}} +} + +export void fn2() { + int4 A = {1,2,3,4}; + int X = A[4]; + // expected-error@-1 {{vector element index 4 is out of bounds}} +} + +export void fn3() { + bool2 A = {true,true}; + bool X = A[-1]; + // expected-error@-1 {{vector element index -1 is out of bounds}} +} `````````` </details> https://github.com/llvm/llvm-project/pull/128952 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits