Skip to content

Commit 965cc90

Browse files
authored
Merge pull request #7161 from apple/out-of-order-init
[Clang] Fix crash when emitting diagnostic for out of order designated initializers in C++
2 parents cb96a4a + 15362c9 commit 965cc90

File tree

3 files changed

+49
-2
lines changed

3 files changed

+49
-2
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,9 @@ Bug Fixes
274274
- Fix assert that fails when the expression causing the this pointer to be
275275
captured by a block is part of a constexpr if statement's branch and
276276
instantiation of the enclosing method causes the branch to be discarded.
277+
- Fix crash when emitting diagnostic for out of order designated initializers
278+
in C++.
279+
(`#63605 <https://github.com/llvm/llvm-project/issues/63605>`_)
277280

278281
Improvements to Clang's diagnostics
279282
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaInit.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2712,7 +2712,7 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
27122712
SemaRef.Diag(DIE->getBeginLoc(), diag::ext_designated_init_reordered)
27132713
<< KnownField << PrevField << DIE->getSourceRange();
27142714

2715-
unsigned OldIndex = NumBases + PrevField->getFieldIndex();
2715+
unsigned OldIndex = StructuredIndex - 1;
27162716
if (StructuredList && OldIndex <= StructuredList->getNumInits()) {
27172717
if (Expr *PrevInit = StructuredList->getInit(OldIndex)) {
27182718
SemaRef.Diag(PrevInit->getBeginLoc(),
@@ -2816,8 +2816,12 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
28162816
// If this the first designator, our caller will continue checking
28172817
// the rest of this struct/class/union subobject.
28182818
if (IsFirstDesignator) {
2819+
if (Field != RT->getDecl()->field_end() && Field->isUnnamedBitfield())
2820+
++Field;
2821+
28192822
if (NextField)
28202823
*NextField = Field;
2824+
28212825
StructuredIndex = FieldIndex;
28222826
return false;
28232827
}

clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ C c = {
6363
.x = 1, // override-note {{previous}}
6464
.x = 1, // override-error {{overrides prior initialization}} override-note {{previous}}
6565
.y = 1, // override-note {{previous}}
66-
.y = 1, // override-error {{overrides prior initialization}}
66+
.y = 1, // override-error {{overrides prior initialization}} // reorder-note {{previous initialization for field 'y' is here}}
6767
.x = 1, // reorder-error {{declaration order}} override-error {{overrides prior initialization}} override-note {{previous}}
6868
.x = 1, // override-error {{overrides prior initialization}}
6969
};
@@ -156,3 +156,43 @@ namespace deduction {
156156
j3<D, E>({}); // ok, selects E overload by SFINAE (too many braces for D)
157157
}
158158
}
159+
160+
namespace GH63605 {
161+
struct A {
162+
unsigned x;
163+
unsigned y;
164+
unsigned z;
165+
};
166+
167+
struct B {
168+
unsigned a;
169+
unsigned b;
170+
};
171+
172+
struct : public A, public B {
173+
unsigned : 2;
174+
unsigned a : 6;
175+
unsigned : 1;
176+
unsigned b : 6;
177+
unsigned : 2;
178+
unsigned c : 6;
179+
unsigned d : 1;
180+
unsigned e : 2;
181+
} data = {
182+
{.z=0,
183+
// pedantic-note@-1 {{first non-designated initializer is here}}
184+
// reorder-note@-2 {{previous initialization for field 'z' is here}}
185+
.y=1, // reorder-error {{field 'z' will be initialized after field 'y'}}
186+
// reorder-note@-1 {{previous initialization for field 'y' is here}}
187+
.x=2}, // reorder-error {{field 'y' will be initialized after field 'x'}}
188+
{.b=3, // reorder-note {{previous initialization for field 'b' is here}}
189+
.a=4}, // reorder-error {{field 'b' will be initialized after field 'a'}}
190+
.e = 1, // reorder-note {{previous initialization for field 'e' is here}}
191+
// pedantic-error@-1 {{mixture of designated and non-designated initializers in the same initializer list is a C99 extension}}
192+
.d = 1, // reorder-error {{field 'e' will be initialized after field 'd'}}
193+
// reorder-note@-1 {{previous initialization for field 'd' is here}}
194+
.c = 1, // reorder-error {{field 'd' will be initialized after field 'c'}} // reorder-note {{previous initialization for field 'c' is here}}
195+
.b = 1, // reorder-error {{field 'c' will be initialized after field 'b'}} // reorder-note {{previous initialization for field 'b' is here}}
196+
.a = 1, // reorder-error {{field 'b' will be initialized after field 'a'}}
197+
};
198+
}

0 commit comments

Comments
 (0)