Author: djasper Date: Thu Mar 3 11:34:14 2016 New Revision: 262630 URL: http://llvm.org/viewvc/llvm-project?rev=262630&view=rev Log: clang-format: Use stable_sort when sorting #includes.
Otherwise, clang-format can output useless replacements in the presence of identical #includes Modified: cfe/trunk/lib/Format/Format.cpp cfe/trunk/unittests/Format/SortIncludesTest.cpp Modified: cfe/trunk/lib/Format/Format.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=262630&r1=262629&r2=262630&view=diff ============================================================================== --- cfe/trunk/lib/Format/Format.cpp (original) +++ cfe/trunk/lib/Format/Format.cpp Thu Mar 3 11:34:14 2016 @@ -1844,10 +1844,11 @@ static void sortIncludes(const FormatSty SmallVector<unsigned, 16> Indices; for (unsigned i = 0, e = Includes.size(); i != e; ++i) Indices.push_back(i); - std::sort(Indices.begin(), Indices.end(), [&](unsigned LHSI, unsigned RHSI) { - return std::tie(Includes[LHSI].Category, Includes[LHSI].Filename) < - std::tie(Includes[RHSI].Category, Includes[RHSI].Filename); - }); + std::stable_sort( + Indices.begin(), Indices.end(), [&](unsigned LHSI, unsigned RHSI) { + return std::tie(Includes[LHSI].Category, Includes[LHSI].Filename) < + std::tie(Includes[RHSI].Category, Includes[RHSI].Filename); + }); // If the #includes are out of order, we generate a single replacement fixing // the entire block. Otherwise, no replacement is generated. Modified: cfe/trunk/unittests/Format/SortIncludesTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/SortIncludesTest.cpp?rev=262630&r1=262629&r2=262630&view=diff ============================================================================== --- cfe/trunk/unittests/Format/SortIncludesTest.cpp (original) +++ cfe/trunk/unittests/Format/SortIncludesTest.cpp Thu Mar 3 11:34:14 2016 @@ -20,8 +20,12 @@ namespace { class SortIncludesTest : public ::testing::Test { protected: - std::string sort(llvm::StringRef Code, StringRef FileName = "input.cpp") { - std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size())); + std::vector<tooling::Range> GetCodeRange(StringRef Code) { + return std::vector<tooling::Range>(1, tooling::Range(0, Code.size())); + } + + std::string sort(StringRef Code, StringRef FileName = "input.cpp") { + auto Ranges = GetCodeRange(Code); std::string Sorted = applyAllReplacements(Code, sortIncludes(Style, Code, Ranges, FileName)); return applyAllReplacements(Sorted, @@ -29,8 +33,7 @@ protected: } unsigned newCursor(llvm::StringRef Code, unsigned Cursor) { - std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size())); - sortIncludes(Style, Code, Ranges, "input.cpp", &Cursor); + sortIncludes(Style, Code, GetCodeRange(Code), "input.cpp", &Cursor); return Cursor; } @@ -47,6 +50,17 @@ TEST_F(SortIncludesTest, BasicSorting) { "#include \"b.h\"\n")); } +TEST_F(SortIncludesTest, NoReplacementsForValidIncludes) { + // Identical #includes have led to a failure with an unstable sort. + std::string Code = "#include <a>\n" + "#include <b>\n" + "#include <b>\n" + "#include <b>\n" + "#include <b>\n" + "#include <c>\n"; + EXPECT_TRUE(sortIncludes(Style, Code, GetCodeRange(Code), "a.cc").empty()); +} + TEST_F(SortIncludesTest, SupportClangFormatOff) { EXPECT_EQ("#include <a>\n" "#include <b>\n" _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits