From: John McCall Date: Mon, 21 Feb 2011 07:57:55 +0000 (+0000) Subject: Reorganize subelement initialization checking, no functionality change. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fef8b344ea299a1717cc94486f5df6facf3e337c;p=clang Reorganize subelement initialization checking, no functionality change. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126116 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index cfc5a1ef91..de6b962aa3 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -71,13 +71,13 @@ static Expr *IsStringInit(Expr *init, QualType declType, ASTContext &Context) { return IsStringInit(init, arrayType, Context); } -static void CheckStringInit(Expr *Str, QualType &DeclT, Sema &S) { +static void CheckStringInit(Expr *Str, QualType &DeclT, const ArrayType *AT, + Sema &S) { // Get the length of the string as parsed. uint64_t StrLength = cast(Str->getType())->getSize().getZExtValue(); - const ArrayType *AT = S.Context.getAsArrayType(DeclT); if (const IncompleteArrayType *IAT = dyn_cast(AT)) { // C99 6.7.8p14. We have an array of character type with unknown size // being initialized to a string literal. @@ -656,82 +656,93 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity, newStructuredList, newStructuredIndex); ++StructuredIndex; ++Index; - } else if (Expr *Str = IsStringInit(expr, ElemType, SemaRef.Context)) { - CheckStringInit(Str, ElemType, SemaRef); - UpdateStructuredListElement(StructuredList, StructuredIndex, Str); - ++Index; + return; } else if (ElemType->isScalarType()) { - CheckScalarType(Entity, IList, ElemType, Index, - StructuredList, StructuredIndex); + return CheckScalarType(Entity, IList, ElemType, Index, + StructuredList, StructuredIndex); } else if (ElemType->isReferenceType()) { - CheckReferenceType(Entity, IList, ElemType, Index, - StructuredList, StructuredIndex); - } else { - if (SemaRef.getLangOptions().CPlusPlus) { - // C++ [dcl.init.aggr]p12: - // All implicit type conversions (clause 4) are considered when - // initializing the aggregate member with an ini- tializer from - // an initializer-list. If the initializer can initialize a - // member, the member is initialized. [...] - - // FIXME: Better EqualLoc? - InitializationKind Kind = - InitializationKind::CreateCopy(expr->getLocStart(), SourceLocation()); - InitializationSequence Seq(SemaRef, Entity, Kind, &expr, 1); - - if (Seq) { - ExprResult Result = - Seq.Perform(SemaRef, Entity, Kind, MultiExprArg(&expr, 1)); - if (Result.isInvalid()) - hadError = true; - - UpdateStructuredListElement(StructuredList, StructuredIndex, - Result.takeAs()); - ++Index; - return; - } + return CheckReferenceType(Entity, IList, ElemType, Index, + StructuredList, StructuredIndex); + } - // Fall through for subaggregate initialization - } else { - // C99 6.7.8p13: - // - // The initializer for a structure or union object that has - // automatic storage duration shall be either an initializer - // list as described below, or a single expression that has - // compatible structure or union type. In the latter case, the - // initial value of the object, including unnamed members, is - // that of the expression. - if ((ElemType->isRecordType() || ElemType->isVectorType()) && - SemaRef.CheckSingleAssignmentConstraints(ElemType, expr) - == Sema::Compatible) { - SemaRef.DefaultFunctionArrayLvalueConversion(expr); - UpdateStructuredListElement(StructuredList, StructuredIndex, expr); - ++Index; - return; - } + if (const ArrayType *arrayType = SemaRef.Context.getAsArrayType(ElemType)) { + // arrayType can be incomplete if we're initializing a flexible + // array member. There's nothing we can do with the completed + // type here, though. - // Fall through for subaggregate initialization + if (Expr *Str = IsStringInit(expr, arrayType, SemaRef.Context)) { + CheckStringInit(Str, ElemType, arrayType, SemaRef); + UpdateStructuredListElement(StructuredList, StructuredIndex, Str); + ++Index; + return; } + // Fall through for subaggregate initialization. + + } else if (SemaRef.getLangOptions().CPlusPlus) { // C++ [dcl.init.aggr]p12: + // All implicit type conversions (clause 4) are considered when + // initializing the aggregate member with an ini- tializer from + // an initializer-list. If the initializer can initialize a + // member, the member is initialized. [...] + + // FIXME: Better EqualLoc? + InitializationKind Kind = + InitializationKind::CreateCopy(expr->getLocStart(), SourceLocation()); + InitializationSequence Seq(SemaRef, Entity, Kind, &expr, 1); + + if (Seq) { + ExprResult Result = + Seq.Perform(SemaRef, Entity, Kind, MultiExprArg(&expr, 1)); + if (Result.isInvalid()) + hadError = true; + + UpdateStructuredListElement(StructuredList, StructuredIndex, + Result.takeAs()); + ++Index; + return; + } + + // Fall through for subaggregate initialization + } else { + // C99 6.7.8p13: // - // [...] Otherwise, if the member is itself a non-empty - // subaggregate, brace elision is assumed and the initializer is - // considered for the initialization of the first member of - // the subaggregate. - if (ElemType->isAggregateType() || ElemType->isVectorType()) { - CheckImplicitInitList(Entity, IList, ElemType, Index, StructuredList, - StructuredIndex); - ++StructuredIndex; - } else { - // We cannot initialize this element, so let - // PerformCopyInitialization produce the appropriate diagnostic. - SemaRef.PerformCopyInitialization(Entity, SourceLocation(), - SemaRef.Owned(expr)); - hadError = true; + // The initializer for a structure or union object that has + // automatic storage duration shall be either an initializer + // list as described below, or a single expression that has + // compatible structure or union type. In the latter case, the + // initial value of the object, including unnamed members, is + // that of the expression. + if ((ElemType->isRecordType() || ElemType->isVectorType()) && + SemaRef.CheckSingleAssignmentConstraints(ElemType, expr) + == Sema::Compatible) { + SemaRef.DefaultFunctionArrayLvalueConversion(expr); + UpdateStructuredListElement(StructuredList, StructuredIndex, expr); ++Index; - ++StructuredIndex; + return; } + + // Fall through for subaggregate initialization + } + + // C++ [dcl.init.aggr]p12: + // + // [...] Otherwise, if the member is itself a non-empty + // subaggregate, brace elision is assumed and the initializer is + // considered for the initialization of the first member of + // the subaggregate. + if (ElemType->isAggregateType() || ElemType->isVectorType()) { + CheckImplicitInitList(Entity, IList, ElemType, Index, StructuredList, + StructuredIndex); + ++StructuredIndex; + } else { + // We cannot initialize this element, so let + // PerformCopyInitialization produce the appropriate diagnostic. + SemaRef.PerformCopyInitialization(Entity, SourceLocation(), + SemaRef.Owned(expr)); + hadError = true; + ++Index; + ++StructuredIndex; } } @@ -947,7 +958,7 @@ void InitListChecker::CheckArrayType(const InitializedEntity &Entity, if (Index < IList->getNumInits()) { if (Expr *Str = IsStringInit(IList->getInit(Index), arrayType, SemaRef.Context)) { - CheckStringInit(Str, DeclType, SemaRef); + CheckStringInit(Str, DeclType, arrayType, SemaRef); // We place the string literal directly into the resulting // initializer list. This is the only place where the structure // of the structured initializer list doesn't match exactly, @@ -4033,7 +4044,8 @@ InitializationSequence::Perform(Sema &S, case SK_StringInit: { QualType Ty = Step->Type; - CheckStringInit(CurInitExpr, ResultType ? *ResultType : Ty, S); + CheckStringInit(CurInitExpr, ResultType ? *ResultType : Ty, + S.Context.getAsArrayType(Ty), S); break; }