<p dir="ltr">On 4 Jun 2014 05:07, "Evgeniy Stepanov" <<a href="mailto:eugeni.stepanov@gmail.com">eugeni.stepanov@gmail.com</a>> wrote:<br>
><br>
> Hi,<br>
><br>
> This change is causing this to fail with -std=c++11:<br>
> struct A { explicit A(int x = 0) {(void)x;}; };<br>
> A a = {};<br>
> with error: chosen constructor is explicit in copy-initialization<br>
><br>
> but this passes:<br>
> struct A { explicit A(int x = 0) {(void)x;}; };<br>
> A a{};<br>
><br>
> Is it correct?</p>
<p dir="ltr">It looks correct (but I need to double check, because the empty list / class with default constructor case is a special case in the standard). I'm surprised that code was affected by this change, though, since it contains no aggregate initialization.</p>
<p dir="ltr">> On Tue, Jun 3, 2014 at 12:26 PM, Richard Smith<br>
> <<a href="mailto:richard-llvm@metafoo.co.uk">richard-llvm@metafoo.co.uk</a>> wrote:<br>
> > Author: rsmith<br>
> > Date: Tue Jun 3 03:26:00 2014<br>
> > New Revision: 210091<br>
> ><br>
> > URL: <a href="http://llvm.org/viewvc/llvm-project?rev=210091&view=rev">http://llvm.org/viewvc/llvm-project?rev=210091&view=rev</a><br>
> > Log:<br>
> > Implement DR990 and DR1070. Aggregate initialization initializes uninitialized<br>
> > elements from {}, rather than value-initializing them. This permits calling an<br>
> > initializer-list constructor or constructing a std::initializer_list object.<br>
> > (It would also permit initializing a const reference or rvalue reference if<br>
> > that weren't explicitly prohibited by other rules.)<br>
> ><br>
> > Added:<br>
> > cfe/trunk/test/CXX/drs/dr10xx.cpp<br>
> > cfe/trunk/test/CXX/drs/dr9xx.cpp<br>
> > Modified:<br>
> > cfe/trunk/include/clang/AST/Expr.h<br>
> > cfe/trunk/include/clang/Sema/Initialization.h<br>
> > cfe/trunk/lib/CodeGen/CGExprCXX.cpp<br>
> > cfe/trunk/lib/Sema/SemaInit.cpp<br>
> > cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp<br>
> > cfe/trunk/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp<br>
> > cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp<br>
> > cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp<br>
> > cfe/trunk/www/cxx_dr_status.html<br>
> ><br>
> > Modified: cfe/trunk/include/clang/AST/Expr.h<br>
> > URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=210091&r1=210090&r2=210091&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=210091&r1=210090&r2=210091&view=diff</a><br>
> > ==============================================================================<br>
> > --- cfe/trunk/include/clang/AST/Expr.h (original)<br>
> > +++ cfe/trunk/include/clang/AST/Expr.h Tue Jun 3 03:26:00 2014<br>
> > @@ -3909,6 +3909,7 @@ public:<br>
> ><br>
> > // Iterators<br>
> > child_range children() {<br>
> > + // FIXME: This does not include the array filler expression.<br>
> > if (InitExprs.empty()) return child_range();<br>
> > return child_range(&InitExprs[0], &InitExprs[0] + InitExprs.size());<br>
> > }<br>
> ><br>
> > Modified: cfe/trunk/include/clang/Sema/Initialization.h<br>
> > URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Initialization.h?rev=210091&r1=210090&r2=210091&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Initialization.h?rev=210091&r1=210090&r2=210091&view=diff</a><br>
> > ==============================================================================<br>
> > --- cfe/trunk/include/clang/Sema/Initialization.h (original)<br>
> > +++ cfe/trunk/include/clang/Sema/Initialization.h Tue Jun 3 03:26:00 2014<br>
> > @@ -401,6 +401,13 @@ public:<br>
> > return SourceLocation::getFromRawEncoding(LocAndNRVO.Location);<br>
> > }<br>
> ><br>
> > + /// \brief If this is an array, vector, or complex number element, get the<br>
> > + /// element's index.<br>
> > + unsigned getElementIndex() const {<br>
> > + assert(getKind() == EK_ArrayElement || getKind() == EK_VectorElement ||<br>
> > + getKind() == EK_ComplexElement);<br>
> > + return Index;<br>
> > + }<br>
> > /// \brief If this is already the initializer for an array or vector<br>
> > /// element, sets the element index.<br>
> > void setElementIndex(unsigned Index) {<br>
> > @@ -851,17 +858,17 @@ public:<br>
> > ///<br>
> > /// \param Args the argument(s) provided for initialization.<br>
> > ///<br>
> > - /// \param InInitList true if we are initializing from an expression within<br>
> > - /// an initializer list. This disallows narrowing conversions in C++11<br>
> > - /// onwards.<br>
> > + /// \param TopLevelOfInitList true if we are initializing from an expression<br>
> > + /// at the top level inside an initializer list. This disallows<br>
> > + /// narrowing conversions in C++11 onwards.<br>
> > InitializationSequence(Sema &S,<br>
> > const InitializedEntity &Entity,<br>
> > const InitializationKind &Kind,<br>
> > MultiExprArg Args,<br>
> > - bool InInitList = false);<br>
> > + bool TopLevelOfInitList = false);<br>
> > void InitializeFrom(Sema &S, const InitializedEntity &Entity,<br>
> > const InitializationKind &Kind, MultiExprArg Args,<br>
> > - bool InInitList);<br>
> > + bool TopLevelOfInitList);<br>
> ><br>
> > ~InitializationSequence();<br>
> ><br>
> ><br>
> > Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp<br>
> > URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=210091&r1=210090&r2=210091&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=210091&r1=210090&r2=210091&view=diff</a><br>
> > ==============================================================================<br>
> > --- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)<br>
> > +++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Tue Jun 3 03:26:00 2014<br>
> > @@ -858,9 +858,21 @@ CodeGenFunction::EmitNewArrayInitializer<br>
> > return true;<br>
> > };<br>
> ><br>
> > + // If all elements have already been initialized, skip any further<br>
> > + // initialization.<br>
> > + llvm::ConstantInt *ConstNum = dyn_cast<llvm::ConstantInt>(NumElements);<br>
> > + if (ConstNum && ConstNum->getZExtValue() <= InitListElements) {<br>
> > + // If there was a Cleanup, deactivate it.<br>
> > + if (CleanupDominator)<br>
> > + DeactivateCleanupBlock(Cleanup, CleanupDominator);<br>
> > + return;<br>
> > + }<br>
> > +<br>
> > + assert(Init && "have trailing elements to initialize but no initializer");<br>
> > +<br>
> > // If this is a constructor call, try to optimize it out, and failing that<br>
> > // emit a single loop to initialize all remaining elements.<br>
> > - if (const CXXConstructExpr *CCE = dyn_cast_or_null<CXXConstructExpr>(Init)){<br>
> > + if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(Init)) {<br>
> > CXXConstructorDecl *Ctor = CCE->getConstructor();<br>
> > if (Ctor->isTrivial()) {<br>
> > // If new expression did not specify value-initialization, then there<br>
> > @@ -891,7 +903,7 @@ CodeGenFunction::EmitNewArrayInitializer<br>
> ><br>
> > // If this is value-initialization, we can usually use memset.<br>
> > ImplicitValueInitExpr IVIE(ElementType);<br>
> > - if (Init && isa<ImplicitValueInitExpr>(Init)) {<br>
> > + if (isa<ImplicitValueInitExpr>(Init)) {<br>
> > if (TryMemsetInitialization())<br>
> > return;<br>
> ><br>
> > @@ -906,15 +918,10 @@ CodeGenFunction::EmitNewArrayInitializer<br>
> > assert(getContext().hasSameUnqualifiedType(ElementType, Init->getType()) &&<br>
> > "got wrong type of element to initialize");<br>
> ><br>
> > - llvm::ConstantInt *ConstNum = dyn_cast<llvm::ConstantInt>(NumElements);<br>
> > -<br>
> > - // If all elements have already been initialized, skip the whole loop.<br>
> > - if (ConstNum && ConstNum->getZExtValue() <= InitListElements) {<br>
> > - // If there was a Cleanup, deactivate it.<br>
> > - if (CleanupDominator)<br>
> > - DeactivateCleanupBlock(Cleanup, CleanupDominator);<br>
> > - return;<br>
> > - }<br>
> > + // If we have an empty initializer list, we can usually use memset.<br>
> > + if (auto *ILE = dyn_cast<InitListExpr>(Init))<br>
> > + if (ILE->getNumInits() == 0 && TryMemsetInitialization())<br>
> > + return;<br>
> ><br>
> > // Create the loop blocks.<br>
> > llvm::BasicBlock *EntryBB = Builder.GetInsertBlock();<br>
> ><br>
> > Modified: cfe/trunk/lib/Sema/SemaInit.cpp<br>
> > URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=210091&r1=210090&r2=210091&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=210091&r1=210090&r2=210091&view=diff</a><br>
> > ==============================================================================<br>
> > --- cfe/trunk/lib/Sema/SemaInit.cpp (original)<br>
> > +++ cfe/trunk/lib/Sema/SemaInit.cpp Tue Jun 3 03:26:00 2014<br>
> > @@ -312,15 +312,20 @@ class InitListChecker {<br>
> > int numArrayElements(QualType DeclType);<br>
> > int numStructUnionElements(QualType DeclType);<br>
> ><br>
> > - void FillInValueInitForField(unsigned Init, FieldDecl *Field,<br>
> > + static ExprResult PerformEmptyInit(Sema &SemaRef,<br>
> > + SourceLocation Loc,<br>
> > + const InitializedEntity &Entity,<br>
> > + bool VerifyOnly);<br>
> > + void FillInEmptyInitForField(unsigned Init, FieldDecl *Field,<br>
> > const InitializedEntity &ParentEntity,<br>
> > InitListExpr *ILE, bool &RequiresSecondPass);<br>
> > - void FillInValueInitializations(const InitializedEntity &Entity,<br>
> > + void FillInEmptyInitializations(const InitializedEntity &Entity,<br>
> > InitListExpr *ILE, bool &RequiresSecondPass);<br>
> > bool CheckFlexibleArrayInit(const InitializedEntity &Entity,<br>
> > Expr *InitExpr, FieldDecl *Field,<br>
> > bool TopLevelObject);<br>
> > - void CheckValueInitializable(const InitializedEntity &Entity);<br>
> > + void CheckEmptyInitializable(const InitializedEntity &Entity,<br>
> > + SourceLocation Loc);<br>
> ><br>
> > public:<br>
> > InitListChecker(Sema &S, const InitializedEntity &Entity,<br>
> > @@ -333,33 +338,84 @@ public:<br>
> > };<br>
> > } // end anonymous namespace<br>
> ><br>
> > -void InitListChecker::CheckValueInitializable(const InitializedEntity &Entity) {<br>
> > - assert(VerifyOnly &&<br>
> > - "CheckValueInitializable is only inteded for verification mode.");<br>
> > -<br>
> > - SourceLocation Loc;<br>
> > +ExprResult InitListChecker::PerformEmptyInit(Sema &SemaRef,<br>
> > + SourceLocation Loc,<br>
> > + const InitializedEntity &Entity,<br>
> > + bool VerifyOnly) {<br>
> > InitializationKind Kind = InitializationKind::CreateValue(Loc, Loc, Loc,<br>
> > true);<br>
> > - InitializationSequence InitSeq(SemaRef, Entity, Kind, None);<br>
> > - if (InitSeq.Failed())<br>
> > + MultiExprArg SubInit;<br>
> > + Expr *InitExpr;<br>
> > + InitListExpr DummyInitList(SemaRef.Context, Loc, None, Loc);<br>
> > +<br>
> > + // C++ [dcl.init.aggr]p7:<br>
> > + // If there are fewer initializer-clauses in the list than there are<br>
> > + // members in the aggregate, then each member not explicitly initialized<br>
> > + // ...<br>
> > + if (SemaRef.getLangOpts().CPlusPlus11 &&<br>
> > + Entity.getType()->getBaseElementTypeUnsafe()->isRecordType()) {<br>
> > + // C++1y / DR1070:<br>
> > + // shall be initialized [...] from an empty initializer list.<br>
> > + //<br>
> > + // We apply the resolution of this DR to C++11 but not C++98, since C++98<br>
> > + // does not have useful semantics for initialization from an init list.<br>
> > + // We treat this as copy-initialization, because aggregate initialization<br>
> > + // always performs copy-initialization on its elements.<br>
> > + //<br>
> > + // Only do this if we're initializing a class type, to avoid filling in<br>
> > + // the initializer list where possible.<br>
> > + InitExpr = VerifyOnly ? &DummyInitList : new (SemaRef.Context)<br>
> > + InitListExpr(SemaRef.Context, Loc, None, Loc);<br>
> > + InitExpr->setType(SemaRef.Context.VoidTy);<br>
> > + SubInit = InitExpr;<br>
> > + Kind = InitializationKind::CreateCopy(Loc, Loc);<br>
> > + } else {<br>
> > + // C++03:<br>
> > + // shall be value-initialized.<br>
> > + }<br>
> > +<br>
> > + InitializationSequence InitSeq(SemaRef, Entity, Kind, SubInit);<br>
> > + if (!InitSeq) {<br>
> > + if (!VerifyOnly) {<br>
> > + InitSeq.Diagnose(SemaRef, Entity, Kind, SubInit);<br>
> > + if (Entity.getKind() == InitializedEntity::EK_Member)<br>
> > + SemaRef.Diag(Entity.getDecl()->getLocation(),<br>
> > + diag::note_in_omitted_aggregate_initializer)<br>
> > + << /*field*/1 << Entity.getDecl();<br>
> > + else if (Entity.getKind() == InitializedEntity::EK_ArrayElement)<br>
> > + SemaRef.Diag(Loc, diag::note_in_omitted_aggregate_initializer)<br>
> > + << /*array element*/0 << Entity.getElementIndex();<br>
> > + }<br>
> > + return ExprError();<br>
> > + }<br>
> > +<br>
> > + return VerifyOnly ? ExprResult(static_cast<Expr *>(nullptr))<br>
> > + : InitSeq.Perform(SemaRef, Entity, Kind, SubInit);<br>
> > +}<br>
> > +<br>
> > +void InitListChecker::CheckEmptyInitializable(const InitializedEntity &Entity,<br>
> > + SourceLocation Loc) {<br>
> > + assert(VerifyOnly &&<br>
> > + "CheckEmptyInitializable is only inteded for verification mode.");<br>
> > + if (PerformEmptyInit(SemaRef, Loc, Entity, /*VerifyOnly*/true).isInvalid())<br>
> > hadError = true;<br>
> > }<br>
> ><br>
> > -void InitListChecker::FillInValueInitForField(unsigned Init, FieldDecl *Field,<br>
> > +void InitListChecker::FillInEmptyInitForField(unsigned Init, FieldDecl *Field,<br>
> > const InitializedEntity &ParentEntity,<br>
> > InitListExpr *ILE,<br>
> > bool &RequiresSecondPass) {<br>
> > - SourceLocation Loc = ILE->getLocStart();<br>
> > + SourceLocation Loc = ILE->getLocEnd();<br>
> > unsigned NumInits = ILE->getNumInits();<br>
> > InitializedEntity MemberEntity<br>
> > = InitializedEntity::InitializeMember(Field, &ParentEntity);<br>
> > if (Init >= NumInits || !ILE->getInit(Init)) {<br>
> > - // If there's no explicit initializer but we have a default initializer, use<br>
> > - // that. This only happens in C++1y, since classes with default<br>
> > - // initializers are not aggregates in C++11.<br>
> > + // C++1y [dcl.init.aggr]p7:<br>
> > + // If there are fewer initializer-clauses in the list than there are<br>
> > + // members in the aggregate, then each member not explicitly initialized<br>
> > + // shall be initialized from its brace-or-equal-initializer [...]<br>
> > if (Field->hasInClassInitializer()) {<br>
> > - Expr *DIE = CXXDefaultInitExpr::Create(SemaRef.Context,<br>
> > - ILE->getRBraceLoc(), Field);<br>
> > + Expr *DIE = CXXDefaultInitExpr::Create(SemaRef.Context, Loc, Field);<br>
> > if (Init < NumInits)<br>
> > ILE->setInit(Init, DIE);<br>
> > else {<br>
> > @@ -369,9 +425,6 @@ void InitListChecker::FillInValueInitFor<br>
> > return;<br>
> > }<br>
> ><br>
> > - // FIXME: We probably don't need to handle references<br>
> > - // specially here, since value-initialization of references is<br>
> > - // handled in InitializationSequence.<br>
> > if (Field->getType()->isReferenceType()) {<br>
> > // C++ [dcl.init.aggr]p9:<br>
> > // If an incomplete or empty initializer-list leaves a<br>
> > @@ -386,20 +439,8 @@ void InitListChecker::FillInValueInitFor<br>
> > return;<br>
> > }<br>
> ><br>
> > - InitializationKind Kind = InitializationKind::CreateValue(Loc, Loc, Loc,<br>
> > - true);<br>
> > - InitializationSequence InitSeq(SemaRef, MemberEntity, Kind, None);<br>
> > - if (!InitSeq) {<br>
> > - InitSeq.Diagnose(SemaRef, MemberEntity, Kind, None);<br>
> > - SemaRef.Diag(Field->getLocation(),<br>
> > - diag::note_in_omitted_aggregate_initializer)<br>
> > - << /*field*/1 << Field;<br>
> > - hadError = true;<br>
> > - return;<br>
> > - }<br>
> > -<br>
> > - ExprResult MemberInit<br>
> > - = InitSeq.Perform(SemaRef, MemberEntity, Kind, None);<br>
> > + ExprResult MemberInit = PerformEmptyInit(SemaRef, Loc, MemberEntity,<br>
> > + /*VerifyOnly*/false);<br>
> > if (MemberInit.isInvalid()) {<br>
> > hadError = true;<br>
> > return;<br>
> > @@ -409,8 +450,8 @@ void InitListChecker::FillInValueInitFor<br>
> > // Do nothing<br>
> > } else if (Init < NumInits) {<br>
> > ILE->setInit(Init, MemberInit.getAs<Expr>());<br>
> > - } else if (InitSeq.isConstructorInitialization()) {<br>
> > - // Value-initialization requires a constructor call, so<br>
> > + } else if (!isa<ImplicitValueInitExpr>(MemberInit.get())) {<br>
> > + // Empty initialization requires a constructor call, so<br>
> > // extend the initializer list to include the constructor<br>
> > // call and make a note that we'll need to take another pass<br>
> > // through the initializer list.<br>
> > @@ -419,7 +460,7 @@ void InitListChecker::FillInValueInitFor<br>
> > }<br>
> > } else if (InitListExpr *InnerILE<br>
> > = dyn_cast<InitListExpr>(ILE->getInit(Init)))<br>
> > - FillInValueInitializations(MemberEntity, InnerILE,<br>
> > + FillInEmptyInitializations(MemberEntity, InnerILE,<br>
> > RequiresSecondPass);<br>
> > }<br>
> ><br>
> > @@ -427,7 +468,7 @@ void InitListChecker::FillInValueInitFor<br>
> > /// with expressions that perform value-initialization of the<br>
> > /// appropriate type.<br>
> > void<br>
> > -InitListChecker::FillInValueInitializations(const InitializedEntity &Entity,<br>
> > +InitListChecker::FillInEmptyInitializations(const InitializedEntity &Entity,<br>
> > InitListExpr *ILE,<br>
> > bool &RequiresSecondPass) {<br>
> > assert((ILE->getType() != SemaRef.Context.VoidTy) &&<br>
> > @@ -436,13 +477,13 @@ InitListChecker::FillInValueInitializati<br>
> > if (const RecordType *RType = ILE->getType()->getAs<RecordType>()) {<br>
> > const RecordDecl *RDecl = RType->getDecl();<br>
> > if (RDecl->isUnion() && ILE->getInitializedFieldInUnion())<br>
> > - FillInValueInitForField(0, ILE->getInitializedFieldInUnion(),<br>
> > + FillInEmptyInitForField(0, ILE->getInitializedFieldInUnion(),<br>
> > Entity, ILE, RequiresSecondPass);<br>
> > else if (RDecl->isUnion() && isa<CXXRecordDecl>(RDecl) &&<br>
> > cast<CXXRecordDecl>(RDecl)->hasInClassInitializer()) {<br>
> > for (auto *Field : RDecl->fields()) {<br>
> > if (Field->hasInClassInitializer()) {<br>
> > - FillInValueInitForField(0, Field, Entity, ILE, RequiresSecondPass);<br>
> > + FillInEmptyInitForField(0, Field, Entity, ILE, RequiresSecondPass);<br>
> > break;<br>
> > }<br>
> > }<br>
> > @@ -455,7 +496,7 @@ InitListChecker::FillInValueInitializati<br>
> > if (hadError)<br>
> > return;<br>
> ><br>
> > - FillInValueInitForField(Init, Field, Entity, ILE, RequiresSecondPass);<br>
> > + FillInEmptyInitForField(Init, Field, Entity, ILE, RequiresSecondPass);<br>
> > if (hadError)<br>
> > return;<br>
> ><br>
> > @@ -489,10 +530,6 @@ InitListChecker::FillInValueInitializati<br>
> > } else<br>
> > ElementType = ILE->getType();<br>
> ><br>
> > - SourceLocation Loc = ILE->getLocEnd();<br>
> > - if (ILE->getSyntacticForm())<br>
> > - Loc = ILE->getSyntacticForm()->getLocEnd();<br>
> > -<br>
> > for (unsigned Init = 0; Init != NumElements; ++Init) {<br>
> > if (hadError)<br>
> > return;<br>
> > @@ -503,19 +540,9 @@ InitListChecker::FillInValueInitializati<br>
> ><br>
> > Expr *InitExpr = (Init < NumInits ? ILE->getInit(Init) : nullptr);<br>
> > if (!InitExpr && !ILE->hasArrayFiller()) {<br>
> > - InitializationKind Kind = InitializationKind::CreateValue(Loc, Loc, Loc,<br>
> > - true);<br>
> > - InitializationSequence InitSeq(SemaRef, ElementEntity, Kind, None);<br>
> > - if (!InitSeq) {<br>
> > - InitSeq.Diagnose(SemaRef, ElementEntity, Kind, None);<br>
> > - SemaRef.Diag(Loc, diag::note_in_omitted_aggregate_initializer)<br>
> > - << /*array element*/0 << Init;<br>
> > - hadError = true;<br>
> > - return;<br>
> > - }<br>
> > -<br>
> > - ExprResult ElementInit<br>
> > - = InitSeq.Perform(SemaRef, ElementEntity, Kind, None);<br>
> > + ExprResult ElementInit = PerformEmptyInit(SemaRef, ILE->getLocEnd(),<br>
> > + ElementEntity,<br>
> > + /*VerifyOnly*/false);<br>
> > if (ElementInit.isInvalid()) {<br>
> > hadError = true;<br>
> > return;<br>
> > @@ -538,8 +565,8 @@ InitListChecker::FillInValueInitializati<br>
> > return;<br>
> > }<br>
> ><br>
> > - if (InitSeq.isConstructorInitialization()) {<br>
> > - // Value-initialization requires a constructor call, so<br>
> > + if (!isa<ImplicitValueInitExpr>(ElementInit.get())) {<br>
> > + // Empty initialization requires a constructor call, so<br>
> > // extend the initializer list to include the constructor<br>
> > // call and make a note that we'll need to take another pass<br>
> > // through the initializer list.<br>
> > @@ -549,7 +576,7 @@ InitListChecker::FillInValueInitializati<br>
> > }<br>
> > } else if (InitListExpr *InnerILE<br>
> > = dyn_cast_or_null<InitListExpr>(InitExpr))<br>
> > - FillInValueInitializations(ElementEntity, InnerILE, RequiresSecondPass);<br>
> > + FillInEmptyInitializations(ElementEntity, InnerILE, RequiresSecondPass);<br>
> > }<br>
> > }<br>
> ><br>
> > @@ -567,9 +594,9 @@ InitListChecker::InitListChecker(Sema &S<br>
> ><br>
> > if (!hadError && !VerifyOnly) {<br>
> > bool RequiresSecondPass = false;<br>
> > - FillInValueInitializations(Entity, FullyStructuredList, RequiresSecondPass);<br>
> > + FillInEmptyInitializations(Entity, FullyStructuredList, RequiresSecondPass);<br>
> > if (RequiresSecondPass && !hadError)<br>
> > - FillInValueInitializations(Entity, FullyStructuredList,<br>
> > + FillInEmptyInitializations(Entity, FullyStructuredList,<br>
> > RequiresSecondPass);<br>
> > }<br>
> > }<br>
> > @@ -678,7 +705,6 @@ void InitListChecker::CheckExplicitInitL<br>
> > InitListExpr *IList, QualType &T,<br>
> > InitListExpr *StructuredList,<br>
> > bool TopLevelObject) {<br>
> > - assert(IList->isExplicit() && "Illegal Implicit InitListExpr");<br>
> > if (!VerifyOnly) {<br>
> > SyntacticToSemantic[IList] = StructuredList;<br>
> > StructuredList->setSyntacticForm(IList);<br>
> > @@ -1121,8 +1147,9 @@ void InitListChecker::CheckVectorType(co<br>
> > if (Index >= IList->getNumInits()) {<br>
> > // Make sure the element type can be value-initialized.<br>
> > if (VerifyOnly)<br>
> > - CheckValueInitializable(<br>
> > - InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity));<br>
> > + CheckEmptyInitializable(<br>
> > + InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity),<br>
> > + IList->getLocEnd());<br>
> > return;<br>
> > }<br>
> ><br>
> > @@ -1169,7 +1196,7 @@ void InitListChecker::CheckVectorType(co<br>
> > // Don't attempt to go past the end of the init list<br>
> > if (Index >= IList->getNumInits()) {<br>
> > if (VerifyOnly)<br>
> > - CheckValueInitializable(ElementEntity);<br>
> > + CheckEmptyInitializable(ElementEntity, IList->getLocEnd());<br>
> > break;<br>
> > }<br>
> ><br>
> > @@ -1346,8 +1373,9 @@ void InitListChecker::CheckArrayType(con<br>
> > // If so, check if doing that is possible.<br>
> > // FIXME: This needs to detect holes left by designated initializers too.<br>
> > if (maxElementsKnown && elementIndex < maxElements)<br>
> > - CheckValueInitializable(InitializedEntity::InitializeElement(<br>
> > - SemaRef.Context, 0, Entity));<br>
> > + CheckEmptyInitializable(InitializedEntity::InitializeElement(<br>
> > + SemaRef.Context, 0, Entity),<br>
> > + IList->getLocEnd());<br>
> > }<br>
> > }<br>
> ><br>
> > @@ -1432,8 +1460,9 @@ void InitListChecker::CheckStructUnionTy<br>
> > Field != FieldEnd; ++Field) {<br>
> > if (Field->getDeclName()) {<br>
> > if (VerifyOnly)<br>
> > - CheckValueInitializable(<br>
> > - InitializedEntity::InitializeMember(*Field, &Entity));<br>
> > + CheckEmptyInitializable(<br>
> > + InitializedEntity::InitializeMember(*Field, &Entity),<br>
> > + IList->getLocEnd());<br>
> > else<br>
> > StructuredList->setInitializedFieldInUnion(*Field);<br>
> > break;<br>
> > @@ -1545,8 +1574,9 @@ void InitListChecker::CheckStructUnionTy<br>
> > // FIXME: Should check for holes left by designated initializers too.<br>
> > for (; Field != FieldEnd && !hadError; ++Field) {<br>
> > if (!Field->isUnnamedBitfield() && !Field->hasInClassInitializer())<br>
> > - CheckValueInitializable(<br>
> > - InitializedEntity::InitializeMember(*Field, &Entity));<br>
> > + CheckEmptyInitializable(<br>
> > + InitializedEntity::InitializeMember(*Field, &Entity),<br>
> > + IList->getLocEnd());<br>
> > }<br>
> > }<br>
> ><br>
> ><br>
> > Added: cfe/trunk/test/CXX/drs/dr10xx.cpp<br>
> > URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr10xx.cpp?rev=210091&view=auto">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr10xx.cpp?rev=210091&view=auto</a><br>
> > ==============================================================================<br>
> > --- cfe/trunk/test/CXX/drs/dr10xx.cpp (added)<br>
> > +++ cfe/trunk/test/CXX/drs/dr10xx.cpp Tue Jun 3 03:26:00 2014<br>
> > @@ -0,0 +1,33 @@<br>
> > +// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors<br>
> > +// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors<br>
> > +// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors<br>
> > +<br>
> > +// expected-no-diagnostics<br>
> > +<br>
> > +namespace std {<br>
> > + __extension__ typedef __SIZE_TYPE__ size_t;<br>
> > +<br>
> > + template<typename T> struct initializer_list {<br>
> > + const T *p; size_t n;<br>
> > + initializer_list(const T *p, size_t n);<br>
> > + };<br>
> > +}<br>
> > +<br>
> > +namespace dr1070 { // dr1070: 3.5<br>
> > +#if __cplusplus >= 201103L<br>
> > + struct A {<br>
> > + A(std::initializer_list<int>);<br>
> > + };<br>
> > + struct B {<br>
> > + int i;<br>
> > + A a;<br>
> > + };<br>
> > + B b = {1};<br>
> > + struct C {<br>
> > + std::initializer_list<int> a;<br>
> > + B b;<br>
> > + std::initializer_list<double> c;<br>
> > + };<br>
> > + C c = {};<br>
> > +#endif<br>
> > +}<br>
> ><br>
> > Added: cfe/trunk/test/CXX/drs/dr9xx.cpp<br>
> > URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr9xx.cpp?rev=210091&view=auto">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr9xx.cpp?rev=210091&view=auto</a><br>
> > ==============================================================================<br>
> > --- cfe/trunk/test/CXX/drs/dr9xx.cpp (added)<br>
> > +++ cfe/trunk/test/CXX/drs/dr9xx.cpp Tue Jun 3 03:26:00 2014<br>
> > @@ -0,0 +1,45 @@<br>
> > +// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors<br>
> > +// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors<br>
> > +// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors<br>
> > +<br>
> > +#if __cplusplus < 201103L<br>
> > +// expected-no-diagnostics<br>
> > +#endif<br>
> > +<br>
> > +namespace std {<br>
> > + __extension__ typedef __SIZE_TYPE__ size_t;<br>
> > +<br>
> > + template<typename T> struct initializer_list {<br>
> > + const T *p; size_t n;<br>
> > + initializer_list(const T *p, size_t n);<br>
> > + };<br>
> > +}<br>
> > +<br>
> > +namespace dr990 { // dr990: 3.5<br>
> > +#if __cplusplus >= 201103L<br>
> > + struct A { // expected-note 2{{candidate}}<br>
> > + A(std::initializer_list<int>); // expected-note {{candidate}}<br>
> > + };<br>
> > + struct B {<br>
> > + A a;<br>
> > + };<br>
> > + B b1 { };<br>
> > + B b2 { 1 }; // expected-error {{no viable conversion from 'int' to 'dr990::A'}}<br>
> > + B b3 { { 1 } };<br>
> > +<br>
> > + struct C {<br>
> > + C();<br>
> > + C(int);<br>
> > + C(std::initializer_list<int>) = delete; // expected-note {{here}}<br>
> > + };<br>
> > + C c1[3] { 1 }; // ok<br>
> > + C c2[3] { 1, {2} }; // expected-error {{call to deleted}}<br>
> > +<br>
> > + struct D {<br>
> > + D();<br>
> > + D(std::initializer_list<int>);<br>
> > + D(std::initializer_list<double>);<br>
> > + };<br>
> > + D d{};<br>
> > +#endif<br>
> > +}<br>
> ><br>
> > Modified: cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp<br>
> > URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp?rev=210091&r1=210090&r2=210091&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp?rev=210091&r1=210090&r2=210091&view=diff</a><br>
> > ==============================================================================<br>
> > --- cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp (original)<br>
> > +++ cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp Tue Jun 3 03:26:00 2014<br>
> > @@ -1,4 +1,4 @@<br>
> > -// RUN: %clang_cc1 -std=c++11 -S -triple x86_64-none-linux-gnu -emit-llvm -o - %s | FileCheck %s<br>
> > +// RUN: %clang_cc1 -std=c++11 -triple x86_64-none-linux-gnu -emit-llvm -o - %s | FileCheck %s<br>
> ><br>
> > namespace std {<br>
> > typedef decltype(sizeof(int)) size_t;<br>
> > @@ -431,3 +431,20 @@ namespace nested {<br>
> > // CHECK: }<br>
> > }<br>
> > }<br>
> > +<br>
> > +namespace DR1070 {<br>
> > + struct A {<br>
> > + A(std::initializer_list<int>);<br>
> > + };<br>
> > + struct B {<br>
> > + int i;<br>
> > + A a;<br>
> > + };<br>
> > + B b = {1};<br>
> > + struct C {<br>
> > + std::initializer_list<int> a;<br>
> > + B b;<br>
> > + std::initializer_list<double> c;<br>
> > + };<br>
> > + C c = {};<br>
> > +}<br>
> ><br>
> > Modified: cfe/trunk/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp<br>
> > URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp?rev=210091&r1=210090&r2=210091&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp?rev=210091&r1=210090&r2=210091&view=diff</a><br>
> > ==============================================================================<br>
> > --- cfe/trunk/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp (original)<br>
> > +++ cfe/trunk/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp Tue Jun 3 03:26:00 2014<br>
> > @@ -46,7 +46,7 @@ B z { 1 };<br>
> > // CHECK: store i8 %{{.*}}, i8* getelementptr inbounds ({{.*}} @a, i32 0, i32 2)<br>
> > // CHECK: call i32 @_ZN1A1fEv({{.*}} @a)<br>
> > // CHECK: store i32 %{{.*}}, i32* getelementptr inbounds ({{.*}}* @a, i32 0, i32 3)<br>
> > -// CHECK: call void @{{.*}}C1Ev({{.*}} getelementptr inbounds (%struct.A* @a, i32 0, i32 4))<br>
> > +// CHECK: store double 1.000000e+00, double* getelementptr inbounds ({{.*}} @a, i32 0, i32 4, i32 0)<br>
> ><br>
> > // No dynamic initialization of 'b':<br>
> ><br>
> ><br>
> > Modified: cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp<br>
> > URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp?rev=210091&r1=210090&r2=210091&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp?rev=210091&r1=210090&r2=210091&view=diff</a><br>
> > ==============================================================================<br>
> > --- cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp (original)<br>
> > +++ cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp Tue Jun 3 03:26:00 2014<br>
> > @@ -389,8 +389,8 @@ namespace PR11410 {<br>
> ><br>
> > struct B {<br>
> > A a; // expected-note {{in implicit initialization of field 'a'}}<br>
> > - } b = { // expected-error {{call to deleted constructor}}<br>
> > - };<br>
> > + } b = {<br>
> > + }; // expected-error {{call to deleted constructor}}<br>
> ><br>
> > struct C {<br>
> > C(int = 0); // expected-note 2{{candidate}}<br>
> ><br>
> > Modified: cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp<br>
> > URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp?rev=210091&r1=210090&r2=210091&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp?rev=210091&r1=210090&r2=210091&view=diff</a><br>
> > ==============================================================================<br>
> > --- cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp (original)<br>
> > +++ cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp Tue Jun 3 03:26:00 2014<br>
> > @@ -230,3 +230,11 @@ namespace PR18013 {<br>
> > int f();<br>
> > std::initializer_list<long (*)()> x = {f}; // expected-error {{cannot initialize an array element of type 'long (*const)()' with an lvalue of type 'int ()': different return type ('long' vs 'int')}}<br>
> > }<br>
> > +<br>
> > +namespace DR1070 {<br>
> > + struct S {<br>
> > + S(std::initializer_list<int>);<br>
> > + };<br>
> > + S s[3] = { {1, 2, 3}, {4, 5} }; // ok<br>
> > + S *p = new S[3] { {1, 2, 3}, {4, 5} }; // ok<br>
> > +}<br>
> ><br>
> > Modified: cfe/trunk/www/cxx_dr_status.html<br>
> > URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_dr_status.html?rev=210091&r1=210090&r2=210091&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_dr_status.html?rev=210091&r1=210090&r2=210091&view=diff</a><br>
> > ==============================================================================<br>
> > --- cfe/trunk/www/cxx_dr_status.html (original)<br>
> > +++ cfe/trunk/www/cxx_dr_status.html Tue Jun 3 03:26:00 2014<br>
> > @@ -3233,7 +3233,7 @@ of class templates</td><br>
> > <td><a href="<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#532">http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#532</a>">532</a></td><br>
> > <td>C++11</td><br>
> > <td>Member/nonmember operator template partial ordering</td><br>
> > - <td class="none" align="center">Unknown</td><br>
> > + <td class="svn" align="center">SVN</td><br>
> > </tr><br>
> > <tr id="533"><br>
> > <td><a href="<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#533">http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#533</a>">533</a></td><br>
> > @@ -5755,7 +5755,7 @@ and <I>POD class</I></td><br>
> > <td><a href="<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#990">http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#990</a>">990</a></td><br>
> > <td>CD2</td><br>
> > <td>Value initialization with multiple initializer-list constructors</td><br>
> > - <td class="none" align="center">Unknown</td><br>
> > + <td class="svn" align="center">SVN</td><br>
> > </tr><br>
> > <tr id="991"><br>
> > <td><a href="<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#991">http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#991</a>">991</a></td><br>
> > @@ -6235,7 +6235,7 @@ and <I>POD class</I></td><br>
> > <td><a href="<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1070">http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1070</a>">1070</a></td><br>
> > <td>C++11</td><br>
> > <td>Missing initializer clauses in aggregate initialization</td><br>
> > - <td class="none" align="center">Unknown</td><br>
> > + <td class="svn" align="center">SVN</td><br>
> > </tr><br>
> > <tr id="1071"><br>
> > <td><a href="<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1071">http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1071</a>">1071</a></td><br>
> ><br>
> ><br>
> > _______________________________________________<br>
> > cfe-commits mailing list<br>
> > <a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
> > <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</p>