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