hintonda updated this revision to Diff 51099.
hintonda added a comment.
Addressed comments.
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
@@ -1812,6 +1812,10 @@
// anything except look at designated initializers; That's okay,
// because an error should get printed out elsewhere. It might be
// worthwhile to skip over the rest of the initializer, though.
+ unsigned FieldIdx = 0;
+ unsigned MaxFieldIdx = 0;
+ llvm::BitVector SeenFields;
+ RecordDecl::field_iterator FieldStart = Field;
RecordDecl *RD = DeclType->getAs<RecordType>()->getDecl();
RecordDecl::field_iterator FieldEnd = RD->field_end();
bool CheckForMissingFields = true;
@@ -1833,6 +1837,26 @@
true, TopLevelObject))
hadError = true;
+ if (!hadError) {
+ if (CheckForMissingFields) {
+ unsigned FieldSize{0};
+ for (RecordDecl::field_iterator f = FieldStart; f != FieldEnd; ++f) {
+ FieldSize++;
+ }
+ MaxFieldIdx = FieldSize - 1;
+ SeenFields.resize(FieldSize);
+ for (unsigned i = 0; i < FieldIdx; ++i)
+ SeenFields.set(i);
+ }
+ if (Field == FieldEnd) {
+ FieldIdx = MaxFieldIdx;
+ } else {
+ FieldIdx = Field->getFieldIndex() - 1;
+ }
+ SeenFields.set(FieldIdx);
+ ++FieldIdx;
+ }
+
InitializedSomething = true;
// Disable check for missing fields when designators are used.
@@ -1856,6 +1880,7 @@
if (Field->isUnnamedBitfield()) {
// Don't initialize unnamed bitfields, e.g. "int : 20;"
+ ++FieldIdx;
++Field;
continue;
}
@@ -1885,6 +1910,9 @@
StructuredList->setInitializedFieldInUnion(*Field);
}
+ if (!CheckForMissingFields && !hadError)
+ SeenFields.set(FieldIdx);
+ ++FieldIdx;
++Field;
}
@@ -1904,15 +1932,37 @@
}
}
- // 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())
- CheckEmptyInitializable(
- InitializedEntity::InitializeMember(*Field, &Entity),
- IList->getLocEnd());
+ if (!hadError) {
+ SmallVector<RecordDecl::field_iterator, 10> MissingFields;
+ if (CheckForMissingFields) {
+ FieldStart = Field;
+ } else {
+ for (int Idx = 0, SeenIdx = SeenFields.find_first(); SeenIdx != -1;
+ SeenIdx = SeenFields.find_next(SeenIdx)) {
+ while (Idx < SeenIdx) {
+ MissingFields.push_back(FieldStart);
+ ++FieldStart;
+ ++Idx;
+ }
+ ++FieldStart;
+ ++Idx;
+ }
+ }
+ while (FieldStart != FieldEnd) {
+ MissingFields.push_back(FieldStart);
+ ++FieldStart;
+ }
+
+ // Check that any remaining fields can be value-initialized.
+ if (VerifyOnly && MissingFields.size() && !DeclType->isUnionType()) {
+ for (auto MissedField : MissingFields) {
+ Field = MissedField;
+ if (!Field->isUnnamedBitfield() && !Field->hasInClassInitializer() &&
+ !Field->getType()->isIncompleteArrayType())
+ CheckEmptyInitializable(
+ InitializedEntity::InitializeMember(*Field, &Entity),
+ IList->getLocEnd());
+ }
}
}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits