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

Don Hinton via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 22 00:32:45 PDT 2019


hintonda updated this revision to Diff 191828.
hintonda added a comment.
Herald added a subscriber: jdoerfert.
Herald added a project: clang.

- Initial checkin from original D17407 <https://reviews.llvm.org/D17407>.
- Refactored code and simplify tests based on review comments.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D17407/new/

https://reviews.llvm.org/D17407

Files:
  clang/lib/Sema/SemaInit.cpp
  clang/test/SemaCXX/cxx0x-initializer-constructor.cpp


Index: clang/test/SemaCXX/cxx0x-initializer-constructor.cpp
===================================================================
--- clang/test/SemaCXX/cxx0x-initializer-constructor.cpp
+++ clang/test/SemaCXX/cxx0x-initializer-constructor.cpp
@@ -409,3 +409,21 @@
     [0] = 1, [2] = 3
   }; // expected-error {{ambiguous}} expected-note {{in implicit initialization of array element 1}}
 }
+
+namespace PR23514 {
+struct Q {  // expected-note-re 4{{candidate constructor (the implicit {{(copy|move)}} constructor) not viable: requires 1 argument, but 0 were provided}}
+  Q(int) {} // expected-note 2{{candidate constructor not viable: requires 1 argument, but 0 were provided}}
+};
+struct A {
+  Q x, y; // expected-note 2{{in implicit initialization of field 'x' with omitted initializer}}
+};
+struct B {
+  int i;
+  A a;
+  int k;
+};
+B w = {.a.y = 0, 0, .a.x = 10};
+B x = {.a.y = 0, 0}; // expected-error {{no matching constructor for initialization of 'PR23514::Q'}}
+B y = {.a = {.y = 0, .x = 0}, 0};
+B z = {.a = {.y = 0}, 0}; // expected-error {{no matching constructor for initialization of 'PR23514::Q'}}
+} // namespace PR23514
Index: clang/lib/Sema/SemaInit.cpp
===================================================================
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -2000,6 +2000,9 @@
     !IList->isIdiomaticZeroInitializer(SemaRef.getLangOpts());
   bool HasDesignatedInit = false;
 
+  unsigned FieldSize = std::distance(RD->field_begin(), RD->field_end());
+  llvm::BitVector SeenFields(FieldSize);
+
   while (Index < IList->getNumInits()) {
     Expr *Init = IList->getInit(Index);
     SourceLocation InitLoc = Init->getBeginLoc();
@@ -2032,6 +2035,10 @@
         }
       }
 
+      if (!hadError)
+        SeenFields.set(Field == FieldEnd ? FieldSize - 1
+                                         : Field->getFieldIndex() - 1);
+
       InitializedSomething = true;
 
       // Disable check for missing fields when designators are used.
@@ -2045,6 +2052,8 @@
       break;
     }
 
+    SeenFields.set(Field->getFieldIndex());
+
     // We've already initialized a member of a union. We're done.
     if (InitializedSomething && DeclType->isUnionType())
       break;
@@ -2111,12 +2120,15 @@
     }
   }
 
-  // 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 unseen fields can be value-initialized.
+  if (VerifyOnly && TopLevelObject && !DeclType->isUnionType() &&
+      (Field != FieldEnd || HasDesignatedInit)) {
+    Field = RD->field_begin();
+    for (unsigned i = 0; i < FieldSize && !hadError; ++i, ++Field) {
+      if (SeenFields[i])
+        continue;
+      if(!Field->isUnnamedBitfield() && !Field->hasInClassInitializer() &&
+          !Field->getType()->isIncompleteArrayType())
         CheckEmptyInitializable(
             InitializedEntity::InitializeMember(*Field, &Entity),
             IList->getEndLoc());


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D17407.191828.patch
Type: text/x-patch
Size: 3248 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190322/f3a78f13/attachment.bin>


More information about the cfe-commits mailing list