Skip to content

Commit f1e3675

Browse files
spallllvm-beanzAaronBallman
authored
[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 <[email protected]> Co-authored-by: Aaron Ballman <[email protected]>
1 parent e858b10 commit f1e3675

File tree

6 files changed

+49
-1
lines changed

6 files changed

+49
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,8 @@ Improvements to Clang's diagnostics
235235
under the subgroup ``-Wunsafe-buffer-usage-in-libc-call``.
236236
- Diagnostics on chained comparisons (``a < b < c``) are now an error by default. This can be disabled with
237237
``-Wno-error=parentheses``.
238+
- Adds an error diagnostic for out of bounds vector accesses; produces an error
239+
for compile time statically provable out of bounds vector accesses.
238240
- The ``-Wshift-bool`` warning has been added to warn about shifting a boolean. (#GH28334)
239241
- Fixed diagnostics adding a trailing ``::`` when printing some source code
240242
constructs, like base classes.

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10688,6 +10688,9 @@ def err_block_on_vm : Error<
1068810688
def err_sizeless_nonlocal : Error<
1068910689
"non-local variable with sizeless type %0">;
1069010690

10691+
def err_vector_index_out_of_range : Error<
10692+
"vector element index %0 is out of bounds">;
10693+
1069110694
def err_vec_builtin_non_vector : Error<
1069210695
"%select{first two|all}1 arguments to %0 must be vectors">;
1069310696
def err_vec_builtin_incompatible_vector : Error<

clang/include/clang/Sema/Sema.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2468,6 +2468,7 @@ class Sema final : public SemaBase {
24682468
const ArraySubscriptExpr *ASE = nullptr,
24692469
bool AllowOnePastEnd = true, bool IndexNegated = false);
24702470
void CheckArrayAccess(const Expr *E);
2471+
void CheckVectorAccess(const Expr *BaseExpr, const Expr *IndexExpr);
24712472

24722473
bool CheckPointerCall(NamedDecl *NDecl, CallExpr *TheCall,
24732474
const FunctionProtoType *Proto);

clang/lib/Sema/SemaChecking.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14054,6 +14054,23 @@ void Sema::CheckCastAlign(Expr *Op, QualType T, SourceRange TRange) {
1405414054
<< TRange << Op->getSourceRange();
1405514055
}
1405614056

14057+
void Sema::CheckVectorAccess(const Expr *BaseExpr, const Expr *IndexExpr) {
14058+
const auto *VTy = BaseExpr->getType()->getAs<VectorType>();
14059+
if (!VTy)
14060+
return;
14061+
14062+
Expr::EvalResult Result;
14063+
if (!IndexExpr->EvaluateAsInt(Result, Context, Expr::SE_AllowSideEffects))
14064+
return;
14065+
14066+
unsigned DiagID = diag::err_vector_index_out_of_range;
14067+
14068+
llvm::APSInt index = Result.Val.getInt();
14069+
if (index.isNegative() || index >= VTy->getNumElements())
14070+
Diag(BaseExpr->getBeginLoc(), DiagID) << toString(index, 10, true);
14071+
return;
14072+
}
14073+
1405714074
void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
1405814075
const ArraySubscriptExpr *ASE,
1405914076
bool AllowOnePastEnd, bool IndexNegated) {
@@ -14068,6 +14085,12 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
1406814085
const Type *EffectiveType =
1406914086
BaseExpr->getType()->getPointeeOrArrayElementType();
1407014087
BaseExpr = BaseExpr->IgnoreParenCasts();
14088+
14089+
if (BaseExpr->getType()->isVectorType()) {
14090+
CheckVectorAccess(BaseExpr, IndexExpr);
14091+
return;
14092+
}
14093+
1407114094
const ConstantArrayType *ArrayTy =
1407214095
Context.getAsConstantArrayType(BaseExpr->getType());
1407314096

clang/test/CodeGenCXX/x86_64-arguments.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,6 @@ union U {
215215
float f1;
216216
char __attribute__((__vector_size__(1))) f2;
217217
};
218-
int f(union U u) { return u.f2[1]; }
218+
int f(union U u) { return u.f2[0]; }
219219
// CHECK-LABEL: define{{.*}} i32 @_ZN6test111fENS_1UE(i32
220220
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -verify
2+
3+
export void fn1() {
4+
int2 A = {1,2};
5+
int X = A[-1];
6+
// expected-error@-1 {{vector element index -1 is out of bounds}}
7+
}
8+
9+
export void fn2() {
10+
int4 A = {1,2,3,4};
11+
int X = A[4];
12+
// expected-error@-1 {{vector element index 4 is out of bounds}}
13+
}
14+
15+
export void fn3() {
16+
bool2 A = {true,true};
17+
bool X = A[-1];
18+
// expected-error@-1 {{vector element index -1 is out of bounds}}
19+
}

0 commit comments

Comments
 (0)