Skip to content

Commit 7663deb

Browse files
committedJun 27, 2017
[clang-tidy] Handle new array expressions in modernize-make-unique check.
Reviewers: alexfh Reviewed By: alexfh Subscribers: JDevlieghere, xazax.hun, cfe-commits Differential Revision: https://reviews.llvm.org/D34674 llvm-svn: 306421
1 parent ff680f0 commit 7663deb

File tree

3 files changed

+76
-14
lines changed

3 files changed

+76
-14
lines changed
 

‎clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp

+43-13
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,17 @@ namespace tidy {
1717
namespace modernize {
1818

1919
namespace {
20-
StringRef GetNewExprName(const CXXNewExpr *NewExpr,
21-
const SourceManager &SM,
22-
const LangOptions &Lang) {
23-
return Lexer::getSourceText(
20+
std::string GetNewExprName(const CXXNewExpr *NewExpr,
21+
const SourceManager &SM,
22+
const LangOptions &Lang) {
23+
StringRef WrittenName = Lexer::getSourceText(
2424
CharSourceRange::getTokenRange(
2525
NewExpr->getAllocatedTypeSourceInfo()->getTypeLoc().getSourceRange()),
2626
SM, Lang);
27+
if (NewExpr->isArray()) {
28+
return WrittenName.str() + "[]";
29+
}
30+
return WrittenName.str();
2731
}
2832
} // namespace
2933

@@ -114,7 +118,7 @@ void MakeSmartPtrCheck::checkConstruct(SourceManager &SM,
114118
ConstructCallEnd = ConstructCallStart.getLocWithOffset(ExprStr.size());
115119
Diag << FixItHint::CreateInsertion(
116120
ConstructCallEnd,
117-
"<" + GetNewExprName(New, SM, getLangOpts()).str() + ">");
121+
"<" + GetNewExprName(New, SM, getLangOpts()) + ">");
118122
} else {
119123
ConstructCallEnd = ConstructCallStart.getLocWithOffset(LAngle);
120124
}
@@ -137,7 +141,7 @@ void MakeSmartPtrCheck::checkConstruct(SourceManager &SM,
137141
")");
138142
}
139143

140-
replaceNew(Diag, New);
144+
replaceNew(Diag, New, SM);
141145
}
142146

143147
void MakeSmartPtrCheck::checkReset(SourceManager &SM,
@@ -162,23 +166,49 @@ void MakeSmartPtrCheck::checkReset(SourceManager &SM,
162166
if (Expr->isArrow())
163167
Diag << FixItHint::CreateInsertion(ExprStart, "*");
164168

165-
replaceNew(Diag, New);
169+
replaceNew(Diag, New, SM);
166170
}
167171

168172
void MakeSmartPtrCheck::replaceNew(DiagnosticBuilder &Diag,
169-
const CXXNewExpr *New) {
173+
const CXXNewExpr *New,
174+
SourceManager& SM) {
170175
SourceLocation NewStart = New->getSourceRange().getBegin();
171176
SourceLocation NewEnd = New->getSourceRange().getEnd();
177+
178+
std::string ArraySizeExpr;
179+
if (const auto* ArraySize = New->getArraySize()) {
180+
ArraySizeExpr = Lexer::getSourceText(CharSourceRange::getTokenRange(
181+
ArraySize->getSourceRange()),
182+
SM, getLangOpts())
183+
.str();
184+
}
185+
172186
switch (New->getInitializationStyle()) {
173187
case CXXNewExpr::NoInit: {
174-
Diag << FixItHint::CreateRemoval(SourceRange(NewStart, NewEnd));
188+
if (ArraySizeExpr.empty()) {
189+
Diag << FixItHint::CreateRemoval(SourceRange(NewStart, NewEnd));
190+
} else {
191+
// New array expression without written initializer:
192+
// smart_ptr<Foo[]>(new Foo[5]);
193+
Diag << FixItHint::CreateReplacement(SourceRange(NewStart, NewEnd),
194+
ArraySizeExpr);
195+
}
175196
break;
176197
}
177198
case CXXNewExpr::CallInit: {
178-
SourceRange InitRange = New->getDirectInitRange();
179-
Diag << FixItHint::CreateRemoval(
180-
SourceRange(NewStart, InitRange.getBegin()));
181-
Diag << FixItHint::CreateRemoval(SourceRange(InitRange.getEnd(), NewEnd));
199+
if (ArraySizeExpr.empty()) {
200+
SourceRange InitRange = New->getDirectInitRange();
201+
Diag << FixItHint::CreateRemoval(
202+
SourceRange(NewStart, InitRange.getBegin()));
203+
Diag << FixItHint::CreateRemoval(SourceRange(InitRange.getEnd(), NewEnd));
204+
}
205+
else {
206+
// New array expression with default/value initialization:
207+
// smart_ptr<Foo[]>(new int[5]());
208+
// smart_ptr<Foo[]>(new Foo[5]());
209+
Diag << FixItHint::CreateReplacement(SourceRange(NewStart, NewEnd),
210+
ArraySizeExpr);
211+
}
182212
break;
183213
}
184214
case CXXNewExpr::ListInit: {

‎clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ class MakeSmartPtrCheck : public ClangTidyCheck {
4949
const QualType *Type, const CXXNewExpr *New);
5050
void checkReset(SourceManager &SM, const CXXMemberCallExpr *Member,
5151
const CXXNewExpr *New);
52-
void replaceNew(DiagnosticBuilder &Diag, const CXXNewExpr *New);
52+
void replaceNew(DiagnosticBuilder &Diag, const CXXNewExpr *New,
53+
SourceManager &SM);
5354
};
5455

5556
} // namespace modernize

‎clang-tools-extra/test/clang-tidy/modernize-make-unique.cpp

+31
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class unique_ptr {
1818
type *release();
1919
void reset();
2020
void reset(type *pt);
21+
void reset(type pt);
2122
unique_ptr &operator=(unique_ptr &&);
2223
template <typename T>
2324
unique_ptr &operator=(unique_ptr<T> &&);
@@ -261,6 +262,36 @@ void initialization(int T, Base b) {
261262
BB.reset(new bar::Bar());
262263
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning:
263264
// CHECK-FIXES: BB = std::make_unique<bar::Bar>();
265+
266+
std::unique_ptr<Foo[]> FFs;
267+
FFs.reset(new Foo[5]);
268+
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning:
269+
// CHECK-FIXES: FFs = std::make_unique<Foo[]>(5);
270+
FFs.reset(new Foo[5]());
271+
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning:
272+
// CHECK-FIXES: FFs = std::make_unique<Foo[]>(5);
273+
const int Num = 1;
274+
FFs.reset(new Foo[Num]);
275+
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning:
276+
// CHECK-FIXES: FFs = std::make_unique<Foo[]>(Num);
277+
int Num2 = 1;
278+
FFs.reset(new Foo[Num2]);
279+
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning:
280+
// CHECK-FIXES: FFs = std::make_unique<Foo[]>(Num2);
281+
282+
std::unique_ptr<int[]> FI;
283+
FI.reset(new int[5]);
284+
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning:
285+
// CHECK-FIXES: FI = std::make_unique<int[]>(5);
286+
FI.reset(new int[5]());
287+
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning:
288+
// CHECK-FIXES: FI = std::make_unique<int[]>(5);
289+
FI.reset(new int[Num]);
290+
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning:
291+
// CHECK-FIXES: FI = std::make_unique<int[]>(Num);
292+
FI.reset(new int[Num2]);
293+
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning:
294+
// CHECK-FIXES: FI = std::make_unique<int[]>(Num2);
264295
}
265296

266297
void aliases() {

0 commit comments

Comments
 (0)
Please sign in to comment.