hintonda updated this revision to Diff 51114. hintonda added a comment. Address additional comments.
Always maintain SeenFields, not just when designators are seen which simplies the logic. Note that there is no getNumFields() method, so we still need to determine the total FieldSize to initialize the BitVector and loop through it. http://reviews.llvm.org/D17407 Files: lib/Sema/SemaInit.cpp test/SemaCXX/cxx0x-initializer-constructor.cpp Index: test/SemaCXX/cxx0x-initializer-constructor.cpp =================================================================== --- test/SemaCXX/cxx0x-initializer-constructor.cpp +++ test/SemaCXX/cxx0x-initializer-constructor.cpp @@ -407,3 +407,34 @@ [0] = 1, [2] = 3 }; // expected-error {{ambiguous}} expected-note {{in implicit initialization of array element 1}} } + +namespace PR23514 { +struct Test { + int& a; + int& b; +}; + +int d = 0; +auto a = Test { .b = d, .a = d, }; + +struct S { // expected-note-re 2{{candidate constructor (the implicit {{.*}} constructor) not viable: requires 1 argument, but 0 were provided}} + S(int a) {} // expected-note {{candidate constructor not viable: requires single argument 'a', but no arguments were provided}} +}; + +struct P { + char i1; + char i2; + S s; +}; + +P p1 { .s = 2, .i1 = 1, 1, }; +P p2 { .s = 2, .i1 = 1, }; + +struct PP { + char i1; + S s1; + S s2; // expected-note {{in implicit initialization of field 's2' with omitted initializer}} +}; + +PP pp { .s1 = 2, .i1 = 1, }; // expected-error {{no matching constructor for initialization of 'PR23514::S'}} +} Index: lib/Sema/SemaInit.cpp =================================================================== --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -1814,6 +1814,14 @@ // worthwhile to skip over the rest of the initializer, though. RecordDecl *RD = DeclType->getAs<RecordType>()->getDecl(); RecordDecl::field_iterator FieldEnd = RD->field_end(); + RecordDecl::field_iterator FieldStart = Field; + unsigned FieldSize = [FieldStart, FieldEnd]() mutable -> unsigned { + unsigned i = 0; + for (; FieldStart != FieldEnd; ++FieldStart, ++i) + /*empty*/; + return i; + }(); + llvm::BitVector SeenFields(FieldSize); bool CheckForMissingFields = true; while (Index < IList->getNumInits()) { Expr *Init = IList->getInit(Index); @@ -1833,6 +1841,10 @@ true, TopLevelObject)) hadError = true; + if (!hadError) + SeenFields.set(Field == FieldEnd ? FieldSize - 1 + : Field->getFieldIndex() - 1); + InitializedSomething = true; // Disable check for missing fields when designators are used. @@ -1885,6 +1897,7 @@ StructuredList->setInitializedFieldInUnion(*Field); } + SeenFields.set(Field->getFieldIndex()); ++Field; } @@ -1904,12 +1917,16 @@ } } - // Check that any remaining fields can be value-initialized. - if (VerifyOnly && Field != FieldEnd && !DeclType->isUnionType() && - !Field->getType()->isIncompleteArrayType()) { - // FIXME: Should check for holes left by designated initializers too. - for (; Field != FieldEnd && !hadError; ++Field) { - if (!Field->isUnnamedBitfield() && !Field->hasInClassInitializer()) + // Check that any missing fields can be value-initialized. + if (VerifyOnly && !DeclType->isUnionType() && + (Field != FieldEnd || !CheckForMissingFields)) { + Field = FieldStart; + for (unsigned i = 0; i < FieldSize && !hadError; ++i, ++Field) { + assert(Field != FieldEnd); + if (SeenFields[i]) + continue; + if (!Field->isUnnamedBitfield() && !Field->hasInClassInitializer() && + !Field->getType()->isIncompleteArrayType()) CheckEmptyInitializable( InitializedEntity::InitializeMember(*Field, &Entity), IList->getLocEnd());
Index: test/SemaCXX/cxx0x-initializer-constructor.cpp =================================================================== --- test/SemaCXX/cxx0x-initializer-constructor.cpp +++ test/SemaCXX/cxx0x-initializer-constructor.cpp @@ -407,3 +407,34 @@ [0] = 1, [2] = 3 }; // expected-error {{ambiguous}} expected-note {{in implicit initialization of array element 1}} } + +namespace PR23514 { +struct Test { + int& a; + int& b; +}; + +int d = 0; +auto a = Test { .b = d, .a = d, }; + +struct S { // expected-note-re 2{{candidate constructor (the implicit {{.*}} constructor) not viable: requires 1 argument, but 0 were provided}} + S(int a) {} // expected-note {{candidate constructor not viable: requires single argument 'a', but no arguments were provided}} +}; + +struct P { + char i1; + char i2; + S s; +}; + +P p1 { .s = 2, .i1 = 1, 1, }; +P p2 { .s = 2, .i1 = 1, }; + +struct PP { + char i1; + S s1; + S s2; // expected-note {{in implicit initialization of field 's2' with omitted initializer}} +}; + +PP pp { .s1 = 2, .i1 = 1, }; // expected-error {{no matching constructor for initialization of 'PR23514::S'}} +} Index: lib/Sema/SemaInit.cpp =================================================================== --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -1814,6 +1814,14 @@ // worthwhile to skip over the rest of the initializer, though. RecordDecl *RD = DeclType->getAs<RecordType>()->getDecl(); RecordDecl::field_iterator FieldEnd = RD->field_end(); + RecordDecl::field_iterator FieldStart = Field; + unsigned FieldSize = [FieldStart, FieldEnd]() mutable -> unsigned { + unsigned i = 0; + for (; FieldStart != FieldEnd; ++FieldStart, ++i) + /*empty*/; + return i; + }(); + llvm::BitVector SeenFields(FieldSize); bool CheckForMissingFields = true; while (Index < IList->getNumInits()) { Expr *Init = IList->getInit(Index); @@ -1833,6 +1841,10 @@ true, TopLevelObject)) hadError = true; + if (!hadError) + SeenFields.set(Field == FieldEnd ? FieldSize - 1 + : Field->getFieldIndex() - 1); + InitializedSomething = true; // Disable check for missing fields when designators are used. @@ -1885,6 +1897,7 @@ StructuredList->setInitializedFieldInUnion(*Field); } + SeenFields.set(Field->getFieldIndex()); ++Field; } @@ -1904,12 +1917,16 @@ } } - // Check that any remaining fields can be value-initialized. - if (VerifyOnly && Field != FieldEnd && !DeclType->isUnionType() && - !Field->getType()->isIncompleteArrayType()) { - // FIXME: Should check for holes left by designated initializers too. - for (; Field != FieldEnd && !hadError; ++Field) { - if (!Field->isUnnamedBitfield() && !Field->hasInClassInitializer()) + // Check that any missing fields can be value-initialized. + if (VerifyOnly && !DeclType->isUnionType() && + (Field != FieldEnd || !CheckForMissingFields)) { + Field = FieldStart; + for (unsigned i = 0; i < FieldSize && !hadError; ++i, ++Field) { + assert(Field != FieldEnd); + if (SeenFields[i]) + continue; + if (!Field->isUnnamedBitfield() && !Field->hasInClassInitializer() && + !Field->getType()->isIncompleteArrayType()) CheckEmptyInitializable( InitializedEntity::InitializeMember(*Field, &Entity), IList->getLocEnd());
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits