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:
JF Bastien 2019-08-15 17:47:19 +00:00
parent 6eebd2bcd7
commit 7a210d65ed
1 changed files with 24 additions and 26 deletions

View File

@ -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