189a1d03eSRichard // RUN: %check_clang_tidy %s cppcoreguidelines-prefer-member-initializer %t -- -- -fcxx-exceptions
289a1d03eSRichard 
389a1d03eSRichard extern void __assert_fail (__const char *__assertion, __const char *__file,
489a1d03eSRichard     unsigned int __line, __const char *__function)
589a1d03eSRichard      __attribute__ ((__noreturn__));
689a1d03eSRichard #define assert(expr) \
789a1d03eSRichard   ((expr)  ? (void)(0)  : __assert_fail (#expr, __FILE__, __LINE__, __func__))
889a1d03eSRichard 
989a1d03eSRichard class Simple1 {
1089a1d03eSRichard   int n;
1189a1d03eSRichard   double x;
1289a1d03eSRichard 
1389a1d03eSRichard public:
1489a1d03eSRichard   Simple1() {
1589a1d03eSRichard     // CHECK-FIXES: Simple1() : n(0), x(0.0) {
1689a1d03eSRichard     n = 0;
1789a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'n' should be initialized in a member initializer of the constructor [cppcoreguidelines-prefer-member-initializer]
1889a1d03eSRichard     // CHECK-FIXES: {{^\ *$}}
1989a1d03eSRichard     x = 0.0;
2089a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'x' should be initialized in a member initializer of the constructor [cppcoreguidelines-prefer-member-initializer]
2189a1d03eSRichard     // CHECK-FIXES: {{^\ *$}}
2289a1d03eSRichard   }
2389a1d03eSRichard 
2489a1d03eSRichard   Simple1(int nn, double xx) {
2589a1d03eSRichard     // CHECK-FIXES: Simple1(int nn, double xx) : n(nn), x(xx) {
2689a1d03eSRichard     n = nn;
2789a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'n' should be initialized in a member initializer of the constructor [cppcoreguidelines-prefer-member-initializer]
2889a1d03eSRichard     // CHECK-FIXES: {{^\ *$}}
2989a1d03eSRichard     x = xx;
3089a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'x' should be initialized in a member initializer of the constructor [cppcoreguidelines-prefer-member-initializer]
3189a1d03eSRichard     // CHECK-FIXES: {{^\ *$}}
3289a1d03eSRichard   }
3389a1d03eSRichard 
3489a1d03eSRichard   ~Simple1() = default;
3589a1d03eSRichard };
3689a1d03eSRichard 
3789a1d03eSRichard class Simple2 {
3889a1d03eSRichard   int n;
3989a1d03eSRichard   double x;
4089a1d03eSRichard 
4189a1d03eSRichard public:
4289a1d03eSRichard   Simple2() : n(0) {
4389a1d03eSRichard     // CHECK-FIXES: Simple2() : n(0), x(0.0) {
4489a1d03eSRichard     x = 0.0;
4589a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'x' should be initialized in a member initializer of the constructor [cppcoreguidelines-prefer-member-initializer]
4689a1d03eSRichard     // CHECK-FIXES: {{^\ *$}}
4789a1d03eSRichard   }
4889a1d03eSRichard 
4989a1d03eSRichard   Simple2(int nn, double xx) : n(nn) {
5089a1d03eSRichard     // CHECK-FIXES: Simple2(int nn, double xx) : n(nn), x(xx) {
5189a1d03eSRichard     x = xx;
5289a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'x' should be initialized in a member initializer of the constructor [cppcoreguidelines-prefer-member-initializer]
5389a1d03eSRichard     // CHECK-FIXES: {{^\ *$}}
5489a1d03eSRichard   }
5589a1d03eSRichard 
5689a1d03eSRichard   ~Simple2() = default;
5789a1d03eSRichard };
5889a1d03eSRichard 
5989a1d03eSRichard class Simple3 {
6089a1d03eSRichard   int n;
6189a1d03eSRichard   double x;
6289a1d03eSRichard 
6389a1d03eSRichard public:
6489a1d03eSRichard   Simple3() : x(0.0) {
6589a1d03eSRichard     // CHECK-FIXES: Simple3() : n(0), x(0.0) {
6689a1d03eSRichard     n = 0;
6789a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'n' should be initialized in a member initializer of the constructor [cppcoreguidelines-prefer-member-initializer]
6889a1d03eSRichard     // CHECK-FIXES: {{^\ *$}}
6989a1d03eSRichard   }
7089a1d03eSRichard 
7189a1d03eSRichard   Simple3(int nn, double xx) : x(xx) {
7289a1d03eSRichard     // CHECK-FIXES: Simple3(int nn, double xx) : n(nn), x(xx) {
7389a1d03eSRichard     n = nn;
7489a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'n' should be initialized in a member initializer of the constructor [cppcoreguidelines-prefer-member-initializer]
7589a1d03eSRichard     // CHECK-FIXES: {{^\ *$}}
7689a1d03eSRichard   }
7789a1d03eSRichard 
7889a1d03eSRichard   ~Simple3() = default;
7989a1d03eSRichard };
8089a1d03eSRichard 
8189a1d03eSRichard int something_int();
8289a1d03eSRichard double something_double();
8389a1d03eSRichard 
8489a1d03eSRichard class Simple4 {
8589a1d03eSRichard   int n;
8689a1d03eSRichard 
8789a1d03eSRichard public:
8889a1d03eSRichard   Simple4() {
8989a1d03eSRichard     // CHECK-FIXES: Simple4() : n(something_int()) {
9089a1d03eSRichard     n = something_int();
9189a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'n' should be initialized in a member initializer of the constructor [cppcoreguidelines-prefer-member-initializer]
9289a1d03eSRichard     // CHECK-FIXES: {{^\ *$}}
9389a1d03eSRichard   }
9489a1d03eSRichard 
9589a1d03eSRichard   ~Simple4() = default;
9689a1d03eSRichard };
9789a1d03eSRichard 
9889a1d03eSRichard static bool dice();
9989a1d03eSRichard 
10089a1d03eSRichard class Complex1 {
10189a1d03eSRichard   int n;
10289a1d03eSRichard   int m;
10389a1d03eSRichard 
10489a1d03eSRichard public:
10589a1d03eSRichard   Complex1() : n(0) {
10689a1d03eSRichard     if (dice())
10789a1d03eSRichard       m = 1;
10889a1d03eSRichard     // NO-MESSAGES: initialization of 'm' is nested in a conditional expression
10989a1d03eSRichard   }
11089a1d03eSRichard 
11189a1d03eSRichard   ~Complex1() = default;
11289a1d03eSRichard };
11389a1d03eSRichard 
11489a1d03eSRichard class Complex2 {
11589a1d03eSRichard   int n;
11689a1d03eSRichard   int m;
11789a1d03eSRichard 
11889a1d03eSRichard public:
11989a1d03eSRichard   Complex2() : n(0) {
12089a1d03eSRichard     if (!dice())
12189a1d03eSRichard       return;
12289a1d03eSRichard     m = 1;
12389a1d03eSRichard     // NO-MESSAGES: initialization of 'm' follows a conditional expression
12489a1d03eSRichard   }
12589a1d03eSRichard 
12689a1d03eSRichard   ~Complex2() = default;
12789a1d03eSRichard };
12889a1d03eSRichard 
12989a1d03eSRichard class Complex3 {
13089a1d03eSRichard   int n;
13189a1d03eSRichard   int m;
13289a1d03eSRichard 
13389a1d03eSRichard public:
13489a1d03eSRichard   Complex3() : n(0) {
13589a1d03eSRichard     while (dice())
13689a1d03eSRichard       m = 1;
13789a1d03eSRichard     // NO-MESSAGES: initialization of 'm' is nested in a conditional loop
13889a1d03eSRichard   }
13989a1d03eSRichard 
14089a1d03eSRichard   ~Complex3() = default;
14189a1d03eSRichard };
14289a1d03eSRichard 
14389a1d03eSRichard class Complex4 {
14489a1d03eSRichard   int n;
14589a1d03eSRichard   int m;
14689a1d03eSRichard 
14789a1d03eSRichard public:
14889a1d03eSRichard   Complex4() : n(0) {
14989a1d03eSRichard     while (!dice())
15089a1d03eSRichard       return;
15189a1d03eSRichard     m = 1;
15289a1d03eSRichard     // NO-MESSAGES: initialization of 'm' follows a conditional loop
15389a1d03eSRichard   }
15489a1d03eSRichard 
15589a1d03eSRichard   ~Complex4() = default;
15689a1d03eSRichard };
15789a1d03eSRichard 
15889a1d03eSRichard class Complex5 {
15989a1d03eSRichard   int n;
16089a1d03eSRichard   int m;
16189a1d03eSRichard 
16289a1d03eSRichard public:
16389a1d03eSRichard   Complex5() : n(0) {
16489a1d03eSRichard     do {
16589a1d03eSRichard       m = 1;
16689a1d03eSRichard       // NO-MESSAGES: initialization of 'm' is nested in a conditional loop
16789a1d03eSRichard     } while (dice());
16889a1d03eSRichard   }
16989a1d03eSRichard 
17089a1d03eSRichard   ~Complex5() = default;
17189a1d03eSRichard };
17289a1d03eSRichard 
17389a1d03eSRichard class Complex6 {
17489a1d03eSRichard   int n;
17589a1d03eSRichard   int m;
17689a1d03eSRichard 
17789a1d03eSRichard public:
17889a1d03eSRichard   Complex6() : n(0) {
17989a1d03eSRichard     do {
18089a1d03eSRichard       return;
18189a1d03eSRichard     } while (!dice());
18289a1d03eSRichard     m = 1;
18389a1d03eSRichard     // NO-MESSAGES: initialization of 'm' follows a conditional loop
18489a1d03eSRichard   }
18589a1d03eSRichard 
18689a1d03eSRichard   ~Complex6() = default;
18789a1d03eSRichard };
18889a1d03eSRichard 
18989a1d03eSRichard class Complex7 {
19089a1d03eSRichard   int n;
19189a1d03eSRichard   int m;
19289a1d03eSRichard 
19389a1d03eSRichard public:
19489a1d03eSRichard   Complex7() : n(0) {
19589a1d03eSRichard     for (int i = 2; i < 1; ++i) {
19689a1d03eSRichard       m = 1;
19789a1d03eSRichard     }
19889a1d03eSRichard     // NO-MESSAGES: initialization of 'm' is nested into a conditional loop
19989a1d03eSRichard   }
20089a1d03eSRichard 
20189a1d03eSRichard   ~Complex7() = default;
20289a1d03eSRichard };
20389a1d03eSRichard 
20489a1d03eSRichard class Complex8 {
20589a1d03eSRichard   int n;
20689a1d03eSRichard   int m;
20789a1d03eSRichard 
20889a1d03eSRichard public:
20989a1d03eSRichard   Complex8() : n(0) {
21089a1d03eSRichard     for (int i = 0; i < 2; ++i) {
21189a1d03eSRichard       return;
21289a1d03eSRichard     }
21389a1d03eSRichard     m = 1;
21489a1d03eSRichard     // NO-MESSAGES: initialization of 'm' follows a conditional loop
21589a1d03eSRichard   }
21689a1d03eSRichard 
21789a1d03eSRichard   ~Complex8() = default;
21889a1d03eSRichard };
21989a1d03eSRichard 
22089a1d03eSRichard class Complex9 {
22189a1d03eSRichard   int n;
22289a1d03eSRichard   int m;
22389a1d03eSRichard 
22489a1d03eSRichard public:
22589a1d03eSRichard   Complex9() : n(0) {
22689a1d03eSRichard     switch (dice()) {
22789a1d03eSRichard     case 1:
22889a1d03eSRichard       m = 1;
22989a1d03eSRichard       // NO-MESSAGES: initialization of 'm' is nested in a conditional expression
23089a1d03eSRichard       break;
23189a1d03eSRichard     default:
23289a1d03eSRichard       break;
23389a1d03eSRichard     }
23489a1d03eSRichard   }
23589a1d03eSRichard 
23689a1d03eSRichard   ~Complex9() = default;
23789a1d03eSRichard };
23889a1d03eSRichard 
23989a1d03eSRichard class Complex10 {
24089a1d03eSRichard   int n;
24189a1d03eSRichard   int m;
24289a1d03eSRichard 
24389a1d03eSRichard public:
24489a1d03eSRichard   Complex10() : n(0) {
24589a1d03eSRichard     switch (dice()) {
24689a1d03eSRichard     case 1:
24789a1d03eSRichard       return;
24889a1d03eSRichard       break;
24989a1d03eSRichard     default:
25089a1d03eSRichard       break;
25189a1d03eSRichard     }
25289a1d03eSRichard     m = 1;
25389a1d03eSRichard     // NO-MESSAGES: initialization of 'm' follows a conditional expression
25489a1d03eSRichard   }
25589a1d03eSRichard 
25689a1d03eSRichard   ~Complex10() = default;
25789a1d03eSRichard };
25889a1d03eSRichard 
25989a1d03eSRichard class E {};
26089a1d03eSRichard int risky(); // may throw
26189a1d03eSRichard 
26289a1d03eSRichard class Complex11 {
26389a1d03eSRichard   int n;
26489a1d03eSRichard   int m;
26589a1d03eSRichard 
26689a1d03eSRichard public:
26789a1d03eSRichard   Complex11() : n(0) {
26889a1d03eSRichard     try {
26989a1d03eSRichard       risky();
27089a1d03eSRichard       m = 1;
27189a1d03eSRichard       // NO-MESSAGES: initialization of 'm' follows is nested in a try-block
27289a1d03eSRichard     } catch (const E& e) {
27389a1d03eSRichard       return;
27489a1d03eSRichard     }
27589a1d03eSRichard   }
27689a1d03eSRichard 
27789a1d03eSRichard   ~Complex11() = default;
27889a1d03eSRichard };
27989a1d03eSRichard 
28089a1d03eSRichard class Complex12 {
28189a1d03eSRichard   int n;
28289a1d03eSRichard   int m;
28389a1d03eSRichard 
28489a1d03eSRichard public:
28589a1d03eSRichard   Complex12() : n(0) {
28689a1d03eSRichard     try {
28789a1d03eSRichard       risky();
28889a1d03eSRichard     } catch (const E& e) {
28989a1d03eSRichard       return;
29089a1d03eSRichard     }
29189a1d03eSRichard     m = 1;
29289a1d03eSRichard     // NO-MESSAGES: initialization of 'm' follows a try-block
29389a1d03eSRichard   }
29489a1d03eSRichard 
29589a1d03eSRichard   ~Complex12() = default;
29689a1d03eSRichard };
29789a1d03eSRichard 
29889a1d03eSRichard class Complex13 {
29989a1d03eSRichard   int n;
30089a1d03eSRichard   int m;
30189a1d03eSRichard 
30289a1d03eSRichard public:
30389a1d03eSRichard   Complex13() : n(0) {
30489a1d03eSRichard     return;
30589a1d03eSRichard     m = 1;
30689a1d03eSRichard     // NO-MESSAGES: initialization of 'm' follows a return statement
30789a1d03eSRichard   }
30889a1d03eSRichard 
30989a1d03eSRichard   ~Complex13() = default;
31089a1d03eSRichard };
31189a1d03eSRichard 
31289a1d03eSRichard class Complex14 {
31389a1d03eSRichard   int n;
31489a1d03eSRichard   int m;
31589a1d03eSRichard 
31689a1d03eSRichard public:
31789a1d03eSRichard   Complex14() : n(0) {
31889a1d03eSRichard     goto X;
31989a1d03eSRichard     m = 1;
32089a1d03eSRichard     // NO-MESSAGES: initialization of 'm' follows a goto statement
32189a1d03eSRichard   X:
32289a1d03eSRichard     ;
32389a1d03eSRichard   }
32489a1d03eSRichard 
32589a1d03eSRichard   ~Complex14() = default;
32689a1d03eSRichard };
32789a1d03eSRichard 
32889a1d03eSRichard void returning();
32989a1d03eSRichard 
33089a1d03eSRichard class Complex15 {
33189a1d03eSRichard   int n;
33289a1d03eSRichard   int m;
33389a1d03eSRichard 
33489a1d03eSRichard public:
33589a1d03eSRichard   Complex15() : n(0) {
33689a1d03eSRichard     // CHECK-FIXES: Complex15() : n(0), m(1) {
33789a1d03eSRichard     returning();
33889a1d03eSRichard     m = 1;
33989a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'm' should be initialized in a member initializer of the constructor [cppcoreguidelines-prefer-member-initializer]
34089a1d03eSRichard     // CHECK-FIXES: {{^\ *$}}
34189a1d03eSRichard   }
34289a1d03eSRichard 
34389a1d03eSRichard   ~Complex15() = default;
34489a1d03eSRichard };
34589a1d03eSRichard 
34689a1d03eSRichard [[noreturn]] void not_returning();
34789a1d03eSRichard 
34889a1d03eSRichard class Complex16 {
34989a1d03eSRichard   int n;
35089a1d03eSRichard   int m;
35189a1d03eSRichard 
35289a1d03eSRichard public:
35389a1d03eSRichard   Complex16() : n(0) {
35489a1d03eSRichard     not_returning();
35589a1d03eSRichard     m = 1;
35689a1d03eSRichard     // NO-MESSAGES: initialization of 'm' follows a non-returning function call
35789a1d03eSRichard   }
35889a1d03eSRichard 
35989a1d03eSRichard   ~Complex16() = default;
36089a1d03eSRichard };
36189a1d03eSRichard 
36289a1d03eSRichard class Complex17 {
36389a1d03eSRichard   int n;
36489a1d03eSRichard   int m;
36589a1d03eSRichard 
36689a1d03eSRichard public:
36789a1d03eSRichard   Complex17() : n(0) {
36889a1d03eSRichard     throw 1;
36989a1d03eSRichard     m = 1;
37089a1d03eSRichard     // NO-MESSAGES: initialization of 'm' follows a 'throw' statement;
37189a1d03eSRichard   }
37289a1d03eSRichard 
37389a1d03eSRichard   ~Complex17() = default;
37489a1d03eSRichard };
37589a1d03eSRichard 
37689a1d03eSRichard class Complex18 {
37789a1d03eSRichard   int n;
37889a1d03eSRichard 
37989a1d03eSRichard public:
38089a1d03eSRichard   Complex18() try {
38189a1d03eSRichard     n = risky();
38289a1d03eSRichard     // NO-MESSAGES: initialization of 'n' in a 'try' body;
38389a1d03eSRichard   } catch (const E& e) {
38489a1d03eSRichard     n = 0;
38589a1d03eSRichard   }
38689a1d03eSRichard 
38789a1d03eSRichard   ~Complex18() = default;
38889a1d03eSRichard };
38989a1d03eSRichard 
39089a1d03eSRichard class Complex19 {
39189a1d03eSRichard   int n;
39289a1d03eSRichard public:
39389a1d03eSRichard   Complex19() {
39489a1d03eSRichard     // CHECK-FIXES: Complex19() : n(0) {
39589a1d03eSRichard     n = 0;
39689a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'n' should be initialized in a member initializer of the constructor [cppcoreguidelines-prefer-member-initializer]
39789a1d03eSRichard     // CHECK-FIXES: {{^\ *$}}
39889a1d03eSRichard   }
39989a1d03eSRichard 
40089a1d03eSRichard   explicit Complex19(int) {
40189a1d03eSRichard     // CHECK-FIXES: Complex19(int) : n(12) {
40289a1d03eSRichard     n = 12;
40389a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'n' should be initialized in a member initializer of the constructor [cppcoreguidelines-prefer-member-initializer]
40489a1d03eSRichard     // CHECK-FIXES: {{^\ *$}}
40589a1d03eSRichard   }
40689a1d03eSRichard 
40789a1d03eSRichard   ~Complex19() = default;
40889a1d03eSRichard };
40989a1d03eSRichard 
41089a1d03eSRichard class Complex20 {
41189a1d03eSRichard   int n;
41289a1d03eSRichard   int m;
41389a1d03eSRichard 
41489a1d03eSRichard public:
41589a1d03eSRichard   Complex20(int k) : n(0) {
41689a1d03eSRichard     assert(k > 0);
41789a1d03eSRichard     m = 1;
41889a1d03eSRichard     // NO-MESSAGES: initialization of 'm' follows an assertion
41989a1d03eSRichard   }
42089a1d03eSRichard 
42189a1d03eSRichard   ~Complex20() = default;
42289a1d03eSRichard };
42389a1d03eSRichard 
42489a1d03eSRichard class VeryComplex1 {
42589a1d03eSRichard   int n1, n2, n3;
42689a1d03eSRichard   double x1, x2, x3;
42789a1d03eSRichard   int n4, n5, n6;
42889a1d03eSRichard   double x4, x5, x6;
42989a1d03eSRichard 
43089a1d03eSRichard   VeryComplex1() : n3(something_int()), x3(something_double()),
43189a1d03eSRichard                    n5(something_int()), x4(something_double()),
43289a1d03eSRichard                    x5(something_double()) {
43389a1d03eSRichard     // CHECK-FIXES: VeryComplex1() : n2(something_int()), n1(something_int()), n3(something_int()), x2(something_double()), x1(something_double()), x3(something_double()),
43489a1d03eSRichard     // CHECK-FIXES:                  n4(something_int()), n5(something_int()), n6(something_int()), x4(something_double()),
43589a1d03eSRichard     // CHECK-FIXES:                  x5(something_double()), x6(something_double()) {
43689a1d03eSRichard 
43789a1d03eSRichard // FIXME: Order of elements on the constructor initializer list should match
43889a1d03eSRichard //        the order of the declaration of the fields. Thus the correct fixes
43989a1d03eSRichard //        should look like these:
44089a1d03eSRichard //
44189a1d03eSRichard     // C ECK-FIXES: VeryComplex1() : n2(something_int()), n1(something_int()), n3(something_int()), x2(something_double()), x1(something_double()), x3(something_double()),
44289a1d03eSRichard     // C ECK-FIXES:                  n4(something_int()), n5(something_int()), n6(something_int()), x4(something_double()),
44389a1d03eSRichard     // C ECK-FIXES:                  x5(something_double()), x6(something_double()) {
44489a1d03eSRichard //
44589a1d03eSRichard //        However, the Diagnostics Engine processes fixes in the order of the
44689a1d03eSRichard //        diagnostics and insertions to the same position are handled in left to
44789a1d03eSRichard //        right order thus in the case two adjacent fields are initialized
44889a1d03eSRichard //        inside the constructor in reverse order the provided fix is a
44989a1d03eSRichard //        constructor initializer list that does not match the order of the
45089a1d03eSRichard //        declaration of the fields.
45189a1d03eSRichard 
45289a1d03eSRichard     x2 = something_double();
45389a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'x2' should be initialized in a member initializer of the constructor [cppcoreguidelines-prefer-member-initializer]
45489a1d03eSRichard     // CHECK-FIXES: {{^\ *$}}
45589a1d03eSRichard     n2 = something_int();
45689a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'n2' should be initialized in a member initializer of the constructor [cppcoreguidelines-prefer-member-initializer]
45789a1d03eSRichard     // CHECK-FIXES: {{^\ *$}}
45889a1d03eSRichard     x6 = something_double();
45989a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'x6' should be initialized in a member initializer of the constructor [cppcoreguidelines-prefer-member-initializer]
46089a1d03eSRichard     // CHECK-FIXES: {{^\ *$}}
46189a1d03eSRichard     x1 = something_double();
46289a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'x1' should be initialized in a member initializer of the constructor [cppcoreguidelines-prefer-member-initializer]
46389a1d03eSRichard     // CHECK-FIXES: {{^\ *$}}
46489a1d03eSRichard     n6 = something_int();
46589a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'n6' should be initialized in a member initializer of the constructor [cppcoreguidelines-prefer-member-initializer]
46689a1d03eSRichard     // CHECK-FIXES: {{^\ *$}}
46789a1d03eSRichard     n1 = something_int();
46889a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'n1' should be initialized in a member initializer of the constructor [cppcoreguidelines-prefer-member-initializer]
46989a1d03eSRichard     // CHECK-FIXES: {{^\ *$}}
47089a1d03eSRichard     n4 = something_int();
47189a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'n4' should be initialized in a member initializer of the constructor [cppcoreguidelines-prefer-member-initializer]
47289a1d03eSRichard     // CHECK-FIXES: {{^\ *$}}
47389a1d03eSRichard   }
47489a1d03eSRichard };
47589a1d03eSRichard 
47689a1d03eSRichard struct Outside {
47789a1d03eSRichard   int n;
47889a1d03eSRichard   double x;
47989a1d03eSRichard   Outside();
48089a1d03eSRichard };
48189a1d03eSRichard 
48289a1d03eSRichard Outside::Outside() {
48389a1d03eSRichard     // CHECK-FIXES: Outside::Outside() : n(1), x(1.0) {
48489a1d03eSRichard   n = 1;
48589a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'n' should be initialized in a member initializer of the constructor [cppcoreguidelines-prefer-member-initializer]
48689a1d03eSRichard     // CHECK-FIXES: {{^\ *$}}
48789a1d03eSRichard   x = 1.0;
48889a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'x' should be initialized in a member initializer of the constructor [cppcoreguidelines-prefer-member-initializer]
48989a1d03eSRichard     // CHECK-FIXES: {{^\ *$}}
49089a1d03eSRichard }
49189a1d03eSRichard 
49289a1d03eSRichard struct SafeDependancy {
49389a1d03eSRichard   int m;
49489a1d03eSRichard   int n;
49589a1d03eSRichard   SafeDependancy(int M) : m(M) {
49689a1d03eSRichard     // CHECK-FIXES: SafeDependancy(int M) : m(M), n(m) {
49789a1d03eSRichard     n = m;
49889a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'n' should be initialized in a member initializer of the constructor
49989a1d03eSRichard   }
50089a1d03eSRichard   // We match against direct field dependancy as well as descendant field
50189a1d03eSRichard   // dependancy, ensure both are accounted for.
50289a1d03eSRichard   SafeDependancy(short M) : m(M) {
50389a1d03eSRichard     // CHECK-FIXES: SafeDependancy(short M) : m(M), n(m + 1) {
50489a1d03eSRichard     n = m + 1;
50589a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'n' should be initialized in a member initializer of the constructor
50689a1d03eSRichard   }
50789a1d03eSRichard };
50889a1d03eSRichard 
50989a1d03eSRichard struct BadDependancy {
51089a1d03eSRichard   int m;
51189a1d03eSRichard   int n;
51289a1d03eSRichard   BadDependancy(int N) : n(N) {
51389a1d03eSRichard     m = n;
51489a1d03eSRichard   }
51589a1d03eSRichard   BadDependancy(short N) : n(N) {
51689a1d03eSRichard     m = n + 1;
51789a1d03eSRichard   }
51889a1d03eSRichard };
51989a1d03eSRichard 
52089a1d03eSRichard struct InitFromVarDecl {
52189a1d03eSRichard   int m;
52289a1d03eSRichard   InitFromVarDecl() {
52389a1d03eSRichard     // Can't apply this fix as n is declared in the body of the constructor.
52489a1d03eSRichard     int n = 3;
52589a1d03eSRichard     m = n;
52689a1d03eSRichard   }
52789a1d03eSRichard };
52889a1d03eSRichard 
52989a1d03eSRichard struct HasInClassInit {
53089a1d03eSRichard   int m = 4;
53189a1d03eSRichard   HasInClassInit() {
53289a1d03eSRichard     m = 3;
53389a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'm' should be initialized in a member initializer of the constructor
53489a1d03eSRichard   }
53589a1d03eSRichard };
53689a1d03eSRichard 
53789a1d03eSRichard struct HasInitListInit {
53889a1d03eSRichard   int M;
53989a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE+5]]:5: warning: 'M' should be initialized in a member initializer of the constructor
54089a1d03eSRichard   // CHECK-FIXES: HasInitListInit(const HasInitListInit &Other) : M(Other.M) {
54189a1d03eSRichard   // CHECK-FIXES-NEXT: {{^    $}}
54289a1d03eSRichard   // CHECK-FIXES-NEXT: }
54389a1d03eSRichard   HasInitListInit(const HasInitListInit &Other) : M(4) {
54489a1d03eSRichard     M = Other.M;
54589a1d03eSRichard   }
54689a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE+5]]:5: warning: 'M' should be initialized in a member initializer of the constructor
54789a1d03eSRichard   // CHECK-FIXES: HasInitListInit(HasInitListInit &&Other) : M(Other.M) {
54889a1d03eSRichard   // CHECK-FIXES-NEXT: {{^    $}}
54989a1d03eSRichard   // CHECK-FIXES-NEXT: }
55089a1d03eSRichard   HasInitListInit(HasInitListInit &&Other) : M() {
55189a1d03eSRichard     M = Other.M;
55289a1d03eSRichard   }
55389a1d03eSRichard };
55489a1d03eSRichard 
55589a1d03eSRichard #define ASSIGN_IN_MACRO(FIELD, VALUE) FIELD = (VALUE);
55689a1d03eSRichard 
55789a1d03eSRichard struct MacroCantFix {
55889a1d03eSRichard   int n; // NoFix
55989a1d03eSRichard   // CHECK-FIXES: int n; // NoFix
56089a1d03eSRichard   MacroCantFix() {
56189a1d03eSRichard     ASSIGN_IN_MACRO(n, 0)
56289a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'n' should be initialized in a member initializer of the constructor
56389a1d03eSRichard     // CHECK-FIXES: ASSIGN_IN_MACRO(n, 0)
56489a1d03eSRichard   }
56589a1d03eSRichard };
5667a4b12e3SPiotr Zegar 
5677a4b12e3SPiotr Zegar struct PR52818  {
5687a4b12e3SPiotr Zegar     PR52818() : bar(5) {}
5697a4b12e3SPiotr Zegar     PR52818(int) : PR52818() { bar = 3; }
5707a4b12e3SPiotr Zegar 
5717a4b12e3SPiotr Zegar     int bar;
5727a4b12e3SPiotr Zegar };
57326374675SCongcong Cai 
57426374675SCongcong Cai struct RefReassignment {
57526374675SCongcong Cai   RefReassignment(int &i) : m_i{i} {
57626374675SCongcong Cai     m_i = 1;
57726374675SCongcong Cai   }
57826374675SCongcong Cai   int & m_i;
57926374675SCongcong Cai };
58026374675SCongcong Cai 
58126374675SCongcong Cai struct ReassignmentAfterUnsafetyAssignment {
58226374675SCongcong Cai   ReassignmentAfterUnsafetyAssignment() {
58326374675SCongcong Cai     int a = 10;
58426374675SCongcong Cai     m_i = a;
58526374675SCongcong Cai     m_i = 1;
58626374675SCongcong Cai   }
58726374675SCongcong Cai   int m_i;
58826374675SCongcong Cai };
5896a80e56aSPiotr Zegar 
5906a80e56aSPiotr Zegar namespace PR70189 {
5916a80e56aSPiotr Zegar #define RGB(r,g,b) ((unsigned long)(((unsigned char)(r)|((unsigned short)((unsigned char)(g))<<8))|(((unsigned long)(unsigned char)(b))<<16)))
5926a80e56aSPiotr Zegar #define INVALID_HANDLE_VALUE ((void*)(unsigned long long)-1)
5936a80e56aSPiotr Zegar #define SIMPLE 12
5946a80e56aSPiotr Zegar 
5956a80e56aSPiotr Zegar class Foo {
5966a80e56aSPiotr Zegar public:
5976a80e56aSPiotr Zegar   Foo() {
5986a80e56aSPiotr Zegar // CHECK-FIXES: Foo() : m_color(RGB(255, 128, 0)), m_handle(INVALID_HANDLE_VALUE), m_myval(SIMPLE) {
5996a80e56aSPiotr Zegar     m_color = RGB(255, 128, 0);
6006a80e56aSPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'm_color' should be initialized in a member initializer of the constructor [cppcoreguidelines-prefer-member-initializer]
6016a80e56aSPiotr Zegar // CHECK-FIXES: {{^\ *$}}
6026a80e56aSPiotr Zegar     m_handle = INVALID_HANDLE_VALUE;
6036a80e56aSPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'm_handle' should be initialized in a member initializer of the constructor [cppcoreguidelines-prefer-member-initializer]
6046a80e56aSPiotr Zegar // CHECK-FIXES: {{^\ *$}}
6056a80e56aSPiotr Zegar     m_myval = SIMPLE;
6066a80e56aSPiotr Zegar // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'm_myval' should be initialized in a member initializer of the constructor [cppcoreguidelines-prefer-member-initializer]
6076a80e56aSPiotr Zegar // CHECK-FIXES: {{^\ *$}}
6086a80e56aSPiotr Zegar   }
6096a80e56aSPiotr Zegar private:
6106a80e56aSPiotr Zegar   unsigned long m_color;
6116a80e56aSPiotr Zegar   void* m_handle;
6126a80e56aSPiotr Zegar   int m_myval;
6136a80e56aSPiotr Zegar };
6146a80e56aSPiotr Zegar 
6156a80e56aSPiotr Zegar #undef SIMPLE
6166a80e56aSPiotr Zegar #undef INVALID_HANDLE_VALUE
6176a80e56aSPiotr Zegar #undef RGB
6186a80e56aSPiotr Zegar }
619e9cec392SCongcong Cai 
620e9cec392SCongcong Cai namespace GH77684 {
621e9cec392SCongcong Cai struct S1 {
622e9cec392SCongcong Cai // CHECK-MESSAGES: :[[@LINE+1]]:16: warning: 'M' should be initialized in a member initializer of the constructor [cppcoreguidelines-prefer-member-initializer]
623e9cec392SCongcong Cai   S1() : M{} { M = 0; }
624e9cec392SCongcong Cai // CHECK-FIXES:  S1() : M{0} { }
625e9cec392SCongcong Cai   int M;
626e9cec392SCongcong Cai };
627e9cec392SCongcong Cai struct S2 {
628e9cec392SCongcong Cai // CHECK-MESSAGES: :[[@LINE+1]]:17: warning: 'M' should be initialized in a member initializer of the constructor [cppcoreguidelines-prefer-member-initializer]
629e9cec392SCongcong Cai   S2() : M{2} { M = 1; }
630e9cec392SCongcong Cai // CHECK-FIXES:  S2() : M{1} { }
631e9cec392SCongcong Cai   int M;
632e9cec392SCongcong Cai };
633e9cec392SCongcong Cai struct T { int a; int b; int c; };
634e9cec392SCongcong Cai T v;
635e9cec392SCongcong Cai struct S3 {
636e9cec392SCongcong Cai // CHECK-MESSAGES: :[[@LINE+1]]:21: warning: 'M' should be initialized in a member initializer of the constructor [cppcoreguidelines-prefer-member-initializer]
637e9cec392SCongcong Cai   S3() : M{1,2,3} { M = v; }
638e9cec392SCongcong Cai // CHECK-FIXES:  S3() : M{v} { }
639e9cec392SCongcong Cai   T M;
640e9cec392SCongcong Cai };
641e9cec392SCongcong Cai }
6427deca859SCongcong Cai 
6437deca859SCongcong Cai namespace GH82970 {
644*267ad430SZoltán Porkoláb struct InitFromBindingDecl {
6457deca859SCongcong Cai   int m;
646*267ad430SZoltán Porkoláb   InitFromBindingDecl() {
6477deca859SCongcong Cai     struct { int i; } a;
6487deca859SCongcong Cai     auto [n] = a;
6497deca859SCongcong Cai     m = n;
6507deca859SCongcong Cai   }
6517deca859SCongcong Cai };
6527deca859SCongcong Cai } // namespace GH82970
653