njames93 created this revision. njames93 added reviewers: aaron.ballman, alexfh, gribozavr2, hokein. Herald added subscribers: cfe-commits, kbarton, xazax.hun, nemanjai. Herald added a project: clang.
Handle insertion fix-its when removing incompatible errors by introducting a new EventType `ET_Insert` This has lower prioirty than End events, but higher than begin. Idea being If an insert is at the same place as a begin event, the insert should be processed first to reduce unnecessary conflicts. Likewise if its at the same place as an end event, process the end event first for the same reason. This also fixes https://bugs.llvm.org/show_bug.cgi?id=46511. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D82898 Files: clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-init-variables-conflict.cpp Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-init-variables-conflict.cpp =================================================================== --- /dev/null +++ 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; +} \ No newline at end of file Index: clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp =================================================================== --- clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp +++ 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); } @@ -669,12 +672,13 @@ 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]); + 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 +690,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
Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-init-variables-conflict.cpp =================================================================== --- /dev/null +++ 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; +} \ No newline at end of file Index: clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp =================================================================== --- clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp +++ 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); } @@ -669,12 +672,13 @@ 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]); + 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 +690,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
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits