r210091 - Implement DR990 and DR1070. Aggregate initialization initializes uninitialized
Nico Weber
thakis at chromium.org
Wed Jul 2 16:59:36 PDT 2014
All done, and landed in r212238. Thanks!
On Wed, Jul 2, 2014 at 4:32 PM, Richard Smith <richard at metafoo.co.uk> wrote:
> On Wed, Jul 2, 2014 at 2:04 PM, Nico Weber <thakis at chromium.org> wrote:
>
>> On Mon, Jun 30, 2014 at 11:22 AM, Nico Weber <thakis at chromium.org> wrote:
>>
>>> On Fri, Jun 27, 2014 at 12:56 PM, Richard Smith <richard at metafoo.co.uk>
>>> wrote:
>>>
>>>> On Fri, Jun 27, 2014 at 12:33 PM, Nico Weber <thakis at chromium.org>
>>>> wrote:
>>>>
>>>>> I played with this some. The simplest thing is to use the C++03 logic
>>>>> in system headers, but then system headers will always stay broken. Then I
>>>>> tried only falling back to C++03 for known containers like you suggest –
>>>>> this turned out to be fairly ugly, since libstdc++ put them in
>>>>> std::__debug, stlport in std:: (but it doesn't really have a predictable
>>>>> namespace; depending on defines it uses one out of several possible names
>>>>> for its namespace), and there's a bunch of containers.
>>>>>
>>>>> I've now arrived at falling back to 03 logic only for the constructor
>>>>> failure, but with a warning (which is suppressed in system headers by
>>>>> default, but is visible when building with -Wsystem-headers), this seems
>>>>> like the least bad approach to me. The attached patch implements this. Do
>>>>> you think this is ok?
>>>>>
>>>>
>>>> The standard library has classes with explicit default constructors
>>>> that are not covered by LWG2193 (throughout iostreams and in regex's
>>>> match_result). This workaround shouldn't apply to them, or else this could
>>>> do the wrong thing in a SFINAE context or send overload resolution the
>>>> wrong way. So that brings us back to having a list.
>>>>
>>>
>>> Great point, as usual, thanks.
>>>
>>>
>>>> Is this std::__debug an inline namespace? (Even if not, it shouldn't
>>>> be difficult to walk out of it and find if we're in 'std'.)
>>>>
>>>> Please add a note to the diagnostic indicating where the constructor
>>>> was used.
>>>>
>>>
>>> Done.
>>>
>>> Updated patch attached, as promised it's uglier :-) I added a few more
>>> changes to limit this more: It now checks if the ctor has 0 required
>>> arguments, and that it's explicit. (Is isExplicitSpecified() or
>>> isExplicit() the right call for this?)
>>>
>>
>> Is this ok?
>>
>
> isExplicit is the right thing to check (although in this case they should
> always return the same value in practice).
>
>
> + // libstdc++4.6 marks the vector default constructor as explicit in
> + // _GLIBCXX_DEBUG mode, so recover using the C++03 logic in that case.
> + // stlport does so too. Look for std::__debug for libstdc++, and for
> + // std:: for stlport.
>
> Please mention that we're effectively implementing LWG2193 here.
>
>
> + R->getDeclName().isIdentifier() &&
>
> I think this should be just 'R->getDeclName()'. isIdentifier will always
> return true here (even if the class is unnamed).
>
>
> + bool IsStd = ND &&
> SemaRef.getStdNamespace()->InEnclosingNamespaceSetOf(ND);
> + bool IsStdDebug = ND && NND && ND->getName() == "__debug" &&
> + SemaRef.getStdNamespace()->InEnclosingNamespaceSetOf(NND);
>
> I don't particularly like hard-coding this knowledge of __debug. Maybe
> instead loop up to the outermost namespace and check whether that's 'std'?
> You've already done the 'isInSystemHeader' check, so this should be
> uncommon.
>
>
> + StringRef N = R->getName();
> + if ((IsStd || IsStdDebug) && (
> + N == "basic_string" || N == "deque" || N == "forward_list" ||
> + N == "list" || N == "map" || N == "multimap" || N == "multiset"
> ||
> + N == "priority_queue" || N == "queue" || N == "set" ||
> + N == "stack" || N == "unordered_map" || N == "unordered_set" ||
> + N == "vector")) {
>
> Please use a StringSwitch for this.
>
> Otherwise, the direction looks fine here. Feel free to commit with the
> above things fixed.
>
> On Thu, Jun 26, 2014 at 2:13 PM, Richard Smith <richard at metafoo.co.uk>
>>>> wrote:
>>>>
>>>>> Either that, or detect an explicit default constructor for standard
>>>>>> library containers and pretend they're not explicit.
>>>>>> On 26 Jun 2014 21:25, "Nico Weber" <thakis at chromium.org> wrote:
>>>>>>
>>>>>>> On Mon, Jun 23, 2014 at 6:08 PM, Nico Weber <thakis at chromium.org>
>>>>>>> wrote:
>>>>>>>
>>>>>>>> On Thu, Jun 5, 2014 at 9:23 AM, Nico Weber <thakis at chromium.org>
>>>>>>>> wrote:
>>>>>>>>
>>>>>>>>> On Thu, Jun 5, 2014 at 1:49 AM, Richard Smith <
>>>>>>>>> richard at metafoo.co.uk> wrote:
>>>>>>>>>
>>>>>>>>>> On Wed, Jun 4, 2014 at 9:54 AM, Evgeniy Stepanov <
>>>>>>>>>> eugeni.stepanov at gmail.com> 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).
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> It's a C++ standard library that's available in the Android NDK.
>>>>>>>>> The other two standard libraries in there are libstdc++ (which some people
>>>>>>>>> don't like using due to license reasons) and libc++ (which is great, but
>>>>>>>>> we've only got all tests to pass this week, so it's not really usable in a
>>>>>>>>> released NDK). So it's reasonably popular for NDK apps – chromium/android
>>>>>>>>> uses it for example. So it'd be nice to have some short-term workaround.
>>>>>>>>>
>>>>>>>>
>>>>>>>> Apparently, this also breaks our linux builds with libstdc++4.6.
>>>>>>>>
>>>>>>>
>>>>>>> In particular, this doesn't build after this patch:
>>>>>>>
>>>>>>> $ cat test.cc
>>>>>>> #include <vector>
>>>>>>> struct { int a, b; std::vector<int> c; } e[] = { {1, 1}, {2, 2} };
>>>>>>> $ ~/src/llvm-cmake/bin/clang -c test.cc -std=c++11
>>>>>>> -D_GLIBCXX_DEBUG=1
>>>>>>> test.cc:3:55: error: chosen constructor is explicit in
>>>>>>> copy-initialization
>>>>>>> struct { int a, b; std::vector<int> c; } e[] = { {1, 1}, {2, 2} };
>>>>>>> ^
>>>>>>> /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../include/c++/4.6/debug/vector:77:7:
>>>>>>> note: constructor declared here
>>>>>>> vector(const _Allocator& __a = _Allocator())
>>>>>>> ^
>>>>>>> test.cc:3:37: note: in implicit initialization of field 'c' with
>>>>>>> omitted initializer
>>>>>>> struct { int a, b; std::vector<int> c; } e[] = { {1, 1}, {2, 2} };
>>>>>>> ^
>>>>>>>
>>>>>>> It builds fine with gcc, clang before this revision, or clang
>>>>>>> without -D_GLIBCXX_DEBUG=1. Allowing this in system headers might be an
>>>>>>> acceptable workaround?
>>>>>>>
>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>> (https://code.google.com/p/chromium/issues/detail?id=381053 –
>>>>>>>>> sounds like there are no great client-side workarounds.)
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>> On Wed, Jun 4, 2014 at 8:47 PM, Richard Smith <
>>>>>>>>>>> richard at metafoo.co.uk> wrote:
>>>>>>>>>>> > On 4 Jun 2014 05:07, "Evgeniy Stepanov" <
>>>>>>>>>>> eugeni.stepanov at gmail.com> 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
>>>>>>>>>>> >> <richard-llvm at metafoo.co.uk> 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
>>>>>>>>>>> >> > cfe-commits at cs.uiuc.edu
>>>>>>>>>>> >> > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> _______________________________________________
>>>>>>>>>> cfe-commits mailing list
>>>>>>>>>> cfe-commits at cs.uiuc.edu
>>>>>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>
>>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140702/fe086c94/attachment.html>
More information about the cfe-commits
mailing list