aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaChecking.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2011-02-16 01:57:07 +0000
committerTed Kremenek <kremenek@apple.com>2011-02-16 01:57:07 +0000
commita0125d8520f65aca581378c235384e7affefa1fc (patch)
treef414ba8e8fae306c6eae82dc32c20f45fbcd4879 /lib/Sema/SemaChecking.cpp
parenta1fdb0bc09aa0d17841cdbdd8c52cd1368251cbf (diff)
Add trivial buffer overflow checking in Sema.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125640 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaChecking.cpp')
-rw-r--r--lib/Sema/SemaChecking.cpp30
1 files changed, 30 insertions, 0 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 03ce7f3708..ea1f07d783 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -3080,3 +3080,33 @@ void Sema::CheckCastAlign(Expr *Op, QualType T, SourceRange TRange) {
<< TRange << Op->getSourceRange();
}
+void Sema::CheckArrayAccess(const clang::ArraySubscriptExpr *ae) {
+ const DeclRefExpr *dr =
+ dyn_cast<DeclRefExpr>(ae->getBase()->IgnoreParenImpCasts());
+ if (!dr)
+ return;
+ const VarDecl *vd = cast<VarDecl>(dr->getDecl());
+ const ConstantArrayType *cat = Context.getAsConstantArrayType(vd->getType());
+ if (!cat)
+ return;
+ const Expr *idx = ae->getIdx();
+ if (idx->isValueDependent())
+ return;
+ llvm::APSInt result;
+ if (!idx->isIntegerConstantExpr(result, Context))
+ return;
+ unsigned kind = 2;
+ if (result.slt(0))
+ kind = /* precedes */ 0;
+ else {
+ const llvm::APInt &size = cat->getSize();
+ if (size.getBitWidth() > result.getBitWidth())
+ result = result.sext(size.getBitWidth());
+ if (result.sge(size))
+ kind = /* excedes */ 1;
+ }
+ if (kind < 2)
+ Diag(ae->getBase()->getLocEnd(), diag::warn_array_index_out_of_bounds)
+ << kind << idx->getSourceRange();
+}
+