Skip to content

Commit 051847c

Browse files
rb-integrationAaronBallman
authored andcommitted
Improve the 'modernize-use-default-member-init'
We want to deal with non-default constructors that just happen to contain constant initializers. There was already a negative test case, it is now a positive one. We find and refactor this case: struct PositiveNotDefaultInt { PositiveNotDefaultInt(int) : i(7) {} int i; };
1 parent 95b74d4 commit 051847c

File tree

4 files changed

+56
-18
lines changed

4 files changed

+56
-18
lines changed

clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -212,17 +212,14 @@ void UseDefaultMemberInitCheck::registerMatchers(MatchFinder *Finder) {
212212
InitBase);
213213

214214
Finder->addMatcher(
215-
cxxConstructorDecl(
216-
isDefaultConstructor(),
217-
forEachConstructorInitializer(
218-
cxxCtorInitializer(
219-
forField(unless(anyOf(getLangOpts().CPlusPlus20
220-
? unless(anything())
221-
: isBitField(),
222-
hasInClassInitializer(anything()),
223-
hasParent(recordDecl(isUnion()))))),
224-
withInitializer(Init))
225-
.bind("default"))),
215+
cxxConstructorDecl(forEachConstructorInitializer(
216+
cxxCtorInitializer(
217+
forField(unless(anyOf(
218+
getLangOpts().CPlusPlus20 ? unless(anything()) : isBitField(),
219+
hasInClassInitializer(anything()),
220+
hasParent(recordDecl(isUnion()))))),
221+
withInitializer(Init))
222+
.bind("default"))),
226223
this);
227224

228225
Finder->addMatcher(
@@ -248,6 +245,14 @@ void UseDefaultMemberInitCheck::checkDefaultInit(
248245
const MatchFinder::MatchResult &Result, const CXXCtorInitializer *Init) {
249246
const FieldDecl *Field = Init->getAnyMember();
250247

248+
// Check whether we have multiple hand-written constructors and bomb out, as
249+
// it is hard to reconcile their sets of member initializers.
250+
const auto *ClassDecl = dyn_cast<CXXRecordDecl>(Field->getParent());
251+
if (llvm::count_if(ClassDecl->ctors(), [](const CXXConstructorDecl *Ctor) {
252+
return !Ctor->isCopyOrMoveConstructor();
253+
}) > 1)
254+
return;
255+
251256
SourceLocation StartLoc = Field->getBeginLoc();
252257
if (StartLoc.isMacroID() && IgnoreMacros)
253258
return;

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ Improvements to clang-tidy
7373
- Added support for `NOLINTBEGIN` ... `NOLINTEND` comments to suppress
7474
Clang-Tidy warnings over multiple lines.
7575

76+
- Generalized the `modernize-use-default-member-init` check to handle non-default
77+
constructors.
78+
7679
New checks
7780
^^^^^^^^^^
7881

clang-tools-extra/docs/clang-tidy/checks/modernize-use-default-member-init.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
modernize-use-default-member-init
44
=================================
55

6-
This check converts a default constructor's member initializers into the new
6+
This check converts constructors' member initializers into the new
77
default member initializers in C++11. Other member initializers that match the
88
default member initializer are removed. This can reduce repeated code or allow
99
use of '= default'.

clang-tools-extra/test/clang-tidy/checkers/modernize-use-default-member-init.cpp

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,42 @@ struct PositiveInt {
4545
// CHECK-FIXES: int j{1};
4646
};
4747

48+
struct PositiveNotDefaultInt {
49+
PositiveNotDefaultInt(int) : i(7) {}
50+
// CHECK-FIXES: PositiveNotDefaultInt(int) {}
51+
int i;
52+
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use default member initializer for 'i'
53+
// CHECK-FIXES: int i{7};
54+
};
55+
56+
// We cannot reconcile these initializers.
57+
struct TwoConstructors {
58+
TwoConstructors(int) : i(7) {}
59+
TwoConstructors(int, int) : i(8) {}
60+
int i;
61+
};
62+
63+
struct PositiveNotDefaultOOLInt {
64+
PositiveNotDefaultOOLInt(int);
65+
int i;
66+
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use default member initializer for 'i'
67+
// CHECK-FIXES: int i{7};
68+
};
69+
70+
PositiveNotDefaultOOLInt::PositiveNotDefaultOOLInt(int) : i(7) {}
71+
// CHECK-FIXES: PositiveNotDefaultOOLInt::PositiveNotDefaultOOLInt(int) {}
72+
73+
struct PositiveNotDefaultOOLInt2 {
74+
PositiveNotDefaultOOLInt2(int, int);
75+
int i;
76+
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use default member initializer for 'i'
77+
// CHECK-FIXES: int i{7};
78+
int j;
79+
};
80+
81+
PositiveNotDefaultOOLInt2::PositiveNotDefaultOOLInt2(int, int arg) : i(7), j(arg) {}
82+
// CHECK-FIXES: PositiveNotDefaultOOLInt2::PositiveNotDefaultOOLInt2(int, int arg) : j(arg) {}
83+
4884
struct PositiveUnaryMinusInt {
4985
PositiveUnaryMinusInt() : j(-1) {}
5086
// CHECK-FIXES: PositiveUnaryMinusInt() {}
@@ -234,12 +270,6 @@ struct NegativeBitField
234270
int i : 5;
235271
};
236272

237-
struct NegativeNotDefaultInt
238-
{
239-
NegativeNotDefaultInt(int) : i(7) {}
240-
int i;
241-
};
242-
243273
struct NegativeDefaultArg
244274
{
245275
NegativeDefaultArg(int i = 4) : i(i) {}

0 commit comments

Comments
 (0)