Enhance the array bounds checking to work for several other constructs,
especially C++ code, and generally expand the test coverage.
Logic adapted from a patch by Kaelyn Uhrain <rikka@google.com> and
another Googler.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125775 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index d00f092..6b1013d 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -3095,17 +3095,12 @@
}
void Sema::CheckArrayAccess(const clang::ArraySubscriptExpr *E) {
- const DeclRefExpr *DRE =
- dyn_cast<DeclRefExpr>(E->getBase()->IgnoreParenImpCasts());
- if (!DRE)
- return;
- const VarDecl *Variable = dyn_cast<VarDecl>(DRE->getDecl());
- if (!Variable)
- return;
+ const Expr *BaseExpr = E->getBase()->IgnoreParenImpCasts();
const ConstantArrayType *ArrayTy =
- Context.getAsConstantArrayType(Variable->getType());
+ Context.getAsConstantArrayType(BaseExpr->getType());
if (!ArrayTy)
return;
+
const Expr *IndexExpr = E->getIdx();
if (IndexExpr->isValueDependent())
return;
@@ -3115,6 +3110,8 @@
if (!index.isNegative()) {
const llvm::APInt &size = ArrayTy->getSize();
+ if (!size.isStrictlyPositive())
+ return;
if (size.getBitWidth() > index.getBitWidth())
index = index.sext(size.getBitWidth());
if (index.slt(size))
@@ -3127,7 +3124,14 @@
Diag(E->getBase()->getLocStart(), diag::warn_array_index_precedes_bounds)
<< index.toString(10, true) << IndexExpr->getSourceRange();
}
- Diag(Variable->getLocStart(), diag::note_array_index_out_of_bounds)
- << Variable->getDeclName();
+
+ const NamedDecl *ND = NULL;
+ if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
+ ND = dyn_cast<NamedDecl>(DRE->getDecl());
+ if (const MemberExpr *ME = dyn_cast<MemberExpr>(BaseExpr))
+ ND = dyn_cast<NamedDecl>(ME->getMemberDecl());
+ if (ND)
+ Diag(ND->getLocStart(), diag::note_array_index_out_of_bounds)
+ << ND->getDeclName();
}