From: Edwin Vane Date: Tue, 13 Aug 2013 16:26:44 +0000 (+0000) Subject: Fixing a conflict detection bug in tooling::deduplicate X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=95f0766c1942c8cdc9f913a083ad2bfc4c0c27c9;p=clang Fixing a conflict detection bug in tooling::deduplicate If a Replacment is contained within the conflict range being built, the conflict range would be erroneously shortened. Now fixed. Tests updated to catch this case. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@188287 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Tooling/Refactoring.cpp b/lib/Tooling/Refactoring.cpp index 8599f97512..52daaebfd2 100644 --- a/lib/Tooling/Refactoring.cpp +++ b/lib/Tooling/Refactoring.cpp @@ -206,8 +206,9 @@ void deduplicate(std::vector &Replaces, if (ConflictRange.overlapsWith(Current)) { // Extend conflicted range ConflictRange = Range(ConflictRange.getOffset(), - Current.getOffset() + Current.getLength() - - ConflictRange.getOffset()); + std::max(ConflictRange.getLength(), + Current.getOffset() + Current.getLength() - + ConflictRange.getOffset())); ++ConflictLength; } else { if (ConflictLength > 1) diff --git a/unittests/Tooling/RefactoringTest.cpp b/unittests/Tooling/RefactoringTest.cpp index 3030162858..d9f023d965 100644 --- a/unittests/Tooling/RefactoringTest.cpp +++ b/unittests/Tooling/RefactoringTest.cpp @@ -400,20 +400,25 @@ TEST(DeduplicateTest, detectsConflicts) { // returned conflict info refers to. Input.push_back(Replacement("fileA", 0, 5, " foo ")); // 0 Input.push_back(Replacement("fileA", 5, 5, " bar ")); // 1 + Input.push_back(Replacement("fileA", 6, 0, " bar ")); // 3 Input.push_back(Replacement("fileA", 5, 5, " moo ")); // 2 - Input.push_back(Replacement("fileA", 15, 5, " golf ")); // 4 - Input.push_back(Replacement("fileA", 16, 5, " bag ")); // 5 - Input.push_back(Replacement("fileA", 10, 3, " club ")); // 6 + Input.push_back(Replacement("fileA", 7, 2, " bar ")); // 4 + Input.push_back(Replacement("fileA", 15, 5, " golf ")); // 5 + Input.push_back(Replacement("fileA", 16, 5, " bag ")); // 6 + Input.push_back(Replacement("fileA", 10, 3, " club ")); // 7 + + // #3 is special in that it is completely contained by another conflicting + // Replacement. #4 ensures #3 hasn't messed up the conflicting range size. std::vector Conflicts; deduplicate(Input, Conflicts); // No duplicates - ASSERT_EQ(6u, Input.size()); + ASSERT_EQ(8u, Input.size()); ASSERT_EQ(2u, Conflicts.size()); ASSERT_EQ(1u, Conflicts[0].getOffset()); - ASSERT_EQ(2u, Conflicts[0].getLength()); - ASSERT_EQ(4u, Conflicts[1].getOffset()); + ASSERT_EQ(4u, Conflicts[0].getLength()); + ASSERT_EQ(6u, Conflicts[1].getOffset()); ASSERT_EQ(2u, Conflicts[1].getLength()); } }