From 3ff5c86d409a55d0e64a28c07197ee3e791166c2 Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Sun, 16 Oct 2011 18:19:20 +0000 Subject: [PATCH] In the verify-only pass, check that items that don't have an initializer in an init list can be value-initialized, at least when designated initializers are not involved. No test case yet, since early failures cannot be distinguished from late failures until overload resolution works. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142146 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaInit.cpp | 79 +++++++++++++++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 17 deletions(-) diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 7ed3fa84c8..cef4870638 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -256,6 +256,8 @@ class InitListChecker { bool CheckFlexibleArrayInit(const InitializedEntity &Entity, Expr *InitExpr, FieldDecl *Field, bool TopLevelObject); + void CheckValueInitializable(const InitializedEntity &Entity); + public: InitListChecker(Sema &S, const InitializedEntity &Entity, InitListExpr *IL, QualType &T, bool VerifyOnly); @@ -267,6 +269,18 @@ public: }; } // end anonymous namespace +void InitListChecker::CheckValueInitializable(const InitializedEntity &Entity) { + assert(VerifyOnly && + "CheckValueInitializable is only inteded for verification mode."); + + SourceLocation Loc; + InitializationKind Kind = InitializationKind::CreateValue(Loc, Loc, Loc, + true); + InitializationSequence InitSeq(SemaRef, Entity, Kind, 0, 0); + if (InitSeq.Failed()) + hadError = true; +} + void InitListChecker::FillInValueInitForField(unsigned Init, FieldDecl *Field, const InitializedEntity &ParentEntity, InitListExpr *ILE, @@ -1005,14 +1019,19 @@ void InitListChecker::CheckVectorType(const InitializedEntity &Entity, unsigned &Index, InitListExpr *StructuredList, unsigned &StructuredIndex) { - if (Index >= IList->getNumInits()) - return; - const VectorType *VT = DeclType->getAs(); unsigned maxElements = VT->getNumElements(); unsigned numEltsInit = 0; QualType elementType = VT->getElementType(); + if (Index >= IList->getNumInits()) { + // Make sure the element type can be value-initialized. + if (VerifyOnly) + CheckValueInitializable( + InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity)); + return; + } + if (!SemaRef.getLangOptions().OpenCL) { // If the initializing element is a vector, try to copy-initialize // instead of breaking it apart (which is doomed to failure anyway). @@ -1055,8 +1074,11 @@ void InitListChecker::CheckVectorType(const InitializedEntity &Entity, for (unsigned i = 0; i < maxElements; ++i, ++numEltsInit) { // Don't attempt to go past the end of the init list - if (Index >= IList->getNumInits()) + if (Index >= IList->getNumInits()) { + if (VerifyOnly) + CheckValueInitializable(ElementEntity); break; + } ElementEntity.setElementIndex(Index); CheckSubElementType(ElementEntity, IList, elementType, Index, @@ -1098,11 +1120,13 @@ void InitListChecker::CheckVectorType(const InitializedEntity &Entity, } // OpenCL requires all elements to be initialized. - // FIXME: Shouldn't this set hadError to true then? - if (numEltsInit != maxElements && !VerifyOnly) - SemaRef.Diag(IList->getSourceRange().getBegin(), - diag::err_vector_incorrect_num_initializers) - << (numEltsInit < maxElements) << maxElements << numEltsInit; + if (numEltsInit != maxElements) { + if (!VerifyOnly) + SemaRef.Diag(IList->getSourceRange().getBegin(), + diag::err_vector_incorrect_num_initializers) + << (numEltsInit < maxElements) << maxElements << numEltsInit; + hadError = true; + } } void InitListChecker::CheckArrayType(const InitializedEntity &Entity, @@ -1223,6 +1247,14 @@ void InitListChecker::CheckArrayType(const InitializedEntity &Entity, DeclType = SemaRef.Context.getConstantArrayType(elementType, maxElements, ArrayType::Normal, 0); } + if (!hadError && VerifyOnly) { + // Check if there are any members of the array that get value-initialized. + // If so, check if doing that is possible. + // FIXME: This needs to detect holes left by designated initializers too. + if (maxElementsKnown && elementIndex < maxElements) + CheckValueInitializable(InitializedEntity::InitializeElement( + SemaRef.Context, 0, Entity)); + } } bool InitListChecker::CheckFlexibleArrayInit(const InitializedEntity &Entity, @@ -1283,15 +1315,17 @@ void InitListChecker::CheckStructUnionTypes(const InitializedEntity &Entity, } if (DeclType->isUnionType() && IList->getNumInits() == 0) { - if (!VerifyOnly) { - // Value-initialize the first named member of the union. - RecordDecl *RD = DeclType->getAs()->getDecl(); - for (RecordDecl::field_iterator FieldEnd = RD->field_end(); - Field != FieldEnd; ++Field) { - if (Field->getDeclName()) { + // Value-initialize the first named member of the union. + RecordDecl *RD = DeclType->getAs()->getDecl(); + for (RecordDecl::field_iterator FieldEnd = RD->field_end(); + Field != FieldEnd; ++Field) { + if (Field->getDeclName()) { + if (VerifyOnly) + CheckValueInitializable( + InitializedEntity::InitializeMember(*Field, &Entity)); + else StructuredList->setInitializedFieldInUnion(*Field); - break; - } + break; } } return; @@ -1394,6 +1428,17 @@ void InitListChecker::CheckStructUnionTypes(const InitializedEntity &Entity, } } + // Check that any remaining fields can be value-initialized. + if (VerifyOnly && Field != FieldEnd && !DeclType->isUnionType() && + !Field->getType()->isIncompleteArrayType()) { + // FIXME: Should check for holes left by designated initializers too. + for (; Field != FieldEnd && !hadError; ++Field) { + if (!Field->isUnnamedBitfield()) + CheckValueInitializable( + InitializedEntity::InitializeMember(*Field, &Entity)); + } + } + if (Field == FieldEnd || !Field->getType()->isIncompleteArrayType() || Index >= IList->getNumInits()) return; -- 2.40.0