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;
|
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.
|
// A helper function for the SORT() command.
|
||||||
static bool matchConstraints(ArrayRef<InputSection *> sections,
|
static bool matchConstraints(ArrayRef<InputSection *> sections,
|
||||||
ConstraintKind kind) {
|
ConstraintKind kind) {
|
||||||
|
|
@ -343,8 +319,30 @@ static bool matchConstraints(ArrayRef<InputSection *> sections,
|
||||||
|
|
||||||
static void sortSections(MutableArrayRef<InputSection *> vec,
|
static void sortSections(MutableArrayRef<InputSection *> vec,
|
||||||
SortSectionPolicy k) {
|
SortSectionPolicy k) {
|
||||||
if (k != SortSectionPolicy::Default && k != SortSectionPolicy::None)
|
auto alignmentComparator = [](InputSectionBase *a, InputSectionBase *b) {
|
||||||
llvm::stable_sort(vec, getComparator(k));
|
// ">" 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
|
// Sort sections as instructed by SORT-family commands and --sort-section
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue