Skip to content

Commit a466e4b

Browse files
committed
[clangd] Fix modernize-loop-convert "multiple diag in flight" crash.
Summary: this maybe not ideal, but it is trivial and does fix the crash. Fixes clangd/clangd#156. Reviewers: sammccall Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D78715
1 parent 0eec666 commit a466e4b

File tree

2 files changed

+35
-9
lines changed

2 files changed

+35
-9
lines changed

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

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -525,13 +525,11 @@ void LoopConvertCheck::doConversion(
525525
const ValueDecl *MaybeContainer, const UsageResult &Usages,
526526
const DeclStmt *AliasDecl, bool AliasUseRequired, bool AliasFromForInit,
527527
const ForStmt *Loop, RangeDescriptor Descriptor) {
528-
auto Diag = diag(Loop->getForLoc(), "use range-based for loop instead");
529-
530528
std::string VarName;
531529
bool VarNameFromAlias = (Usages.size() == 1) && AliasDecl;
532530
bool AliasVarIsRef = false;
533531
bool CanCopy = true;
534-
532+
std::vector<FixItHint> FixIts;
535533
if (VarNameFromAlias) {
536534
const auto *AliasVar = cast<VarDecl>(AliasDecl->getSingleDecl());
537535
VarName = AliasVar->getName().str();
@@ -563,8 +561,8 @@ void LoopConvertCheck::doConversion(
563561
getAliasRange(Context->getSourceManager(), ReplaceRange);
564562
}
565563

566-
Diag << FixItHint::CreateReplacement(
567-
CharSourceRange::getTokenRange(ReplaceRange), ReplacementText);
564+
FixIts.push_back(FixItHint::CreateReplacement(
565+
CharSourceRange::getTokenRange(ReplaceRange), ReplacementText));
568566
// No further replacements are made to the loop, since the iterator or index
569567
// was used exactly once - in the initialization of AliasVar.
570568
} else {
@@ -609,8 +607,8 @@ void LoopConvertCheck::doConversion(
609607
Usage.Kind == Usage::UK_CaptureByCopy ? "&" + VarName : VarName;
610608
}
611609
TUInfo->getReplacedVars().insert(std::make_pair(Loop, IndexVar));
612-
Diag << FixItHint::CreateReplacement(
613-
CharSourceRange::getTokenRange(Range), ReplaceText);
610+
FixIts.push_back(FixItHint::CreateReplacement(
611+
CharSourceRange::getTokenRange(Range), ReplaceText));
614612
}
615613
}
616614

@@ -648,8 +646,9 @@ void LoopConvertCheck::doConversion(
648646
std::string Range = ("(" + TypeString + " " + VarName + " : " +
649647
MaybeDereference + Descriptor.ContainerString + ")")
650648
.str();
651-
Diag << FixItHint::CreateReplacement(
652-
CharSourceRange::getTokenRange(ParenRange), Range);
649+
FixIts.push_back(FixItHint::CreateReplacement(
650+
CharSourceRange::getTokenRange(ParenRange), Range));
651+
diag(Loop->getForLoc(), "use range-based for loop instead") << FixIts;
653652
TUInfo->getGeneratedDecls().insert(make_pair(Loop, VarName));
654653
}
655654

clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,33 @@ TEST(DiagnosticsTest, ClangTidy) {
272272
"use a trailing return type for this function")))));
273273
}
274274

275+
TEST(DiagnosticTest, NoMultipleDiagnosticInFlight) {
276+
Annotations Main(R"cpp(
277+
template <typename T> struct Foo {
278+
T *begin();
279+
T *end();
280+
};
281+
struct LabelInfo {
282+
int a;
283+
bool b;
284+
};
285+
286+
void f() {
287+
Foo<LabelInfo> label_info_map;
288+
[[for]] (auto it = label_info_map.begin(); it != label_info_map.end(); ++it) {
289+
auto S = *it;
290+
}
291+
}
292+
)cpp");
293+
TestTU TU = TestTU::withCode(Main.code());
294+
TU.ClangTidyChecks = "modernize-loop-convert";
295+
EXPECT_THAT(
296+
TU.build().getDiagnostics(),
297+
UnorderedElementsAre(::testing::AllOf(
298+
Diag(Main.range(), "use range-based for loop instead"),
299+
DiagSource(Diag::ClangTidy), DiagName("modernize-loop-convert"))));
300+
}
301+
275302
TEST(DiagnosticTest, ClangTidySuppressionComment) {
276303
Annotations Main(R"cpp(
277304
int main() {

0 commit comments

Comments
 (0)