summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBruno Ricci <riccibrun@gmail.com>2018-12-20 20:05:11 +0000
committerBruno Ricci <riccibrun@gmail.com>2018-12-20 20:05:11 +0000
commited414847bc80916af4361ad703ab542fe2d2577b (patch)
tree0d8a0f350609336c353ec1cd51810eaa51f649cb
parent02e96dd039309dd99a26248ff0934f336d6a188e (diff)
downloadbcm5719-llvm-ed414847bc80916af4361ad703ab542fe2d2577b.tar.gz
bcm5719-llvm-ed414847bc80916af4361ad703ab542fe2d2577b.zip
[Sema] Don't try to account for the size of an incomplete type in CheckArrayAccess
When checking that the array access is not out-of-bounds in CheckArrayAccess it is possible that the type of the base expression after IgnoreParenCasts is incomplete, even though the type of the base expression before IgnoreParenCasts is complete. In this case we have no information about whether the array access is out-of-bounds and we should just bail-out instead. This fixes PR39746 which was caused by trying to obtain the size of an incomplete type. Differential Revision: https://reviews.llvm.org/D55862 Reviewed By: efriedma llvm-svn: 349811
-rw-r--r--clang/lib/Sema/SemaChecking.cpp12
-rw-r--r--clang/test/SemaCXX/array-bounds.cpp9
2 files changed, 19 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index b06f793b17a..9fe65c1dce4 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -12379,10 +12379,19 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
BaseExpr->getType()->getPointeeOrArrayElementType();
BaseExpr = BaseExpr->IgnoreParenCasts();
const ConstantArrayType *ArrayTy =
- Context.getAsConstantArrayType(BaseExpr->getType());
+ Context.getAsConstantArrayType(BaseExpr->getType());
+
if (!ArrayTy)
return;
+ const Type *BaseType = ArrayTy->getElementType().getTypePtr();
+ // It is possible that the type of the base expression after IgnoreParenCasts
+ // is incomplete, even though the type of the base expression before
+ // IgnoreParenCasts is complete (see PR39746 for an example). In this case we
+ // have no information about whether the array access is out-of-bounds.
+ if (BaseType->isIncompleteType())
+ return;
+
Expr::EvalResult Result;
if (!IndexExpr->EvaluateAsInt(Result, Context, Expr::SE_AllowSideEffects))
return;
@@ -12402,7 +12411,6 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
if (!size.isStrictlyPositive())
return;
- const Type *BaseType = BaseExpr->getType()->getPointeeOrArrayElementType();
if (BaseType != EffectiveType) {
// Make sure we're comparing apples to apples when comparing index to size
uint64_t ptrarith_typesize = Context.getTypeSize(EffectiveType);
diff --git a/clang/test/SemaCXX/array-bounds.cpp b/clang/test/SemaCXX/array-bounds.cpp
index a97f8e312a0..3eb929b93ed 100644
--- a/clang/test/SemaCXX/array-bounds.cpp
+++ b/clang/test/SemaCXX/array-bounds.cpp
@@ -284,3 +284,12 @@ struct multi_s multi2[4]; // expected-note {{array 'multi2' declared here}}
int test_struct_multiarray() {
return multi2[4].arr[0]; // expected-warning {{array index 4 is past the end of the array (which contains 4 elements)}}
}
+
+namespace PR39746 {
+ struct S;
+ extern S xxx[2];
+ class C {};
+
+ C &f() { return reinterpret_cast<C *>(xxx)[1]; } // no-warning
+ C &g() { return reinterpret_cast<C *>(xxx)[2]; } // no-warning
+}
OpenPOWER on IntegriCloud