[PATCH] D66306: Fix lld on GCC 5.1 after the C++14 move

JF Bastien via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 15 10:25:53 PDT 2019


jfb created this revision.
jfb added reviewers: thakis, ruiu.
Herald added subscribers: llvm-commits, dexonsmith, jkorous, MaskRay, arichardson, emaste.
Herald added a reviewer: espindola.
Herald added a project: LLVM.

libstdc++ in GCC 5.1 has some bugs. The move to C++14 in D66195 <https://reviews.llvm.org/D66195> triggered one
such bug caused by the new constexpr support in C++14, and the implementation
doing SFINAE wrong with the comparator to std::stable_sort.

Here's a small repro: https://godbolt.org/z/2QC3-n

The fix is to inline the lambdas directly into the llvm::stable_sort call
instead of erasing them through a std::function. The code is more readable as
well.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D66306

Files:
  lld/ELF/LinkerScript.cpp


Index: lld/ELF/LinkerScript.cpp
===================================================================
--- lld/ELF/LinkerScript.cpp
+++ lld/ELF/LinkerScript.cpp
@@ -304,30 +304,6 @@
   return false;
 }
 
-// A helper function for the SORT() command.
-static std::function<bool(InputSectionBase *, InputSectionBase *)>
-getComparator(SortSectionPolicy k) {
-  switch (k) {
-  case SortSectionPolicy::Alignment:
-    return [](InputSectionBase *a, InputSectionBase *b) {
-      // ">" is not a mistake. Sections with larger alignments are placed
-      // before sections with smaller alignments in order to reduce the
-      // amount of padding necessary. This is compatible with GNU.
-      return a->alignment > b->alignment;
-    };
-  case SortSectionPolicy::Name:
-    return [](InputSectionBase *a, InputSectionBase *b) {
-      return a->name < b->name;
-    };
-  case SortSectionPolicy::Priority:
-    return [](InputSectionBase *a, InputSectionBase *b) {
-      return getPriority(a->name) < getPriority(b->name);
-    };
-  default:
-    llvm_unreachable("unknown sort policy");
-  }
-}
-
 // A helper function for the SORT() command.
 static bool matchConstraints(ArrayRef<InputSection *> sections,
                              ConstraintKind kind) {
@@ -343,8 +319,31 @@
 
 static void sortSections(MutableArrayRef<InputSection *> vec,
                          SortSectionPolicy k) {
-  if (k != SortSectionPolicy::Default && k != SortSectionPolicy::None)
-    llvm::stable_sort(vec, getComparator(k));
+  auto alignmentComparator = [](InputSectionBase *a, InputSectionBase *b) {
+    // ">" is not a mistake. Sections with larger alignments are placed
+    // before sections with smaller alignments in order to reduce the
+    // amount of padding necessary. This is compatible with GNU.
+    return a->alignment > b->alignment;
+  };
+  auto nameComparator = [](InputSectionBase *a, InputSectionBase *b) {
+    return a->name < b->name;
+  };
+  auto priorityComparator = [](InputSectionBase *a, InputSectionBase *b) {
+    return getPriority(a->name) < getPriority(b->name);
+  };
+
+  switch (k) {
+  case SortSectionPolicy::Default:
+    return;
+  case SortSectionPolicy::None:
+    return;
+  case SortSectionPolicy::Alignment:
+    return llvm::stable_sort(vec, alignmentComparator);
+  case SortSectionPolicy::Name:
+    return llvm::stable_sort(vec, nameComparator);
+  case SortSectionPolicy::Priority:
+    return llvm::stable_sort(vec, priorityComparator);
+  }
 }
 
 // Sort sections as instructed by SORT-family commands and --sort-section


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D66306.215431.patch
Type: text/x-patch
Size: 2568 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190815/cb9fd735/attachment.bin>


More information about the llvm-commits mailing list