diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp --- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp +++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp @@ -590,6 +590,7 @@ // An event can be either the begin or the end of an interval. enum EventType { ET_Begin = 1, + ET_Insert = 0, ET_End = -1, }; @@ -623,6 +624,8 @@ // disallowing the first one. if (Type == ET_Begin) Priority = std::make_tuple(Begin, Type, -End, -ErrorSize, ErrorId); + else if (Type == ET_Insert) + Priority = std::make_tuple(Begin, Type, -End, ErrorSize, ErrorId); else Priority = std::make_tuple(End, Type, -Begin, ErrorSize, ErrorId); } @@ -662,19 +665,19 @@ } // Build events from error intervals. - std::map> FileEvents; + llvm::StringMap> FileEvents; for (unsigned I = 0; I < ErrorFixes.size(); ++I) { for (const auto &FileAndReplace : *ErrorFixes[I].second) { for (const auto &Replace : FileAndReplace.second) { unsigned Begin = Replace.getOffset(); unsigned End = Begin + Replace.getLength(); - const std::string &FilePath = std::string(Replace.getFilePath()); - // FIXME: Handle empty intervals, such as those from insertions. - if (Begin == End) - continue; - auto &Events = FileEvents[FilePath]; - Events.emplace_back(Begin, End, Event::ET_Begin, I, Sizes[I]); - Events.emplace_back(Begin, End, Event::ET_End, I, Sizes[I]); + auto &Events = FileEvents[Replace.getFilePath()]; + if (Begin == End) { + Events.emplace_back(Begin, End, Event::ET_Insert, I, Sizes[I]); + } else { + Events.emplace_back(Begin, End, Event::ET_Begin, I, Sizes[I]); + Events.emplace_back(Begin, End, Event::ET_End, I, Sizes[I]); + } } } } @@ -686,6 +689,11 @@ llvm::sort(Events); int OpenIntervals = 0; for (const auto &Event : Events) { + if (Event.Type == Event::ET_Insert) { + if (OpenIntervals != 0) + Apply[Event.ErrorId] = false; + continue; + } if (Event.Type == Event::ET_End) --OpenIntervals; // This has to be checked after removing the interval from the count if it diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-init-variables-conflict.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-init-variables-conflict.cpp new file mode 100644 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-init-variables-conflict.cpp @@ -0,0 +1,15 @@ +// RUN: %check_clang_tidy %s cppcoreguidelines-init-variables,readability-isolate-declaration %t + +void foo() { + int A, B, C; + // CHECK-MESSAGES-DAG: :[[@LINE-1]]:7: warning: variable 'A' is not initialized + // CHECK-MESSAGES-DAG: :[[@LINE-2]]:10: warning: variable 'B' is not initialized + // CHECK-MESSAGES-DAG: :[[@LINE-3]]:13: warning: variable 'C' is not initialized + // CHECK-MESSAGES-DAG: :[[@LINE-4]]:3: warning: multiple declarations in a single statement reduces readability + + // Only the isolate declarations fix-it should be applied + + // CHECK-FIXES: int A; + // CHECK-FIXES-NEXT: int B; + // CHECK-FIXES-NEXT: int C; +}