forked from OSchip/llvm-project
Fix lld on GCC 5.1 after the C++14 move
Summary: libstdc++ in GCC 5.1 has some bugs. The move to C++14 in 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. Reviewers: thakis, ruiu, espindola Subscribers: emaste, arichardson, MaskRay, jkorous, dexonsmith, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D66306 llvm-svn: 369023
This commit is contained in:
parent
6eebd2bcd7
commit
7a210d65ed
|
@ -304,30 +304,6 @@ bool LinkerScript::shouldKeep(InputSectionBase *s) {
|
|||
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,30 @@ static bool matchConstraints(ArrayRef<InputSection *> sections,
|
|||
|
||||
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:
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue