[PATCH] D98745: [clang] Add fixit for Wreorder-ctor

2021-03-24 Thread Nathan James via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG279ea930fa21: [clang] Add fixit for Wreorder-ctor (authored 
by njames93).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98745

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/FixIt/fixit-cxx-init-order.cpp
  clang/test/SemaCXX/constructor-initializer.cpp
  clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp

Index: clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp
===
--- clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp
+++ clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp
@@ -4,15 +4,14 @@
 
 struct BB1 {};
 
-class complex : public BB, BB1 { 
-public: 
+class complex : public BB, BB1 {
+public:
   complex()
-: s2(1), // expected-warning {{field 's2' will be initialized after field 's1'}}
-  s1(1),
-  s3(3), // expected-warning {{field 's3' will be initialized after base 'BB1'}} 
-  BB1(), // expected-warning {{base class 'BB1' will be initialized after base 'BB'}}
-  BB()
-  {}
+  : s2(1), // expected-warning {{initializer order does not match the declaration order}} expected-note {{field 's2' will be initialized after field 's1'}}
+s1(1),
+s3(3), // expected-note {{field 's3' will be initialized after base 'BB1'}}
+BB1(), // expected-note {{base class 'BB1' will be initialized after base 'BB'}}
+BB() {}
   int s1;
   int s2;
   int s3;
Index: clang/test/SemaCXX/constructor-initializer.cpp
===
--- clang/test/SemaCXX/constructor-initializer.cpp
+++ clang/test/SemaCXX/constructor-initializer.cpp
@@ -91,13 +91,14 @@
 
 struct Current : Derived {
   int Derived;
-  Current() : Derived(1), ::Derived(), // expected-warning {{field 'Derived' will be initialized after base '::Derived'}} \
-   // expected-warning {{base class '::Derived' will be initialized after base 'Derived::V'}}
-  ::Derived::Base(), // expected-error {{type '::Derived::Base' is not a direct or virtual base of 'Current'}}
-   Derived::Base1(), // expected-error {{type 'Derived::Base1' is not a direct or virtual base of 'Current'}}
-   Derived::V(),
-   ::NonExisting(), // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
-   INT::NonExisting()  {} // expected-error {{'INT' (aka 'int') is not a class, namespace, or enumeration}} \
+  Current() : Derived(1), ::Derived(), // expected-warning {{initializer order does not match the declaration order}} \
+   // expected-note {{field 'Derived' will be initialized after base '::Derived'}} \
+   // expected-note {{base class '::Derived' will be initialized after base 'Derived::V'}}
+  ::Derived::Base(),   // expected-error {{type '::Derived::Base' is not a direct or virtual base of 'Current'}}
+  Derived::Base1(),// expected-error {{type 'Derived::Base1' is not a direct or virtual base of 'Current'}}
+  Derived::V(),
+  ::NonExisting(),  // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
+  INT::NonExisting() {} // expected-error {{'INT' (aka 'int') is not a class, namespace, or enumeration}} \
   // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
 };
 
Index: clang/test/FixIt/fixit-cxx-init-order.cpp
===
--- /dev/null
+++ clang/test/FixIt/fixit-cxx-init-order.cpp
@@ -0,0 +1,22 @@
+// Due to the fix having multiple edits we can't use
+// '-fdiagnostics-parseable-fixits' to determine if fixes are correct. However,
+// running fixit recompile with 'Werror' should fail if the fixes are invalid.
+
+// RUN: %clang_cc1 %s -Werror=reorder-ctor -fixit-recompile -fixit-to-temporary
+// RUN: %clang_cc1 %s -Wreorder-ctor -verify -verify-ignore-unexpected=note
+
+struct Foo {
+  int A, B, C;
+
+  Foo() : A(1), B(3), C(2) {}
+  Foo(int) : A(1), C(2), B(3) {}  // expected-warning {{field 'C' will be initialized after field 'B'}}
+  Foo(unsigned) : C(2), B(3), A(1) {} // expected-warning {{initializer order does not match the declaration order}}
+};
+
+struct Bar : Foo {
+  int D, E, F;
+
+  Bar() : Foo(), D(1), E(2), F(3) {}
+  Bar(int) : D(1), E(2), F(3), Foo(4) {}  // expected-warning {{field 'F' will be initialized after base 'Foo'}}
+  Bar(unsigned) : F(3), E(2), D(1), Foo(4) {} // expected-warning {{initializer order does not 

[PATCH] D98745: [clang] Add fixit for Wreorder-ctor

2021-03-18 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman added a comment.
This revision is now accepted and ready to land.

Thanks for this! The changes LGTM, but wait to land it for a day or two in case 
@rsmith has concerns.




Comment at: clang/lib/Sema/SemaDeclCXX.cpp:5242
+  if (Previous->isAnyMemberInitializer())
+Diag << 0 << Previous->getAnyMember()->getDeclName();
+  else

njames93 wrote:
> aaron.ballman wrote:
> > 
> This was copied from the old impl, Not sure it this is going to change 
> behaviour though.
> No tests needed to be updated though,
The diagnostic engine knows how to format anything that's a `NamedDecl` 
(including quoting it properly, etc), but it does the same work for 
`DeclarationName`. There shouldn't be a change in behavior in this case, just a 
slight simplification of code.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98745

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D98745: [clang] Add fixit for Wreorder-ctor

2021-03-18 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 331635.
njames93 marked an inline comment as done.
njames93 added a comment.

Address nits.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98745

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/FixIt/fixit-cxx-init-order.cpp
  clang/test/SemaCXX/constructor-initializer.cpp
  clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp

Index: clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp
===
--- clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp
+++ clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp
@@ -4,15 +4,14 @@
 
 struct BB1 {};
 
-class complex : public BB, BB1 { 
-public: 
+class complex : public BB, BB1 {
+public:
   complex()
-: s2(1), // expected-warning {{field 's2' will be initialized after field 's1'}}
-  s1(1),
-  s3(3), // expected-warning {{field 's3' will be initialized after base 'BB1'}} 
-  BB1(), // expected-warning {{base class 'BB1' will be initialized after base 'BB'}}
-  BB()
-  {}
+  : s2(1), // expected-warning {{initializer order does not match the declaration order}} expected-note {{field 's2' will be initialized after field 's1'}}
+s1(1),
+s3(3), // expected-note {{field 's3' will be initialized after base 'BB1'}}
+BB1(), // expected-note {{base class 'BB1' will be initialized after base 'BB'}}
+BB() {}
   int s1;
   int s2;
   int s3;
Index: clang/test/SemaCXX/constructor-initializer.cpp
===
--- clang/test/SemaCXX/constructor-initializer.cpp
+++ clang/test/SemaCXX/constructor-initializer.cpp
@@ -91,13 +91,14 @@
 
 struct Current : Derived {
   int Derived;
-  Current() : Derived(1), ::Derived(), // expected-warning {{field 'Derived' will be initialized after base '::Derived'}} \
-   // expected-warning {{base class '::Derived' will be initialized after base 'Derived::V'}}
-  ::Derived::Base(), // expected-error {{type '::Derived::Base' is not a direct or virtual base of 'Current'}}
-   Derived::Base1(), // expected-error {{type 'Derived::Base1' is not a direct or virtual base of 'Current'}}
-   Derived::V(),
-   ::NonExisting(), // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
-   INT::NonExisting()  {} // expected-error {{'INT' (aka 'int') is not a class, namespace, or enumeration}} \
+  Current() : Derived(1), ::Derived(), // expected-warning {{initializer order does not match the declaration order}} \
+   // expected-note {{field 'Derived' will be initialized after base '::Derived'}} \
+   // expected-note {{base class '::Derived' will be initialized after base 'Derived::V'}}
+  ::Derived::Base(),   // expected-error {{type '::Derived::Base' is not a direct or virtual base of 'Current'}}
+  Derived::Base1(),// expected-error {{type 'Derived::Base1' is not a direct or virtual base of 'Current'}}
+  Derived::V(),
+  ::NonExisting(),  // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
+  INT::NonExisting() {} // expected-error {{'INT' (aka 'int') is not a class, namespace, or enumeration}} \
   // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
 };
 
Index: clang/test/FixIt/fixit-cxx-init-order.cpp
===
--- /dev/null
+++ clang/test/FixIt/fixit-cxx-init-order.cpp
@@ -0,0 +1,22 @@
+// Due to the fix having multiple edits we can't use
+// '-fdiagnostics-parseable-fixits' to determine if fixes are correct. However,
+// running fixit recompile with 'Werror' should fail if the fixes are invalid.
+
+// RUN: %clang_cc1 %s -Werror=reorder-ctor -fixit-recompile -fixit-to-temporary
+// RUN: %clang_cc1 %s -Wreorder-ctor -verify -verify-ignore-unexpected=note
+
+struct Foo {
+  int A, B, C;
+
+  Foo() : A(1), B(3), C(2) {}
+  Foo(int) : A(1), C(2), B(3) {}  // expected-warning {{field 'C' will be initialized after field 'B'}}
+  Foo(unsigned) : C(2), B(3), A(1) {} // expected-warning {{initializer order does not match the declaration order}}
+};
+
+struct Bar : Foo {
+  int D, E, F;
+
+  Bar() : Foo(), D(1), E(2), F(3) {}
+  Bar(int) : D(1), E(2), F(3), Foo(4) {}  // expected-warning {{field 'F' will be initialized after base 'Foo'}}
+  Bar(unsigned) : F(3), E(2), D(1), Foo(4) {} // expected-warning {{initializer order does not match the declaration order}}
+};

[PATCH] D98745: [clang] Add fixit for Wreorder-ctor

2021-03-18 Thread Nathan James via Phabricator via cfe-commits
njames93 marked 4 inline comments as done.
njames93 added inline comments.



Comment at: clang/lib/Sema/SemaDeclCXX.cpp:5242
+  if (Previous->isAnyMemberInitializer())
+Diag << 0 << Previous->getAnyMember()->getDeclName();
+  else

aaron.ballman wrote:
> 
This was copied from the old impl, Not sure it this is going to change 
behaviour though.
No tests needed to be updated though,


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98745

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D98745: [clang] Add fixit for Wreorder-ctor

2021-03-18 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:8611
+def warn_some_initializers_out_of_order : Warning<
+  "some initializers aren't given in the correct order">,
+  InGroup, DefaultIgnore;

Hmmm, how about `initializer order does not match the declaration order` or 
something along those lines? The "some" and "in the correct order" feel a bit 
hand-wavy for a warning.



Comment at: clang/lib/Sema/SemaDeclCXX.cpp:5242
+  if (Previous->isAnyMemberInitializer())
+Diag << 0 << Previous->getAnyMember()->getDeclName();
+  else





Comment at: clang/lib/Sema/SemaDeclCXX.cpp:5247
+  if (Current->isAnyMemberInitializer())
+Diag << 0 << Current->getAnyMember()->getDeclName();
+  else





Comment at: clang/lib/Sema/SemaDeclCXX.cpp:5304
+  SmallVector WarnIndexes;
+  // Correllates the index of an initializer in the init-list to the index of
+  // the field/base in the class.




Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98745

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D98745: [clang] Add fixit for Wreorder-ctor

2021-03-18 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 331582.
njames93 added a comment.

Arc got confused


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98745

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/FixIt/fixit-cxx-init-order.cpp
  clang/test/SemaCXX/constructor-initializer.cpp
  clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp

Index: clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp
===
--- clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp
+++ clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp
@@ -5,14 +5,13 @@
 struct BB1 {};
 
 class complex : public BB, BB1 { 
-public: 
+public:
   complex()
-: s2(1), // expected-warning {{field 's2' will be initialized after field 's1'}}
-  s1(1),
-  s3(3), // expected-warning {{field 's3' will be initialized after base 'BB1'}} 
-  BB1(), // expected-warning {{base class 'BB1' will be initialized after base 'BB'}}
-  BB()
-  {}
+  : s2(1), // expected-warning {{some initializers aren't given in the correct order}} expected-note {{field 's2' will be initialized after field 's1'}}
+s1(1),
+s3(3), // expected-note {{field 's3' will be initialized after base 'BB1'}}
+BB1(), // expected-note {{base class 'BB1' will be initialized after base 'BB'}}
+BB() {}
   int s1;
   int s2;
   int s3;
Index: clang/test/SemaCXX/constructor-initializer.cpp
===
--- clang/test/SemaCXX/constructor-initializer.cpp
+++ clang/test/SemaCXX/constructor-initializer.cpp
@@ -91,13 +91,14 @@
 
 struct Current : Derived {
   int Derived;
-  Current() : Derived(1), ::Derived(), // expected-warning {{field 'Derived' will be initialized after base '::Derived'}} \
-   // expected-warning {{base class '::Derived' will be initialized after base 'Derived::V'}}
-  ::Derived::Base(), // expected-error {{type '::Derived::Base' is not a direct or virtual base of 'Current'}}
-   Derived::Base1(), // expected-error {{type 'Derived::Base1' is not a direct or virtual base of 'Current'}}
-   Derived::V(),
-   ::NonExisting(), // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
-   INT::NonExisting()  {} // expected-error {{'INT' (aka 'int') is not a class, namespace, or enumeration}} \
+  Current() : Derived(1), ::Derived(), // expected-warning {{some initializers aren't given in the correct order}} \
+   // expected-note {{field 'Derived' will be initialized after base '::Derived'}} \
+   // expected-note {{base class '::Derived' will be initialized after base 'Derived::V'}}
+  ::Derived::Base(),   // expected-error {{type '::Derived::Base' is not a direct or virtual base of 'Current'}}
+  Derived::Base1(),// expected-error {{type 'Derived::Base1' is not a direct or virtual base of 'Current'}}
+  Derived::V(),
+  ::NonExisting(),  // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
+  INT::NonExisting() {} // expected-error {{'INT' (aka 'int') is not a class, namespace, or enumeration}} \
   // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
 };
 
Index: clang/test/FixIt/fixit-cxx-init-order.cpp
===
--- /dev/null
+++ clang/test/FixIt/fixit-cxx-init-order.cpp
@@ -0,0 +1,22 @@
+// Due to the fix having multiple edits we can't use
+// '-fdiagnostics-parseable-fixits' to determine if fixes are correct. However,
+// running fixit recompile with 'Werror' should fail if the fixes are invalid.
+
+// RUN: %clang_cc1 %s -Werror=reorder-ctor -fixit-recompile -fixit-to-temporary
+// RUN: %clang_cc1 %s -Wreorder-ctor -verify -verify-ignore-unexpected=note
+
+struct Foo {
+  int A, B, C;
+
+  Foo() : A(1), B(3), C(2) {}
+  Foo(int) : A(1), C(2), B(3) {}  // expected-warning {{field 'C' will be initialized after field 'B'}}
+  Foo(unsigned) : C(2), B(3), A(1) {} // expected-warning {{some initializers aren't given in the correct order}}
+};
+
+struct Bar : Foo {
+  int D, E, F;
+
+  Bar() : Foo(), D(1), E(2), F(3) {}
+  Bar(int) : D(1), E(2), F(3), Foo(4) {}  // expected-warning {{field 'F' will be initialized after base 'Foo'}}
+  Bar(unsigned) : F(3), E(2), D(1), Foo(4) {} // expected-warning {{some initializers aren't given in the correct order}}
+};
Index: clang/lib/Sema/SemaDeclCXX.cpp

[PATCH] D98745: [clang] Add fixit for Wreorder-ctor

2021-03-18 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 331581.
njames93 added a comment.

Fix formatting issues


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98745

Files:
  clang/test/SemaCXX/constructor-initializer.cpp
  clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp


Index: clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp
===
--- clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp
+++ clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp
@@ -5,14 +5,13 @@
 struct BB1 {};
 
 class complex : public BB, BB1 { 
-public: 
+public:
   complex()
-: s2(1), // expected-warning {{some initializers aren't given in the 
correct order}} expected-note {{field 's2' will be initialized after field 
's1'}}
-  s1(1),
-  s3(3), // expected-note {{field 's3' will be initialized after base 
'BB1'}} 
-  BB1(), // expected-note {{base class 'BB1' will be initialized after 
base 'BB'}}
-  BB()
-  {}
+  : s2(1), // expected-warning {{some initializers aren't given in the 
correct order}} expected-note {{field 's2' will be initialized after field 
's1'}}
+s1(1),
+s3(3), // expected-note {{field 's3' will be initialized after base 
'BB1'}}
+BB1(), // expected-note {{base class 'BB1' will be initialized after 
base 'BB'}}
+BB() {}
   int s1;
   int s2;
   int s3;
