aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Sema/SemaChecking.cpp24
-rw-r--r--lib/Sema/SemaExprCXX.cpp4
2 files changed, 18 insertions, 10 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index d00f092274..6b1013d82d 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -3095,17 +3095,12 @@ void Sema::CheckCastAlign(Expr *Op, QualType T, SourceRange TRange) {
}
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 @@ void Sema::CheckArrayAccess(const clang::ArraySubscriptExpr *E) {
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 @@ void Sema::CheckArrayAccess(const clang::ArraySubscriptExpr *E) {
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();
}
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 6fa22a9776..44508540d0 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -2005,6 +2005,10 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
if (!From->isGLValue()) break;
}
+ // Check for trivial buffer overflows.
+ if (const ArraySubscriptExpr *AE = dyn_cast<ArraySubscriptExpr>(From))
+ CheckArrayAccess(AE);
+
FromType = FromType.getUnqualifiedType();
From = ImplicitCastExpr::Create(Context, FromType, CK_LValueToRValue,
From, 0, VK_RValue);