]> granicus.if.org Git - clang/commitdiff
Fixing a conflict detection bug in tooling::deduplicate
authorEdwin Vane <edwin.vane@intel.com>
Tue, 13 Aug 2013 16:26:44 +0000 (16:26 +0000)
committerEdwin Vane <edwin.vane@intel.com>
Tue, 13 Aug 2013 16:26:44 +0000 (16:26 +0000)
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

lib/Tooling/Refactoring.cpp
unittests/Tooling/RefactoringTest.cpp

index 8599f975120653a48edd35338c13e8d5ef6ff385..52daaebfd2191e1b6702746c8cd19738ef3b3cb6 100644 (file)
@@ -206,8 +206,9 @@ void deduplicate(std::vector<Replacement> &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)
index 3030162858a952d5c29423e237fd4397e2b8720d..d9f023d9653e16f2bc713e7b3cb255f3c2298a09 100644 (file)
@@ -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<Range> 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());
   }
 }