@@ -875,6 +875,44 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
875875 }
876876}
877877
878+ // / Determine whether this expression refers to a flexible array member in a
879+ // / struct. We disable array bounds checks for such members.
880+ static bool isFlexibleArrayMemberExpr (const Expr *E) {
881+ // For compatibility with existing code, we treat arrays of length 0 or
882+ // 1 as flexible array members.
883+ // FIXME: This is inconsistent with the warning code in SemaChecking. Unify
884+ // the two mechanisms.
885+ const ArrayType *AT = E->getType ()->castAsArrayTypeUnsafe ();
886+ if (const auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
887+ // FIXME: Sema doesn't treat [1] as a flexible array member if the bound
888+ // was produced by macro expansion.
889+ if (CAT->getSize ().ugt (1 ))
890+ return false ;
891+ } else if (!isa<IncompleteArrayType>(AT))
892+ return false ;
893+
894+ E = E->IgnoreParens ();
895+
896+ // A flexible array member must be the last member in the class.
897+ if (const auto *ME = dyn_cast<MemberExpr>(E)) {
898+ // FIXME: If the base type of the member expr is not FD->getParent(),
899+ // this should not be treated as a flexible array member access.
900+ if (const auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl ())) {
901+ // FIXME: Sema doesn't treat a T[1] union member as a flexible array
902+ // member, only a T[0] or T[] member gets that treatment.
903+ if (FD->getParent ()->isUnion ())
904+ return true ;
905+ RecordDecl::field_iterator FI (
906+ DeclContext::decl_iterator (const_cast <FieldDecl *>(FD)));
907+ return ++FI == FD->getParent ()->field_end ();
908+ }
909+ } else if (const auto *IRE = dyn_cast<ObjCIvarRefExpr>(E)) {
910+ return IRE->getDecl ()->getNextIvar () == nullptr ;
911+ }
912+
913+ return false ;
914+ }
915+
878916llvm::Value *CodeGenFunction::LoadPassedObjectSize (const Expr *E,
879917 QualType EltTy) {
880918 ASTContext &C = getContext ();
@@ -916,11 +954,8 @@ llvm::Value *CodeGenFunction::LoadPassedObjectSize(const Expr *E,
916954
917955// / If Base is known to point to the start of an array, return the length of
918956// / that array. Return 0 if the length cannot be determined.
919- static llvm::Value *getArrayIndexingBound (CodeGenFunction &CGF,
920- const Expr *Base,
921- QualType &IndexedType,
922- ASTContext &Context,
923- int StrictFlexArraysLevel) {
957+ static llvm::Value *getArrayIndexingBound (
958+ CodeGenFunction &CGF, const Expr *Base, QualType &IndexedType) {
924959 // For the vector indexing extension, the bound is the number of elements.
925960 if (const VectorType *VT = Base->getType ()->getAs <VectorType>()) {
926961 IndexedType = Base->getType ();
@@ -931,8 +966,7 @@ static llvm::Value *getArrayIndexingBound(CodeGenFunction &CGF,
931966
932967 if (const auto *CE = dyn_cast<CastExpr>(Base)) {
933968 if (CE->getCastKind () == CK_ArrayToPointerDecay &&
934- !CE->getSubExpr ()->IgnoreParens ()->isFlexibleArrayMember (
935- Context, std::max (StrictFlexArraysLevel, 1 ))) {
969+ !isFlexibleArrayMemberExpr (CE->getSubExpr ())) {
936970 IndexedType = CE->getSubExpr ()->getType ();
937971 const ArrayType *AT = IndexedType->castAsArrayTypeUnsafe ();
938972 if (const auto *CAT = dyn_cast<ConstantArrayType>(AT))
@@ -960,8 +994,7 @@ void CodeGenFunction::EmitBoundsCheck(const Expr *E, const Expr *Base,
960994 SanitizerScope SanScope (this );
961995
962996 QualType IndexedType;
963- llvm::Value *Bound = getArrayIndexingBound (
964- *this , Base, IndexedType, getContext (), getLangOpts ().StrictFlexArrays );
997+ llvm::Value *Bound = getArrayIndexingBound (*this , Base, IndexedType);
965998 if (!Bound)
966999 return ;
9671000
0 commit comments