]> granicus.if.org Git - clang/commitdiff
[Sema] Don't try to account for the size of an incomplete type in CheckArrayAccess
authorBruno Ricci <riccibrun@gmail.com>
Thu, 20 Dec 2018 20:05:11 +0000 (20:05 +0000)
committerBruno Ricci <riccibrun@gmail.com>
Thu, 20 Dec 2018 20:05:11 +0000 (20:05 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349811 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaChecking.cpp
test/SemaCXX/array-bounds.cpp

index b06f793b17a57d89132ec5b12eea265dc6ed8c1b..9fe65c1dce4245ef9fc87aeff0ebef722dc70288 100644 (file)
@@ -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);
index a97f8e312a05d2908ef3dd50099b02b01e16adf7..3eb929b93ed498e923087302b2ec5066894fb1c2 100644 (file)
@@ -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
+}