[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