Skip to content

Commit b6658b1

Browse files
committed
fix reordering in derived records, add tests
1 parent 322f1de commit b6658b1

File tree

2 files changed

+63
-2
lines changed

2 files changed

+63
-2
lines changed

clang/lib/Sema/SemaInit.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3136,9 +3136,14 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
31363136
SourceManager &SM = SemaRef.getSourceManager();
31373137
const LangOptions &LangOpts = SemaRef.getLangOpts();
31383138

3139+
// if Record is derived, then the first n base-classes are
3140+
// initialized first, they cannot be initialized with designated
3141+
// init, so skip them
3142+
const auto IListInits =
3143+
IList->inits().drop_front(CxxRecord->getNumBases());
31393144
// loop over each existing expression and apply replacement
31403145
for (const auto &[OrigExpr, Repl] :
3141-
llvm::zip(IList->inits(), ReorderedInitExprs)) {
3146+
llvm::zip(IListInits, ReorderedInitExprs)) {
31423147
CharSourceRange CharRange = CharSourceRange::getTokenRange(
31433148
Repl.InitExpr->getSourceRange());
31443149
const auto InitText =

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

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
// RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected -Wno-c99-designator -Wno-reorder-init-list -Wno-initializer-overrides
77
// RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected,wmissing,wmissing-designated -Wmissing-field-initializers -Wno-c99-designator -Wno-reorder-init-list -Wno-initializer-overrides
88
// RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected,wmissing -Wmissing-field-initializers -Wno-missing-designated-field-initializers -Wno-c99-designator -Wno-reorder-init-list -Wno-initializer-overrides
9-
9+
// RUN: %clang_cc1 -std=c++20 %s -Wreorder-init-list -fdiagnostics-parseable-fixits 2>&1 | FileCheck %s
1010

1111
namespace class_with_ctor {
1212
struct A { // cxx20-note 6{{candidate}}
@@ -38,6 +38,8 @@ A a1 = {
3838
.y = 1, // reorder-note {{previous initialization for field 'y' is here}}
3939
.x = 2 // reorder-error {{ISO C++ requires field designators to be specified in declaration order; field 'y' will be initialized after field 'x'}}
4040
};
41+
// CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:3-[[@LINE-3]]:9}:".x = 2"
42+
// CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:3-[[@LINE-3]]:9}:".y = 1"
4143
int arr[3] = {[1] = 5}; // pedantic-error {{array designators are a C99 extension}}
4244
B b = {.a.x = 0}; // pedantic-error {{nested designators are a C99 extension}}
4345
A a2 = {
@@ -71,6 +73,12 @@ C c = {
7173
.x = 1, // reorder-error {{declaration order}} override-error {{overrides prior initialization}} override-note {{previous}}
7274
.x = 1, // override-error {{overrides prior initialization}}
7375
};
76+
// CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:3-[[@LINE-7]]:9}:".x = 1"
77+
// CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:3-[[@LINE-7]]:9}:".x = 1"
78+
// CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:3-[[@LINE-7]]:9}:".x = 1"
79+
// CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:3-[[@LINE-7]]:9}:".x = 1"
80+
// CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:3-[[@LINE-7]]:9}:".y = 1"
81+
// CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:3-[[@LINE-7]]:9}:".y = 1"
7482

7583
struct Foo { int a, b; };
7684

@@ -118,6 +126,8 @@ namespace overload_resolution {
118126
void i() {
119127
h({.x = 1, .y = 2});
120128
h({.y = 1, .x = 2}); // reorder-error {{declaration order}} reorder-note {{previous}}
129+
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:8-[[@LINE-1]]:14}:".x = 2"
130+
// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:22}:".y = 1"
121131
h({.x = 1}); // expected-error {{ambiguous}}
122132
}
123133

@@ -228,6 +238,16 @@ struct : public A, public B {
228238
.a = 1, // reorder-error {{field 'b' will be initialized after field 'a'}}
229239
};
230240
}
241+
// CHECK: fix-it:"{{.*}}":{[[@LINE-17]]:4-[[@LINE-17]]:8}:".x=2"
242+
// CHECK: fix-it:"{{.*}}":{[[@LINE-15]]:4-[[@LINE-15]]:8}:".y=1"
243+
// CHECK: fix-it:"{{.*}}":{[[@LINE-14]]:4-[[@LINE-14]]:8}:".z=0"
244+
// CHECK: fix-it:"{{.*}}":{[[@LINE-14]]:4-[[@LINE-14]]:8}:".a=4"
245+
// CHECK: fix-it:"{{.*}}":{[[@LINE-14]]:4-[[@LINE-14]]:8}:".b=3"
246+
// CHECK: fix-it:"{{.*}}":{[[@LINE-14]]:5-[[@LINE-14]]:11}:".a = 1"
247+
// CHECK: fix-it:"{{.*}}":{[[@LINE-13]]:5-[[@LINE-13]]:11}:".b = 1"
248+
// CHECK: fix-it:"{{.*}}":{[[@LINE-12]]:5-[[@LINE-12]]:11}:".c = 1"
249+
// CHECK: fix-it:"{{.*}}":{[[@LINE-12]]:5-[[@LINE-12]]:11}:".d = 1"
250+
// CHECK: fix-it:"{{.*}}":{[[@LINE-12]]:5-[[@LINE-12]]:11}:".e = 1"
231251

232252
namespace GH63759 {
233253
struct C {
@@ -248,3 +268,39 @@ void foo() {
248268
//
249269
}
250270
}
271+
272+
namespace reorder_derived {
273+
struct col {
274+
int r;
275+
int g;
276+
int b;
277+
};
278+
279+
struct point {
280+
float x;
281+
float y;
282+
float z;
283+
};
284+
285+
struct bar : public col, public point {
286+
int z2;
287+
int z1;
288+
};
289+
290+
void foo() {
291+
bar a {
292+
{.b = 1, .g = 2, .r = 3}, // reorder-error {{field 'b' will be initialized after field 'g'}} // reorder-error {{field 'g' will be initialized after field 'r'}} // reorder-note {{previous initialization for field 'b' is here}} // reorder-note {{previous initialization for field 'g' is here}} // pedantic-note {{first non-designated initializer is here}}
293+
{ .z = 1, .y=2, .x = 3 }, // reorder-error {{field 'z' will be initialized after field 'y'}} // reorder-error {{field 'y' will be initialized after field 'x'}} // reorder-note {{previous initialization for field 'z' is here}} // reorder-note {{previous initialization for field 'y' is here}}
294+
.z1 = 1, // pedantic-error {{mixture of designated and non-designated initializers in the same initializer list is a C99 extension}} // reorder-note {{previous initialization for field 'z1' is here}}
295+
.z2 = 2, // reorder-error {{field 'z1' will be initialized after field 'z2'}}
296+
};
297+
}
298+
// CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:6-[[@LINE-6]]:12}:".r = 3"
299+
// CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:14-[[@LINE-7]]:20}:".g = 2"
300+
// CHECK: fix-it:"{{.*}}":{[[@LINE-8]]:22-[[@LINE-8]]:28}:".b = 1"
301+
// CHECK: fix-it:"{{.*}}":{[[@LINE-8]]:15-[[@LINE-8]]:19}:".y=2"
302+
// CHECK: fix-it:"{{.*}}":{[[@LINE-9]]:21-[[@LINE-9]]:28}:".z = 1"
303+
// CHECK: fix-it:"{{.*}}":{[[@LINE-10]]:7-[[@LINE-10]]:13}:".x = 3"
304+
// CHECK: fix-it:"{{.*}}":{[[@LINE-10]]:5-[[@LINE-10]]:12}:".z2 = 2"
305+
// CHECK: fix-it:"{{.*}}":{[[@LINE-10]]:5-[[@LINE-10]]:12}:".z1 = 1"
306+
} // namespace reorder_derived

0 commit comments

Comments
 (0)