summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2012-02-27 21:21:40 +0000
committerEli Friedman <eli.friedman@gmail.com>2012-02-27 21:21:40 +0000
commit84e6e5cd1a68c28ff0b118f02738d476ba63d357 (patch)
tree7359574487757c5ea1476d3f56495f2c43d28d5c
parentbb5abc7b494cd7ff48990abb3ab530342c1b40d7 (diff)
downloadbcm5719-llvm-84e6e5cd1a68c28ff0b118f02738d476ba63d357.tar.gz
bcm5719-llvm-84e6e5cd1a68c28ff0b118f02738d476ba63d357.zip
Fix a couple bugs in the way we handle array indexes in array bounds checking. Specifically, make sure we don't ignore explicit casts in indexes, and make sure we use unsigned extension/comparisons on indexes. Fixes <rdar://problem/10916006>.
llvm-svn: 151569
-rw-r--r--clang/lib/Sema/SemaChecking.cpp8
-rw-r--r--clang/test/SemaCXX/array-bounds.cpp6
2 files changed, 10 insertions, 4 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index e96306535a3..3d9f5b3afd2 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -4440,7 +4440,7 @@ static bool IsTailPaddedMemberArray(Sema &S, llvm::APInt Size,
void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
const ArraySubscriptExpr *ASE,
bool AllowOnePastEnd, bool IndexNegated) {
- IndexExpr = IndexExpr->IgnoreParenCasts();
+ IndexExpr = IndexExpr->IgnoreParenImpCasts();
if (IndexExpr->isValueDependent())
return;
@@ -4486,15 +4486,15 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
}
if (size.getBitWidth() > index.getBitWidth())
- index = index.sext(size.getBitWidth());
+ index = index.zext(size.getBitWidth());
else if (size.getBitWidth() < index.getBitWidth())
- size = size.sext(index.getBitWidth());
+ size = size.zext(index.getBitWidth());
// For array subscripting the index must be less than size, but for pointer
// arithmetic also allow the index (offset) to be equal to size since
// computing the next address after the end of the array is legal and
// commonly done e.g. in C++ iterators and range-based for loops.
- if (AllowOnePastEnd ? index.sle(size) : index.slt(size))
+ if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
return;
// Also don't warn for arrays of size 1 which are members of some
diff --git a/clang/test/SemaCXX/array-bounds.cpp b/clang/test/SemaCXX/array-bounds.cpp
index c1b37011727..57a9e3de6a2 100644
--- a/clang/test/SemaCXX/array-bounds.cpp
+++ b/clang/test/SemaCXX/array-bounds.cpp
@@ -247,3 +247,9 @@ void test_pr11007() {
double a[5]; // expected-note {{array 'a' declared here}}
test_pr11007_aux("foo", a[1000]); // expected-warning {{array index 1000 is past the end of the array}}
}
+
+void test_rdar10916006(void)
+{
+ int a[128]; // expected-note {{array 'a' declared here}}
+ a[(unsigned char)'\xA1'] = 1; // expected-warning {{array index 161 is past the end of the array}}
+}
OpenPOWER on IntegriCloud