[PATCH] D17407: [Sema] PR25755 Fix crash when initializing out-of-order struct references

don hinton via cfe-commits cfe-commits at lists.llvm.org
Sat Mar 19 09:32:56 PDT 2016


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());


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D17407.51114.patch
Type: text/x-patch
Size: 3461 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160319/24b22584/attachment.bin>


More information about the cfe-commits mailing list