Index: clang/test/SemaCXX/constructor-initializer.cpp
===
--- clang/test/SemaCXX/constructor-initializer.cpp
+++ clang/test/SemaCXX/constructor-initializer.cpp
@@ -94,11 +94,11 @@
   Current() : Derived(1), ::Derived(), // expected-warning {{some initializers 
aren't given in the correct order}} \
// expected-note {{field 'Derived' will 
be initialized after base '::Derived'}} \
// expected-note {{base class 
'::Derived' will be initialized after base 'Derived::V'}}
-  ::Derived::Base(), // expected-error {{type 
'::Derived::Base' is not a direct or virtual base of 'Current'}}
-   Derived::Base1(), // expected-error {{type 
'Derived::Base1' is not a direct or virtual base of 'Current'}}
-   Derived::V(),
-   ::NonExisting(), // expected-error {{member 
initializer 'NonExisting' does not name a non-static data member or}}
-   INT::NonExisting()  {} // expected-error {{'INT' 
(aka 'int') is not a class, namespace, or enumeration}} \
+  ::Derived::Base(),   // expected-error {{type 
'::Derived::Base' is not a direct or virtual base of 'Current'}}
+  Derived::Base1(),// expected-error {{type 
'Derived::Base1' is not a direct or virtual base of 'Current'}}
+  Derived::V(),
+  ::NonExisting(),  // expected-error {{member initializer 
'NonExisting' does not name a non-static data member or}}
+  INT::NonExisting() {} // expected-error {{'INT' (aka 'int') is 
not a class, namespace, or enumeration}} \
   // expected-error {{member 
