Skip to content

Commit 656d6e8

Browse files
committed
error on out of bounds vector accesses
1 parent 37559c8 commit 656d6e8

File tree

4 files changed

+49
-0
lines changed

4 files changed

+49
-0
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10635,6 +10635,11 @@ def err_block_on_vm : Error<
1063510635
def err_sizeless_nonlocal : Error<
1063610636
"non-local variable with sizeless type %0">;
1063710637

10638+
def err_vector_index_out_of_range : Error<
10639+
"vector element index %0 is out of bounds">;
10640+
def warn_vector_index_out_of_range : Warning<
10641+
"vector element index %0 is out of bounds">;
10642+
1063810643
def err_vec_builtin_non_vector : Error<
1063910644
"%select{first two|all}1 arguments to %0 must be vectors">;
1064010645
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: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14017,6 +14017,24 @@ void Sema::CheckCastAlign(Expr *Op, QualType T, SourceRange TRange) {
1401714017
<< TRange << Op->getSourceRange();
1401814018
}
1401914019

14020+
void Sema::CheckVectorAccess(const Expr *BaseExpr, const Expr *IndexExpr) {
14021+
const VectorType *VTy = BaseExpr->getType()->getAs<VectorType>();
14022+
if (!VTy)
14023+
return;
14024+
14025+
Expr::EvalResult Result;
14026+
if (!IndexExpr->EvaluateAsInt(Result, Context, Expr::SE_AllowSideEffects))
14027+
return;
14028+
14029+
unsigned DiagID = getLangOpts().HLSL ? diag::err_vector_index_out_of_range
14030+
: diag::warn_vector_index_out_of_range;
14031+
14032+
llvm::APSInt index = Result.Val.getInt();
14033+
if (index.isNegative() || index >= VTy->getNumElements())
14034+
Diag(BaseExpr->getBeginLoc(), DiagID) << toString(index, 10, true);
14035+
return;
14036+
}
14037+
1402014038
void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
1402114039
const ArraySubscriptExpr *ASE,
1402214040
bool AllowOnePastEnd, bool IndexNegated) {
@@ -14031,6 +14049,12 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
1403114049
const Type *EffectiveType =
1403214050
BaseExpr->getType()->getPointeeOrArrayElementType();
1403314051
BaseExpr = BaseExpr->IgnoreParenCasts();
14052+
14053+
if (BaseExpr->getType()->isVectorType()) {
14054+
CheckVectorAccess(BaseExpr, IndexExpr);
14055+
return;
14056+
}
14057+
1403414058
const ConstantArrayType *ArrayTy =
1403514059
Context.getAsConstantArrayType(BaseExpr->getType());
1403614060

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)