On Mon, Jan 26, 2015 at 11:31 AM, Richard Smith <[email protected]> wrote:
> On Sat, Jan 24, 2015 at 3:09 PM, Larisse Voufo <[email protected]> wrote: > > Author: lvoufo > > Date: Sat Jan 24 17:09:54 2015 > > New Revision: 227022 > > > > URL: http://llvm.org/viewvc/llvm-project?rev=227022&view=rev > > Log: > > First steps in implementing DR1467: List-initialization of aggregate > from same-type object. > > Only the first two items for now, changing Sections 8.5.4 > [dcl.init.list] paragraph 3 and 13.3.1.7 [over.match.list] paragraph 1, > > so that defining class objects and character arrays using uniform > initialization syntax is actually treated as list initialization > > and before it is treated aggregate initialization. > > > > Modified: > > cfe/trunk/lib/Sema/SemaInit.cpp > > cfe/trunk/test/CXX/drs/dr14xx.cpp > > > > Modified: cfe/trunk/lib/Sema/SemaInit.cpp > > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=227022&r1=227021&r2=227022&view=diff > > > ============================================================================== > > --- cfe/trunk/lib/Sema/SemaInit.cpp (original) > > +++ cfe/trunk/lib/Sema/SemaInit.cpp Sat Jan 24 17:09:54 2015 > > @@ -3222,9 +3222,16 @@ static void TryConstructorInitialization > > OverloadCandidateSet::iterator Best; > > bool AsInitializerList = false; > > > > + // C++14 DR 1467 [over.match.list]p1: > > + // When objects of non-aggregate type T are list-initialized, such > that > > + // 8.5.4 [dcl.init.list] specifies that overload resolution is > performed > > + // according to the rules in this section, overload resolution > selects > > + // the constructor in two phases: > > + // > > // C++11 [over.match.list]p1: > > // When objects of non-aggregate type T are list-initialized, > overload > > // resolution selects the constructor in two phases: > > + // > > // - Initially, the candidate functions are the initializer-list > > // constructors of the class T and the argument list consists of > the > > // initializer list as a single argument. > > @@ -3425,42 +3432,88 @@ static void TryListInitialization(Sema & > > TryReferenceListInitialization(S, Entity, Kind, InitList, Sequence); > > return; > > } > > - if (DestType->isRecordType()) { > > - if (S.RequireCompleteType(InitList->getLocStart(), DestType, 0)) { > > - Sequence.setIncompleteTypeFailure(DestType); > > - return; > > - } > > > > - // C++11 [dcl.init.list]p3: > > - // - If T is an aggregate, aggregate initialization is performed. > > - if (!DestType->isAggregateType()) { > > - if (S.getLangOpts().CPlusPlus11) { > > - // - Otherwise, if the initializer list has no elements and T > is a > > - // class type with a default constructor, the object is > > - // value-initialized. > > - if (InitList->getNumInits() == 0) { > > - CXXRecordDecl *RD = DestType->getAsCXXRecordDecl(); > > - if (RD->hasDefaultConstructor()) { > > - TryValueInitialization(S, Entity, Kind, Sequence, InitList); > > - return; > > - } > > - } > > - > > - // - Otherwise, if T is a specialization of > std::initializer_list<E>, > > - // an initializer_list object constructed [...] > > - if (TryInitializerListConstruction(S, InitList, DestType, > Sequence)) > > - return; > > + if (DestType->isRecordType() && > > + S.RequireCompleteType(InitList->getLocStart(), DestType, 0)) { > > + Sequence.setIncompleteTypeFailure(DestType); > > + return; > > + } > > > > - // - Otherwise, if T is a class type, constructors are > considered. > > + // C++14 DR1467 [dcl.init.list]p3: > > + // - If T is a class type and the initializer list has a single > element of > > + // type cv U, where U is T or a class derived from T, the object is > > + // initialized from that element (by copy-initialization for > > + // copy-list-initialization, or by direct-initialization for > > + // direct-list-initialization). > > + // - Otherwise, if T is a character array and the initializer list > has a > > + // single element that is an appropriately-typed string literal > > + // (8.5.2 [dcl.init.string]), initialization is performed as > described > > + // in that section. > > + // - Otherwise, If T is an aggregate, [...] (continue below). > > + if (S.getLangOpts().CPlusPlus14 && InitList->getNumInits() == 1) { > > This issue is in DR status, so should be applied retroactively to all > standard revisions where it makes sense. In this case, that means it > should apply to C++11 mode as well as C++14 mode. > Ok. > > > + if (DestType->isRecordType()) { > > + QualType InitType = InitList->getInit(0)->getType(); > > + if (S.Context.hasSameUnqualifiedType(InitType, DestType) || > > + S.IsDerivedFrom(InitType, DestType)) { > > Expr *InitListAsExpr = InitList; > > TryConstructorInitialization(S, Entity, Kind, InitListAsExpr, > DestType, > > Sequence, /*InitListSyntax*/true); > > - } else > > - Sequence.SetFailed( > > - InitializationSequence::FK_InitListBadDestinationType); > > - return; > > + return; > > + } > > + } > > + if (const ArrayType *DestAT = S.Context.getAsArrayType(DestType)) { > > + Expr *SubInit[1] = {InitList->getInit(0)}; > > + if (!isa<VariableArrayType>(DestAT) && > > + IsStringInit(SubInit[0], DestAT, S.Context) == SIF_None) { > > + InitializationKind SubKind = > > + Kind.getKind() == InitializationKind::IK_DirectList > > + ? InitializationKind::CreateDirect(Kind.getLocation(), > > + > InitList->getLBraceLoc(), > > + > InitList->getRBraceLoc()) > > + : Kind; > > + Sequence.InitializeFrom(S, Entity, SubKind, SubInit, > > + /*TopLevelOfInitList*/ true); > > + > > + // TryStringLiteralInitialization() (in InitializeFrom()) will > fail if > > + // the element is not an appropriately-typed string literal, in > which > > + // case we should proceed as in C++11 (below). > > + if (Sequence) { > > + Sequence.RewrapReferenceInitList(Entity.getType(), InitList); > > + return; > > + } > > + } > > } > > } > > + > > + // C++11 [dcl.init.list]p3: > > + // - If T is an aggregate, aggregate initialization is performed. > > + if (DestType->isRecordType() && !DestType->isAggregateType()) { > > + if (S.getLangOpts().CPlusPlus11) { > > + // - Otherwise, if the initializer list has no elements and T > is a > > + // class type with a default constructor, the object is > > + // value-initialized. > > + if (InitList->getNumInits() == 0) { > > + CXXRecordDecl *RD = DestType->getAsCXXRecordDecl(); > > + if (RD->hasDefaultConstructor()) { > > + TryValueInitialization(S, Entity, Kind, Sequence, InitList); > > + return; > > + } > > + } > > + > > + // - Otherwise, if T is a specialization of > std::initializer_list<E>, > > + // an initializer_list object constructed [...] > > + if (TryInitializerListConstruction(S, InitList, DestType, > Sequence)) > > + return; > > + > > + // - Otherwise, if T is a class type, constructors are > considered. > > + Expr *InitListAsExpr = InitList; > > + TryConstructorInitialization(S, Entity, Kind, InitListAsExpr, > DestType, > > + Sequence, /*InitListSyntax*/ true); > > + } else > > + > Sequence.SetFailed(InitializationSequence::FK_InitListBadDestinationType); > > + return; > > + } > > + > > if (S.getLangOpts().CPlusPlus && !DestType->isAggregateType() && > > InitList->getNumInits() == 1 && > > InitList->getInit(0)->getType()->isRecordType()) { > > @@ -3469,6 +3522,14 @@ static void TryListInitialization(Sema & > > // initialized from that element; if a narrowing conversion is > required > > // to convert the element to T, the program is ill-formed. > > // > > + // C++14 DR1467: > > + // - Otherwise, if the initializer list has a single element of > type E > > + // [...references are handled above...], the object or > reference is > > + // initialized from that element (by copy-initialization for > > + // copy-list-initialization, or by direct-initialization for > > + // direct-list-initialization); if a narrowing conversion is > required > > + // to convert the element to T, the program is ill-formed. > > + // > > // Per core-24034, this is direct-initialization if we were > performing > > // direct-list-initialization and copy-initialization otherwise. > > // We can't use InitListChecker for this, because it always performs > > @@ -4408,8 +4469,7 @@ static void checkIndirectCopyRestoreSour > > > > /// \brief Determine whether we have compatible array types for the > > /// purposes of GNU by-copy array initialization. > > -static bool hasCompatibleArrayTypes(ASTContext &Context, > > - const ArrayType *Dest, > > +static bool hasCompatibleArrayTypes(ASTContext &Context, const > ArrayType *Dest, > > const ArrayType *Source) { > > // If the source and destination array types are equivalent, we're > > // done. > > @@ -4668,7 +4728,7 @@ void InitializationSequence::InitializeF > > return; > > } > > > > - // Determine whether we should consider writeback conversions for > > + // Determine whether we should consider writeback conversions for > > // Objective-C ARC. > > bool allowObjCWritebackConversion = S.getLangOpts().ObjCAutoRefCount > && > > Entity.isParameterKind(); > > > > Modified: cfe/trunk/test/CXX/drs/dr14xx.cpp > > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr14xx.cpp?rev=227022&r1=227021&r2=227022&view=diff > > > ============================================================================== > > --- cfe/trunk/test/CXX/drs/dr14xx.cpp (original) > > +++ cfe/trunk/test/CXX/drs/dr14xx.cpp Sat Jan 24 17:09:54 2015 > > @@ -195,3 +195,126 @@ namespace dr1460 { // dr1460: 3.5 > > } > > #endif > > } > > + > > +#if __cplusplus >= 201103L > > +namespace std { > > + typedef decltype(sizeof(int)) size_t; > > + > > + // libc++'s implementation > > + template <class _E> > > + class initializer_list > > + { > > + const _E* __begin_; > > + size_t __size_; > > + > > + initializer_list(const _E* __b, size_t __s) > > + : __begin_(__b), > > + __size_(__s) > > + {} > > + > > + public: > > + typedef _E value_type; > > + typedef const _E& reference; > > + typedef const _E& const_reference; > > + typedef size_t size_type; > > + > > + typedef const _E* iterator; > > + typedef const _E* const_iterator; > > + > > + initializer_list() : __begin_(nullptr), __size_(0) {} > > + > > + size_t size() const {return __size_;} > > + const _E* begin() const {return __begin_;} > > + const _E* end() const {return __begin_ + __size_;} > > + }; > > +} // std > > Please put this at the top of the file. > > > + > > +namespace dr1467 { > > This should be marked as " // dr1467: partial c++11" to indicate that > we have partial support for this in trunk, for C++11 onwards. We have > a script (www/make_cxx_dr_status) that automatically generates the > cxx_dr_status page from these comments. > Ok. > > > + // List-initialization of aggregate from same-type object > > + > > + namespace basic0 { > > + > > + struct S { > > + int i = 42; > > + }; > > + > > + S a; > > + S b(a); > > + S c{a}; > > + > > + struct SS : public S { } x; > > + S y(x); > > + S z{x}; > > + > > + } // basic0 > > + > > + namespace basic1 { > > + > > + struct S { > > + int i{42}; > > + }; > > + > > + S a; > > + S b(a); > > + S c{a}; > > + > > + struct SS : public S { } x; > > + S y(x); > > + S z{x}; > > + > > + } // basic1 > > + > > + namespace basic2 { > > + > > + struct S { > > + int i = {42}; > > + }; > > + > > + S a; > > + S b(a); > > + S c{a}; > > + > > + struct SS : public S { } x; > > + S y(x); > > + S z{x}; > > + > > + } // basic2 > > + > > + namespace dr_example { > > + struct OK { > > + OK() = default; > > + OK(const OK&) = default; > > + OK(int) { } > > + }; > > + > > + OK ok; > > + OK ok2{ok}; > > + > > + > > + struct X { > > + X() = default; > > + X(const X&) = default; > > + }; > > + > > + X x; > > + X x2{x}; > > +#if __cplusplus == 201103L > > + // expected-error@-2 {{excess elements in struct initializer}} > > +#endif > > + > > + // TODO: Only Items 1 and 2 from DR1467 are covered for now. > > + // Implement remaining items, and expand here as necessary. > > + > > + } // dr_example > > + > > +} // dr1467 > > + > > + > > +namespace dr1490 { > > This should be marked "// dr1490: dup 1467". > > > + // List-initialization from a string literal > > + > > + char s[4]{"abc"}; // Ok > > + std::initializer_list<char>{"abc"}; // expected-error {{expected > unqualified-id}}} > > + > > +} // dr1490 > > +#endif > > Can you add tests for dr1756, 1758, 1631 and 1589 (all resolved by > 1467) too, please? > I am still working on these cases. This patch does not handle those yet.
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