initializer 'NonExisting' does not name a non-static data member or}}
 };
 


Index: clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp
===
--- clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp
+++ clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp
@@ -5,14 +5,13 @@
 struct BB1 {};
 
 class complex : public BB, BB1 { 
-public: 
+public:
   complex()
-: s2(1), // expected-warning {{some initializers aren't given in the correct order}} expected-note {{field 's2' will be initialized after field 's1'}}
-  s1(1),
-  s3(3), // expected-note {{field 's3' will be initialized after base 'BB1'}} 
-  BB1(), // expected-note {{base class 'BB1' will be initialized after base 'BB'}}
-  BB()
-  {}
+  : s2(1), // expected-warning {{some initializers aren't given in the correct order}} expected-note {{field 's2' will be initialized after field 's1'}}
+s1(1),
+s3(3), // expected-note {{field 's3' will be initialized after base 'BB1'}}
+BB1(), // expected-note {{base class 'BB1' will be initialized after base 'BB'}}
+BB() {}
   int s1;
   int s2;
   int s3;
Index: clang/test/SemaCXX/constructor-initializer.cpp
===
--- clang/test/SemaCXX/constructor-initializer.cpp
+++ clang/test/SemaCXX/constructor-initializer.cpp
@@ -94,11 +94,11 @@
   Current() : Derived(1), ::Derived(), // expected-warning {{some initializers aren't given in the correct order}} \
// expected-note {{field 'Derived' will be initialized after base '::Derived'}} \

[PATCH] D98745: [clang] Add fixit for Wreorder-ctor

2021-03-16 Thread Nathan James via Phabricator via cfe-commits
njames93 created this revision.
njames93 added reviewers: rsmith, sammccall, aaron.ballman.
Herald added a subscriber: mgrang.
njames93 requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Create fix-it hints to fix the order of constructors.
To make this a lot simpler, I've grouped all the warnings for each out of order 
initializer into 1.
This is necessary as fixing one initializer would often interfere with other 
initializers.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D98745

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/FixIt/fixit-cxx-init-order.cpp
  clang/test/SemaCXX/constructor-initializer.cpp
  clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp

Index: clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp
===
--- clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp
+++ clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp
@@ -7,10 +7,10 @@
 class complex : public BB, BB1 { 
 public: 
   complex()
-: s2(1), // expected-warning {{field 's2' will be initialized after field 's1'}}
+: s2(1), // expected-warning {{some initializers aren't given in the correct order}} expected-note {{field 's2' will be initialized after field 's1'}}
   s1(1),
-  s3(3), // expected-warning {{field 's3' will be initialized after base 'BB1'}} 
-  BB1(), // expected-warning {{base class 'BB1' will be initialized after base 'BB'}}
+  s3(3), // expected-note {{field 's3' will be initialized after base 'BB1'}} 
+  BB1(), // expected-note {{base class 'BB1' will be initialized after base 'BB'}}
   BB()
   {}
   int s1;
Index: clang/test/SemaCXX/constructor-initializer.cpp
===
--- clang/test/SemaCXX/constructor-initializer.cpp
+++ clang/test/SemaCXX/constructor-initializer.cpp
@@ -91,8 +91,9 @@
 
 struct Current : Derived {
   int Derived;
-  Current() : Derived(1), ::Derived(), // expected-warning {{field 'Derived' will be initialized after base '::Derived'}} \
-   // expected-warning {{base class '::Derived' will be initialized after base 'Derived::V'}}
+  Current() : Derived(1), ::Derived(), // expected-warning {{some initializers aren't given in the correct order}} \
+   // expected-note {{field 'Derived' will be initialized after base '::Derived'}} \
+   // expected-note {{base class '::Derived' will be initialized after base 'Derived::V'}}
   ::Derived::Base(), // expected-error {{type '::Derived::Base' is not a direct or virtual base of 'Current'}}
Derived::Base1(), // expected-error {{type 'Derived::Base1' is not a direct or virtual base of 'Current'}}
Derived::V(),
Index: clang/test/FixIt/fixit-cxx-init-order.cpp
===
--- /dev/null
+++ clang/test/FixIt/fixit-cxx-init-order.cpp
@@ -0,0 +1,22 @@
+// Due to the fix having multiple edits we can't use
+// '-fdiagnostics-parseable-fixits' to determine if fixes are correct. However,
+// running fixit recompile with 'Werror' should fail if the fixes are invalid.
+
+// RUN: %clang_cc1 %s -Werror=reorder-ctor -fixit-recompile -fixit-to-temporary
+// RUN: %clang_cc1 %s -Wreorder-ctor -verify -verify-ignore-unexpected=note
+
+struct Foo {
+  int A, B, C;
+
+  Foo() : A(1), B(3), C(2) {}
+  Foo(int) : A(1), C(2), B(3) {}  // expected-warning {{field 'C' will be initialized after field 'B'}}
+  Foo(unsigned) : C(2), B(3), A(1) {} // expected-warning {{some initializers aren't given in the correct order}}
+};
+
+struct Bar : Foo {
+  int D, E, F;
+
+  Bar() : Foo(), D(1), E(2), F(3) {}
+  Bar(int) : D(1), E(2), F(3), Foo(4) {}  // expected-warning {{field 'F' will be initialized after base 'Foo'}}
+  Bar(unsigned) : F(3), E(2), D(1), Foo(4) {} // expected-warning {{some initializers aren't given in the correct order}}
+};
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -5239,6 +5239,20 @@
   return Member->getAnyMember()->getCanonicalDecl();
 }
 
+static void AddInitializerToDiag(const Sema::SemaDiagnosticBuilder ,
+ const CXXCtorInitializer *Previous,
+ const CXXCtorInitializer *Current) {
+  if (Previous->isAnyMemberInitializer())
+Diag << 0 << Previous->getAnyMember()->getDeclName();
+  else
+Diag << 1 << Previous->getTypeSourceInfo()->getType();
+
+  if (Current->isAnyMemberInitializer())
+Diag << 0 << Current->getAnyMember()->getDeclName();
+  else
+Diag << 1 << Current->getTypeSourceInfo()->getType();
+}
+